Gonnen Daube Gonnen Daube - 1 year ago 94
C++ Question

OpenGL crashes when trying to use glDrawArraysInstanced()

Load to VAO function

glGenVertexArrays(1, &VAO);
glGenBuffers(1, &modelVertexVBO);
glGenBuffers(1, &sphereTransformVBO);

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

glVertexAttribDivisor(sphereTransformVBO, 1);


Geometry drawing function:

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

When I try running this code it crashes with the following crash note:
Exception thrown at 0x0000000068F4EDB4 (nvoglv64.dll) in Engine.exe: 0xC0000005: Access violation reading location 0x0000000000000000.

When I remove the second VBO it works for some reason.

Answer Source
 glVertexAttribPointer(0, 4 * 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), NULL);

Your crash is the result of a simple copy-and-paste bug. You use attribute 0 here, which means you never called glVertexAttribPointer for attribute 1. Therefore, it uses the default attribute state, thus leading to a crash.

However, I strongly suspect that you are attempting to pass a 4x4 matrix as a single attribute. That won't work; OpenGL will give you a GL_INVALID_VALUE error if you try to set the attribute's size to be more than 4.

Matrices are treated as arrays of (column) vectors. And each vector takes up a separate attribute index. So if you want to pass a matrix, you will have to use 4 attribute indices (starting with the one provided by your shader). And each one will have to have the divisor set for it as well.