Reputation: 563
I'm starting to work with OpenGL in iOS. I have always learned to draw stuff in OpenGL using glBegin()
and glEnd()
so this is kind of new to me.
I am trying to draw a simple triangle. I can draw a white triangle nicely, I even can draw an entire colored triangle using glColor
. But whenever I try to assign a color to each vertex using this code below, I get a EXC_BAD_ACCESS
when drawing the array. I am using iOS 4.3 simulator for this. What am I doing wrong?
- (void) render:(CADisplayLink*)displayLink {
glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat vertices [] = {0,0,0, 0,100,0, 100,0,0};
GLfloat colours [] = {1.0,1.0,1.0, 1.0,1.0,1.0, 1.0,1.0,1.0};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glColorPointer(3, GL_FLOAT, 0, colours);
glDrawArrays(GL_TRIANGLES, 0, 3); <-- CRASHES HERE
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
[self.context presentRenderbuffer:GL_RENDERBUFFER];
}
Upvotes: 4
Views: 3457
Reputation: 7868
Your OpenGL code looks correct so far.
Does the call to glDrawArrays
cause bad access, or happens bad access within it?
I just can imagine, that the glDrawArrays
func pointer is not initialized,
vertex arrays should be available though.
You may call this function after glEnableClientState(GL_COLOR_ARRAY);
as a test to reset any other stale array pointers, which could cause bad access:
///@brief Emulation of call glClientAttribDefaultEXT(GL_CLIENT_VERTEX_ARRAY_BIT) according to GL_EXT_direct_state_access.
static void ClientAttribDefaultVertexArray(void) {
int i;
GLint max;
glBindBufferARB(GL_ARRAY_BUFFER, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableClientState(GL_EDGE_FLAG_ARRAY);
glEdgeFlagPointer(0, 0);
glDisableClientState(GL_INDEX_ARRAY);
glIndexPointer(GL_FLOAT, 0, 0);
glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
glSecondaryColorPointer(4, GL_FLOAT, 0, 0);
glDisableClientState(GL_FOG_COORD_ARRAY);
glFogCoordPointer(GL_FLOAT, 0, 0);
glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max);
for (i = 0; i < max; ++i) {
glClientActiveTextureARB(GL_TEXTURE0 + i);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(4, GL_FLOAT, 0, 0);
}
glDisableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, 0, 0);
glDisableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glVertexPointer(4, GL_FLOAT, 0, 0);
glDisableClientState(GL_WEIGHT_ARRAY_ARB);
glWeightPointerARB(0, GL_FLOAT, 0, 0);
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max);
for (i = 0; i < max; ++i) {
glDisableVertexAttribArrayARB(i);
glVertexAttribPointerARB(i, 4, GL_FLOAT, GL_FALSE, 0, 0);
}
glClientActiveTextureARB(GL_TEXTURE0);
}
Additionally, you can push and pop the vertex array state on the client attrib stack:
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
///vertex array init and usage
glPopClientAttrib();
Upvotes: 1
Reputation: 6205
The line glColorPointer(3, GL_FLOAT, 0, colours)
generates the GL_INVALID_VALUE
error (you can see that doing po glGetError
right after executing that line, it will print 1281
).
The reason is that OpenGL ES doesn't support 3 color components, the documentation states:
GL_INVALID_VALUE
is generated if size is not 4.
You code will be ok if you change the number of color components to 4 by adding alpha.
Upvotes: 5