尝试使用 glDrawArraysInstanced() 时 OpenGL 崩溃
OpenGL crashes when trying to use glDrawArraysInstanced()
加载到 VAO 函数
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &modelVertexVBO);
glGenBuffers(1, &sphereTransformVBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, modelVertexVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (sphereModel->numVertices * 3), &(sphereModel->vertices[0]), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL);
glBindBuffer(GL_ARRAY_BUFFER, sphereTransformVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (maxSphereStorage * 4 * 4), NULL, GL_STATIC_DRAW);
glVertexAttribPointer(1, 4 * 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), NULL);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribDivisor(sphereTransformVBO, 1);
glBindVertexArray(0);
几何绘图功能:
glBindVertexArray(VAO);
glDrawArraysInstanced(sphereModel->mode, 0, sphereModel->numVertices, sphereCount);
当我尝试 运行 这段代码时,它崩溃并显示以下崩溃说明:
在 Engine.exe 中的 0x0000000068F4EDB4 (nvoglv64.dll) 抛出异常:0xC0000005:访问冲突读取位置 0x0000000000000000.
当我删除第二个 VBO 时,它出于某种原因起作用了。
glVertexAttribPointer(0, 4 * 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), NULL);
您的崩溃是一个简单的复制粘贴错误的结果。您在这里使用属性 0,这意味着您从未为属性 1 调用 glVertexAttribPointer
。因此,它使用默认属性状态,从而导致崩溃。
但是,我强烈怀疑您正试图将 4x4 矩阵作为单个属性传递。那行不通;如果您尝试将属性的大小设置为大于 4,OpenGL 将 give you a GL_INVALID_VALUE
error。
Matrices are treated as arrays of (column) vectors。并且每个向量占用一个单独的属性索引。所以如果你想传递一个矩阵,你将不得不使用 4 个属性索引(从你的着色器提供的那个开始)。而且每个人都必须为其设置除数。
为什么要将顶点属性指针重新映射到第二个 vbo?
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL);
...
glVertexAttribPointer(0, 4 * 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), NULL);
请参阅 https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml 了解有关 glVertexAttribPointer()
的更多信息
我在猜你的抽奖电话
glDrawArraysInstanced(sphereModel->mode, 0, sphereModel->numVertices, sphereCount);
Note the '0' index in both cases
超出了第二个 VBO 的大小,因此出现了错误。这是故意要将顶点属性指针重新映射到第二个 VBO 吗?这将覆盖第一个映射,换句话说,您的第一个 VBO 未被使用。
我建议使用 GLuint attribute1;
存储索引并相应地映射以避免将来出现此类问题。像 0
这样直接使用数字作为属性索引很容易犯这样的错误。
加载到 VAO 函数
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &modelVertexVBO);
glGenBuffers(1, &sphereTransformVBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, modelVertexVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (sphereModel->numVertices * 3), &(sphereModel->vertices[0]), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL);
glBindBuffer(GL_ARRAY_BUFFER, sphereTransformVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (maxSphereStorage * 4 * 4), NULL, GL_STATIC_DRAW);
glVertexAttribPointer(1, 4 * 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), NULL);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribDivisor(sphereTransformVBO, 1);
glBindVertexArray(0);
几何绘图功能:
glBindVertexArray(VAO);
glDrawArraysInstanced(sphereModel->mode, 0, sphereModel->numVertices, sphereCount);
当我尝试 运行 这段代码时,它崩溃并显示以下崩溃说明: 在 Engine.exe 中的 0x0000000068F4EDB4 (nvoglv64.dll) 抛出异常:0xC0000005:访问冲突读取位置 0x0000000000000000.
当我删除第二个 VBO 时,它出于某种原因起作用了。
glVertexAttribPointer(0, 4 * 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), NULL);
您的崩溃是一个简单的复制粘贴错误的结果。您在这里使用属性 0,这意味着您从未为属性 1 调用 glVertexAttribPointer
。因此,它使用默认属性状态,从而导致崩溃。
但是,我强烈怀疑您正试图将 4x4 矩阵作为单个属性传递。那行不通;如果您尝试将属性的大小设置为大于 4,OpenGL 将 give you a GL_INVALID_VALUE
error。
Matrices are treated as arrays of (column) vectors。并且每个向量占用一个单独的属性索引。所以如果你想传递一个矩阵,你将不得不使用 4 个属性索引(从你的着色器提供的那个开始)。而且每个人都必须为其设置除数。
为什么要将顶点属性指针重新映射到第二个 vbo?
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL);
...
glVertexAttribPointer(0, 4 * 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), NULL);
请参阅 https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml 了解有关 glVertexAttribPointer()
我在猜你的抽奖电话
glDrawArraysInstanced(sphereModel->mode, 0, sphereModel->numVertices, sphereCount);
Note the '0' index in both cases
超出了第二个 VBO 的大小,因此出现了错误。这是故意要将顶点属性指针重新映射到第二个 VBO 吗?这将覆盖第一个映射,换句话说,您的第一个 VBO 未被使用。
我建议使用 GLuint attribute1;
存储索引并相应地映射以避免将来出现此类问题。像 0
这样直接使用数字作为属性索引很容易犯这样的错误。