尝试使用glDrawArraysInstanced()时OpenGL崩溃

时间:2016-08-10 23:48:52

标签: c++ opengl crash nvidia vbo

加载到VAO功能

android

几何绘图功能:

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);

当我尝试运行此代码时,它崩溃时出现以下崩溃说明:     Engine.exe中的0x0000000068F4EDB4(nvoglv64.dll)抛出异常:0xC0000005:访问冲突读取位置0x0000000000000000。

当我删除第二个VBO时,它可以出于某种原因。

2 个答案:

答案 0 :(得分:1)

 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个属性索引(从着色器提供的索引开始)。并且每个人都必须为它设置除数。

答案 1 :(得分:0)

为什么要将Vertex属性指针重新映射到第二个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);

有关glVertexAttribPointer()

的更多信息,请参阅https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml

我猜你的抽奖电话

glDrawArraysInstanced(sphereModel->mode, 0, sphereModel->numVertices, sphereCount);
  

注意' 0'两种情况下的指数

超出了你的第二个VBO的大小,因此错误。这是故意要将顶点属性指针重新映射到第二个VBO吗?这会覆盖第一个映射,换句话说,您的第一个VBO未被使用。

我建议使用GLuint attribute1;来存储索引并相应地映射以避免将来出现此类问题。像0一样直接使用属性索引的数字是一种容易犯错误的方法。