I recently changed my app from using OpenGL ES 1.1 to 2.0, and in the process I decided to optimise my code further by using VBOs. I think I've got to grips with the main differences with ES 2.0, and have results to show that I'm doing things correctly without VBOs, however I've been stumped by a problem that only presents itself when I try to use VBOs.
I use a custom struct containing vertex position, color and size (plus a little padding to align data), and then interleave this vertex data in a VBO. This data is used to render point sprites. The problem is that I get an EXC_BAD_ACCESS on the glDrawArrays() call. The backtrace at this error is as follows:
#0 0x31fc7358 in gleRunVertexSubmitARM ()
#1 0x31fc87b2 in gleLLVMArrayFunc ()
#2 0x31fc872a in gleSetVertexArrayFunc ()
#3 0x31fbefcc in gleDrawArraysOrElements_ExecCore ()
#4 0x31fc4608 in glDrawArrays_IMM_Exec ()
#5 0x36ddaee2 in glDrawArrays ()
#6 0x0001cab8 in -[Renderer renderDrawingVertexBuffer:withSize:usingTexture:] (self=0x1783b0, _cmd=0x50fec, vboID=0, size=3584, drawTexture=5) at /Users/Stu/Documents/...
#7 0x000202f4 in -[EAGLView drawSmoothCurveFromPoints:endOfLine:] (self=0x195be0, _cmd=0x50d34, points=0x1956f0, endOfLine=1 '\001') at /Users/Stu/Documents/...
#8 0x0001e50c in -[EAGLView drawView:] (self=0x195be0, _cmd=0x50d8a, sender=0x0) at /Users/Stu/Documents/...
#9 0x0001e174 in -[EAGLView layoutSubviews] (self=0x195be0, _cmd=0x3297d4ac) at /Users/Stu/Documents/...
#10 0x326805fa in -[UIView(CALayerDelegate) layoutSublayersOfLayer:] ()
#11 0x35efbf02 in -[NSObject(NSObject) performSelector:withObject:] ()
#12 0x333fbbb4 in -[CALayer layoutSublayers] ()
#13 0x333fb96c in CALayerLayoutIfNeeded ()
This is the struct for storing vertex data:
typedef struct {
ISVertex2D vertex; // Made up of 2 GLfloats.
ISColor color; // Made up of 4 GLfloats.
GLfloat size;
GLfloat padding;
} ISPointSpriteData;
After a set of data is stored in an array of these structs, the data is sent to the VBO and rendered using glDrawArrays():
[renderer prepareScene];
[renderer renderBackground];
glBindBuffer(GL_ARRAY_BUFFER, penVbo);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(ISPointSpriteData) * penVboSize, sizeof(ISPointSpriteData) * vertexCount, &vertexBuffer[0].vertex);
glBindTexture(GL_TEXTURE_2D, drawTexture);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glEnableVertexAttribArray(ATTRIB_COLOR);
glEnableVertexAttribArray(ATTRIB_SIZE);
glDisableVertexAttribArray(ATTRIB_TEXTURE_COORD);
glUniform1i(uniforms[UNIFORM_IS_SPRITE], GL_TRUE);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(ISPointSpriteData), (void*)offsetof(ISPointSpriteData, vertex));
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(ISPointSpriteData), (void*)offsetof(ISPointSpriteData, color));
glVertexAttribPointer(ATTRIB_SIZE, 1, GL_FLOAT, GL_FALSE, sizeof(ISPointSpriteData), (void*)offsetof(ISPointSpriteData, size));
glDrawArrays(GL_POINTS, 0, vertexCount); // <--- EXC_BAD_ACCESS
glDisableVertexAttribArray(ATTRIB_VERTEX);
glDisableVertexAttribArray(ATTRIB_COLOR);
glDisableVertexAttribArray(ATTRIB_SIZE);
[renderer presentScene];
This code worked right before I put the VBO in, with the only alteration being that the last parameter of the glVertexAttribPointer() calls would obviously point to the data rather than an offset. What am I missing? I don't think this code is particularly complicated so I can only think that I've made a stupid mistake somewhere.
Thanks
Problem solved:
There were a few things wrong with my code, not all of which would have been apparent from the listings in the question. I'll outline the major issues:
GLuint handle for the
buffer (I was attempting to pass it
by reference in a function that
returns void). In the interests of
making this more readable I changed
the function to simply initialise its
own handle and return it. This
stopped the program crashing at the
glDrawArrays() line (presumably the
uninitialised value must already have
been assigned to another buffer
somewhere).A new problem presented itself - the screen was being drawn to black and there were BIG delays between draw calls. This was caused by...
Hope this is helpful to somebody else in a similar situation!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With