I'm having a problem where I'm trying to use two VBOs in a glkviewcontroller. The first holds vertex data for triangles. The second holds data for lines. But, when I try to bind the second vbo the code stops drawing (or overwrites) the scene contained in the first VBO - i.e. only the lines are drawn.
In my draw method:
First I draw the triangles
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, TexCoord));
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
[self.effect prepareToDraw];
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, nLiveSquares*6, GL_UNSIGNED_SHORT, 0);
Now I want to draw my lines
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glBindBuffer(GL_ARRAY_BUFFER, _lineBuffer);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition,2,GL_FLOAT,GL_FALSE,2*4,0);
// Set the line width
glLineWidth(5.0);
// Render the line
glDrawArrays(GL_LINE_STRIP, 0, 2);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
How do I get both the triangles and the lines drawn? And am I right in thinking that each should get its own VBO?
I solved the problem by moving the call to glBindBuffer before glEnableVertexAttribArray/glVertexAttribPointer :
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, TexCoord));
Related
I've created dynamic terrain with Ray Wenderlich lesson, but I have some problem. I've used CCTexture2D for filling terrain area. At first minute it works totally ok, but after some time texture is gonna be smoother and smoother and smoother.
Here's the code:
Initialization of texture:
ccTexParams params = {GL_LINEAR,GL_LINEAR,GL_REPEAT,GL_CLAMP_TO_EDGE};
[texturePattern.texture setTexParameters:¶ms];
justTexture = [[CCTextureCache sharedTextureCache] addImage:#"text1.jpg"];
[justTexture generateMipmap];
[justTexture setTexParameters:¶ms];
Method draw where I fill my area:
-(void) draw
{
CC_NODE_DRAW_SETUP();
//ccGLBindTexture2D(texturePattern.texture.name);
ccGLBindTexture2D(justTexture.name);
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position | kCCVertexAttribFlag_TexCoords);
ccDrawColor4F(1.0f, 1.0f, 1.0f, 1.0f);
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, _hillVertices);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, _hillTexCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)_nHillVertices);
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, _highVertices);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, _highTexCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)_nHighVertices);
}
I'm trying to reproduce in a GLKViewController the effect in this stencil buffer tutorial here in which a stencil is used for clipping.
In my drawinrect method I have:
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
[self.effect prepareToDraw];
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, TexCoord));
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
glStencilFunc(GL_NEVER, 1, 0xFF);
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); // draw 1s on test fail (always)
// draw stencil pattern
glStencilMask(0xFF);
glClear(GL_STENCIL_BUFFER_BIT); // needs mask=0xFF
glDrawElements(GL_TRIANGLES, 1*6, GL_UNSIGNED_SHORT, 0);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
glStencilMask(0x00);
// draw only where stencil's value is 1
glStencilFunc(GL_EQUAL, 1, 0xFF);
glDrawElements(GL_TRIANGLES, nLiveSquares*6, GL_UNSIGNED_SHORT, 0);
glDisable(GL_STENCIL_TEST);
}
The vertexbuffer contains info for squares, which hold textures.
The effect I'm trying to get is to have the first square be used to define the stencil shape and then when I draw the scene, anything which lies outside of the first square is clipped. Hence, I have used drawElements twice - firstly to draw the clipping square and then to draw all the squares.
I also have another method used for the OpenGL set-up, called once at the start of the program. As suggested by an answer to this stackoverflow question, this includes:
GLuint depthStencilRenderbuffer;
glGenRenderbuffers(1, &depthStencilRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthStencilRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRenderbuffer);
Running this results in nothing except a screen containing the grey clear color. It appears that everything has been stenciled out (or is not drawn to the screen).
Solution:
i) I changed the initialization to:
GLuint depthStencilRenderbuffer;
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthStencilRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES,
GL_DEPTH24_STENCIL8_OES,
self.view.bounds.size.width,
self.view.bounds.size.height);
I'm not sure what the difference is, but this seems to work.
ii) In the set up I use:
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
view.drawableStencilFormat = GLKViewDrawableStencilFormat8;
Thanks to #rickster for his suggestion.
I am having major issues a with a libGPUSupportMercury.dylib gpus_ReturnGuiltyForHardwareRestart error.
Currently I am rendering a cube and a line. If I render just the cube or just the line the error arises about 20% of the time. If i render both i get the error about 90% of the time.
I have read online that this is a bug in ios and there is nothing that can be done. However, other OpenGL programs like unity do not have this issue. So I must be doing something wrong
The following is a simplified version of the code i am using.
-(void) setUp{
m_context = [[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2] autorelease];
[EAGLContext setCurrentContext:m_context];
glGenRenderbuffers(1, &m_renderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_renderbuffer);
[m_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_renderbuffer);
}
-(void) render{
//[EAGLContext setCurrentContext:m_context]; Error seems to happen more frequent if I uncomment these lines
// glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glViewport(0, 0, self.bounds.size.width, self.bounds.size.height);
glClearColor(0.3, 0.3, 0.3, 1);
glClear(GL_COLOR_BUFFER_BIT);
[self renderCube]; // VBO
[self renderLine]; // NON VBO
[m_context presentRenderbuffer:GL_RENDERBUFFER]; <---- Error Here
}
-(void) renderCube
{
glUseProgram(m_cubeProgram);
glBindTexture(GL_TEXTURE_2D, m_textureHandle);
glUniformMatrix4fv(m_uniformHandles[UNIFORM_PROJECTION_MATRIX], 1, GL_FALSE, m_projectionMatrix.m);
glUniformMatrix4fv(m_uniformHandles[UNIFORM_MODELVIEW_MATRIX], 1, GL_FALSE, m_modelMatrix.m);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_cubeIndexVBO);
glEnableVertexAttribArray(m_attributeHandles[ATTRIB_POSITION]);
glEnableVertexAttribArray(m_attributeHandles[ATTRIB_TEXCOORD]);
glBindBuffer(GL_ARRAY_BUFFER, m_cubeVertexVBO);
glVertexAttribPointer(m_attributeHandles[ATTRIB_POSITION], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(m_attributeHandles[ATTRIB_TEXCOORD], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
glDrawElements( GL_TRIANGLES, m_numberOfIndices, GL_UNSIGNED_SHORT, (void*)0 );
glDisableVertexAttribArray(m_attributeHandles[ATTRIB_POSITION]);
glDisableVertexAttribArray(m_attributeHandles[ATTRIB_TEXCOORD]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Desperate attempt to fix the issue
glBindBuffer(GL_ARRAY_BUFFER, 0); // this too
glBindTexture(GL_TEXTURE_2D, 0); /// this too
}
-(void) renderLine
{
glUseProgram(m_lineProgram);
glUniformMatrix4fv(m_uniformHandles[UNIFORM_LINE_PROJECTION_MATRIX], 1, GL_FALSE, m_projectionMatrix.m);
glUniformMatrix4fv(m_uniformHandles[UNIFORM_LINE_MODELVIEW_MATRIX], 1, GL_FALSE, m_modelView.m);
glEnableVertexAttribArray(m_attributeHandles[ATTRIB_LINE_POSITION]);
float linVertices[]= {...};
glVertexAttribPointer(m_attributeHandles[ATTRIB_LINE_POSITION], 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, lineVertices);
glLineWidth(3.0f);
glDrawArrays(GL_LINE_STRIP, 0, 3);
glDisableVertexAttribArray(m_attributeHandles[ATTRIB_LINE_POSITION]);
}
In my app I have a view that renders STL files. STL files are essentially a list of triangle vertices with normals, they have no indices.
Every tutorial that I have found explains how to use multiple VBOs but with Indices and when I try using drawArrays rather than drawElements it doesn't work. I'm new to OpenGL and would really appreciate it if someone could provide code examples for using multiple VBOs for setup and drawing them without indices.
Here is how I am trying to do this now to no avail. SetupGL:
[EAGLContext setCurrentContext:self.context];
[self loadShaders];
self.effect = [[GLKBaseEffect alloc] init];
self.effect.light0.enabled = GL_TRUE;
self.effect.light0.diffuseColor = GLKVector4Make(.05f, .55f, 1.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glClearColor(0.88f, 0.88f, 0.88f, 1.0f);
//---- First Vertex Array Object --------
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glBindVertexArrayOES(_vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertCount*sizeof(verticesBuff) * 3 * 2, verticesBuff, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
//----- Second Vertex Array Object ----------
glGenBuffers(1, &_gridVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _gridVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, gridVertCount*sizeof(gridVerticesBuff) * 3 * 2, NULL, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArrayOES(0);
And this is my draw code:
glBindVertexArrayOES(_vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, vertCount);
///////// second VBO and shader program:
glBindBuffer(GL_ARRAY_BUFFER, _gridVertexBuffer);
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, 108);
Also, here is code that I was using before that doesn't render both the arrays but it does render one (verticesBuff). SetupGL:
[EAGLContext setCurrentContext:self.context];
[self loadShaders];
self.effect = [[GLKBaseEffect alloc] init];
self.effect.light0.enabled = GL_TRUE;
self.effect.light0.diffuseColor = GLKVector4Make(.05f, .55f, 1.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glClearColor(0.88f, 0.88f, 0.88f, 1.0f);
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glGenBuffers(1, &_gridVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _gridVertexBuffer);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glBufferData(GL_ARRAY_BUFFER, 108 * sizeof(gridVerticesBuff), NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(gridVerticesBuff) * 108, gridVerticesBuff);
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glBufferData(GL_ARRAY_BUFFER, vertCount*sizeof(verticesBuff) * 3 * 2, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verticesBuff) * vertCount * 3, verticesBuff);
glBindVertexArrayOES(0);
And here is the draw code:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (loaded) {
// Render the object with GLKit
[self.effect prepareToDraw];
glBindVertexArrayOES(_gridVertexArray);
glBindBuffer(GL_ARRAY_BUFFER, _gridVertexBuffer);
glDrawArrays(GL_TRIANGLES, 0, 108);
glBindVertexArrayOES(_vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glDrawArrays(GL_TRIANGLES, 0, vertCount);
}
It is tough to know exactly what is wrong without seeing your code, but if you follow these general steps you should be able to figure it out. There is little difference between indexed and flat data. Using VBOs will be easier if you understand what they are doing. Essentially VBOs allow you to preupload common vertex data onto the graphics card so it doesn't have to be reploaded every draw call. With that in mind you need to think about how to pack all the vertex data used in a normal draw call into a single memory buffer.
Create Buffer:
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, totalBufferSize, NULL, GL_STATIC_DRAW); /* totalBufferSize is sizeof vertices buffer + sizeof normals buffer */
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexBufferSize, vertexBuffer); /* offset 0 */
glBufferSubData(GL_ARRAY_BUFFER, vertexBufferSize, normalBufferSize, normalBuffer); /* offset vertexbufferSize */
Draw Buffer:
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(VERTEX_ATTRIB ..., ((char*)NULL) + 0); /* start at beginning (0 offset) of the vertex buffer */
glVertexAttribPointer(NORMAL_ATTRIB ..., ((char*)NULL) + vertexBufferSize); /* start at normal subdata (offset vertexBufferSize) of the vertex buffer */
glDrawArrays(..., vertexCount);
The (char*)NULL thing may look a little weird. Instead of passing in a pointer to a buffer in RAM, you are passing in an offset into the currently bound VBO. The arguments of the function still require a pointer so the address of the pointer is used as an offset. Understand NULL is 0 and treat the code as if (char*)NULL + is not there.
I'm trying to take my code to the next level. Following some best practices from Apple, I'm trying to implement Vertex Array Objects around my Vertex Buffer Objects (VBO). I setup my VBOs and VAOs like this:
- (void)setupVBOs {
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArrayOES(0);
{
glGenVertexArraysOES(1, &directArrayObject);
glBindVertexArrayOES(directArrayObject);
// GLuint texCoordBuffer;
glGenBuffers(1, &texCoordBuffer);
glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(DirectVertices), DirectVertices, GL_STATIC_DRAW);
glVertexAttribPointer(directPositionSlot, 2, GL_FLOAT, GL_FALSE, sizeof(DirectVertex), (GLvoid*)offsetof(DirectVertex, position));
glEnableVertexAttribArray(directPositionSlot);
glVertexAttribPointer(texCoordSlot, 2, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(DirectVertex), (GLvoid*)offsetof(DirectVertex, texCoord));
glEnableVertexAttribArray(texCoordSlot);
glGenVertexArraysOES(1, &arrayObject);
glBindVertexArrayOES(arrayObject);
// GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glEnableVertexAttribArray(positionSlot);
glVertexAttribPointer(colorSlot, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Color));
glEnableVertexAttribArray(colorSlot);
// GLuint indexBuffer;
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArrayOES(0);
}
which I took from http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=287977 and then use it like this:
- (void) render:(CADisplayLink*)displayLink {
glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, backingWidth, backingHeight);
[directProgram use];
glBindVertexArrayOES(directArrayObject);
glDisable(GL_DEPTH_TEST);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, videoFrameTexture);
// // Update uniform values
glUniform1i(videoFrameUniform, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
[program use];
glBindVertexArrayOES(arrayObject);
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10];
glUniformMatrix4fv(projectionUniform, 1, 0, projection.glMatrix);
CC3GLMatrix *modelView = [CC3GLMatrix matrix];
[modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)];
currentRotation += displayLink.duration * 90;
[modelView rotateBy:CC3VectorMake(currentRotation, currentRotation, 0)];
glUniformMatrix4fv(modelViewUniform, 1, 0, modelView.glMatrix);
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);
glBindVertexArrayOES(0);
BOOL success = [context presentRenderbuffer:GL_RENDERBUFFER];
if(!success)
NSLog(#"present failed");
}
The call to glDrawArrays works, and it fills my texture, however, the call to glDrawElements fails with an EXC_BAD_ACCESS. My shader programs (i use two) are wrapped in a GLProgram object that I took from http://iphonedevelopment.blogspot.com/2010/11/opengl-es-20-for-ios-chapter-4.html
Remove glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); from the end of your setup function.
Per the specification for OES_vertex_array_object, a vertex array object encapsulates all state except the array buffer binding1, so there is no element buffer bound at the time that you’re drawing, whereas you presumably wanted indexBuffer to be bound. By leaving indexBuffer bound at the time that you bind away from your vertex array object, you ensure that it’ll be rebound when you return to that vertex array object.
1 If you’re wondering why the array buffer binding isn’t tracked in vertex array objects, this is presumably because the currently-bound array buffer isn’t used directly when reading vertex data from arrays—rather, each vertex attribute has its own buffer binding, which is filled out by its respective gl*Pointer function by looking at the array buffer binding when the function is called.