4

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]; } 

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks!!! That worked :) I would never hav guessed until I tried loading images with alpha values
1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.