PDA

View Full Version : Crash on glDrawElements()



Zylzyl
01-01-2014, 02:55 PM
Forum thought it would be nice to delete everything I typed so short story.

Crash on line 94, but only on large scenes; black screen either way.

Class I use to represent objects: http://pastebin.com/BEzZceEX

Zylzyl
01-01-2014, 06:51 PM
Changed the render function to this:


void render() {
if (totalTriangleCount > 0) {
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableClientState(GL_VERTEX_ARRAY);
//glEnableClientState(GL_NORMAL_ARRAY);
//glEnableClientState(GL_TEXTURE_COORD_ARRAY);

// We got 36 bytes for normal and tex coords to skip between vertices
glVertexPointer(3, GL_FLOAT, 36, BUFFER_OFFSET(0));
//glNormalPointer(GL_FLOAT, 60, BUFFER_OFFSET(36));
//glTexCoordPointer(2, GL_FLOAT, 48, BUFFER_OFFSET(48));
//glVertexPointer(3, GL_FLOAT, 72, BUFFER_OFFSET(0));
//glNormalPointer(GL_FLOAT, 72, BUFFER_OFFSET(36));
//glTexCoordPointer(2, GL_FLOAT, 72, BUFFER_OFFSET(48));

//glDrawElements(GL_TRIANGLES, totalTriangleCount, GL_UNSIGNED_BYTE, 0);
glDrawArrays(GL_TRIANGLES, 0, totalTriangleCount);

glDisableClientState(GL_VERTEX_ARRAY);
//glDisableClientState(GL_NORMAL_ARRAY);
//glDisableClientState(GL_TEXTURE_COORD_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}

Using glDrawElements was incorrect in my case. It apparantly uses vertex index buffers which I do not use. I use vertex data directly. I get a lot of nonsense out of this anyway, and any camera movements make it stretch, very unlike a perspective behaviour.

http://img593.imageshack.us/img593/2286/ntz8.png

Do these artifacts look familiar to anyone? (rofl)

Zylzyl
01-01-2014, 08:14 PM
After more try and error I got it working. But it makes no sense that it works. Why the hell does this work? rofl


void render() {
if (totalTriangleCount > 0) {
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableClientState(GL_VERTEX_ARRAY);

// Stride must be 0 although there is 50% non-vertex-position-data in there.
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
// Tell it I want 6 times the triangles I have to be rendered to get all rofl
glDrawArrays(GL_TRIANGLES, 0, totalTriangleCount * 6);

// This is the code which makes sense but does not work rofl
//glVertexPointer(3, GL_FLOAT, 36, BUFFER_OFFSET(0));
//glDrawArrays(GL_TRIANGLES, 0, totalTriangleCount);

glDisableClientState(GL_VERTEX_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}

Dark Photon
01-02-2014, 07:30 AM
// We got 36 bytes for normal and tex coords to skip between vertices
glVertexPointer(3, GL_FLOAT, 36, BUFFER_OFFSET(0));
//glNormalPointer(GL_FLOAT, 60, BUFFER_OFFSET(36));
//glTexCoordPointer(2, GL_FLOAT, 48, BUFFER_OFFSET(48));
//glVertexPointer(3, GL_FLOAT, 72, BUFFER_OFFSET(0));
//glNormalPointer(GL_FLOAT, 72, BUFFER_OFFSET(36));
//glTexCoordPointer(2, GL_FLOAT, 72, BUFFER_OFFSET(48));

//glDrawElements(GL_TRIANGLES, totalTriangleCount, GL_UNSIGNED_BYTE, 0);
glDrawArrays(GL_TRIANGLES, 0, totalTriangleCount);

glDisableClientState(GL_VERTEX_ARRAY);
//glDisableClientState(GL_NORMAL_ARRAY);
//glDisableClientState(GL_TEXTURE_COORD_ARRAY);


When you're doing interleaved vertex attributes, and all vertex attributes are interleaved in one VBO, your stride values should be the same for all vertex attributes. In your case, it looks like you have (3+3+2)*sizeof(FLOAT) = 8*4 = 32 bytes for each vertex. The stride is specified in bytes. So plug 32 in there for all of the strides.

Buffer offsets are also specified in bytes. You've got your position (vertex) attribute pointer right (0). But your normal, if it's packed into the VBO right after the vertex position, it should be at offset 3*sizeof(FLOAT)=3*4=12, right? Similarly, your texcoords should be at (3+3)*sizeof(FLOAT)=6*4=24. etc.

Also, your glDrawArrays() call -- the "first" and "count" arguments are "vertex" indices, not "triangle" indices. So here you want 3*totalTriangleCount for your number of vertex indices to render.

Also, you need to enable all of the vertex attribute arrays you're going to use. Start by just enabling VERTEX, and then enable them one at a time. Since you're new to this, best to make small changes and retest frequently.

Note that you're using old-style vertex attributes. With new style vertex attributes (glVertexAttribPointer / glEnableVertexAttribArray), all the vertex attribute defines and enables use the same APIs, which simplifies things a bit. For instance, no implicit numbers of elements as in glNormalArrayPointer -- you provide everything.

Zylzyl
01-02-2014, 07:52 AM
Thank you a lot! A had a fundamental misunderstanding regarding the VBO. I was submitting triangle by triangle as structure of arrays with only 1 normal for the whole triangle rather than vertex by vertex lol. Also stride is actually an offset (rather than a gap), aha.

Seriously they could take your post as it is and slap it in the doc and it'd be 10 times more useful rofl.