OpenGL ES on iOS Multiple VBOs without Indices - ios

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.

Related

Filling area with texture, cocos2d

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:&params];
justTexture = [[CCTextureCache sharedTextureCache] addImage:#"text1.jpg"];
[justTexture generateMipmap];
[justTexture setTexParameters:&params];
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);
}

Using two VBOs results in only the second being drawn

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

IOS OpenGL gpus_ReturnGuiltyForHardwareRestart Error

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

ios opengl es 2.0 2D + 3D combination

I am trying to combine 2D and 3D in OpenGL ES "2.0" and even though there are many questions here on openGL es 1.0 and some on 2.0 I am having trouble trying to figure this out. So for 2D I am going off of this tutorial: http://www.raywenderlich.com/9743/how-to-create-a-simple-2d-iphone-game-with-opengl-es-2-0-and-glkit-part-1 and for the 3D I am using the existing cube rotating xcode template...
I am getting EXC_BAD_ACCESS on the second glDrawArray (somehow its thinking that the original buffer still applies? anyway to unbind this before drawing the 2D texture?) error with the following render function. It works if I disable the lines:
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));
What's going on? Thanks in advance.
[code]
glEnable(GL_DEPTH_TEST);
// glGenVertexArraysOES(1, &_vertexArrayNum);
// glBindVertexArrayOES(_vertexArrayNum);
glGenBuffers(1, &_vertexBufferNum);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferNum);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, 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));
glBindVertexArrayOES(0);
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
// baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
// Compute the model view matrix for the object rendered with GLKit
// GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeRotation(_rotation, 0, 1, 0);
//modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArrayOES(_vertexArrayNum);
// Render the object with GLKit
// [self.effect prepareToDraw];
// glDrawArrays(GL_TRIANGLES, 0, 36);
modelViewMatrix = GLKMatrix4MakeScale(2.0f, 2.0f, 2.0f);
projectionMatrix = GLKMatrix4MakeOrtho(0, 480, 0, 320, -1024, 1048);
self.effect.transform.projectionMatrix = projectionMatrix;
self.effect.transform.modelviewMatrix = modelViewMatrix;
[self.effect prepareToDraw];
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
[self.player render];
[/code]
UPDATE:
Added glEnableClientState(GL_VERTEX_ARRAY); wrapped around the cube drawing part... which got rid of the bad access error, but neither the cube nor the sprite is being drawn (unless of couse I comment out the code part altogether)...
UPDATE2:
so the problen is obviously that after i call glDrawArray to draw the cube (which works fine)... I call glDrawArray again as follows. But somehow its still trying to render previous array?
// 1
self.effect.texture2d0.name = self.textureInfo.name;
self.effect.texture2d0.enabled = YES;
// 2
[self.effect prepareToDraw];
// 3
glEnableVertexAttribArray(GLKVertexAttribPosition);
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
// 4
long offset = (long)&_quad;
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, geometryVertex)));
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, textureVertex)));
// 5
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Stupid me. Works as soon as I do:
glBindBuffer(GL_ARRAY_BUFFER, 0);
to clear the buffer. I kept looking for glUnbind something... forgot openGL works off of memory references... The 2D texutre is now applying to the cube, but I am sure thats an easy fix :).... That you all for the help >:o
Texture issue fixed :)

Use of VAO around VBO in Open ES iPhone app Causes EXC_BAD_ACCESS When Call to glDrawElements

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.

Resources