OpenGL ES 1.1 Vertex Buffer Object Not Working

I am developing an iPhone game using OpenGL ES 1.1 and you need to use buffer vertex objects to render 500+ particles without sacrificing performance.

My game was able to successfully draw using a method other than VBO, but now that I have tried to enable VBOs, nothing else is drawn.

Please help me identify what I am doing wrong and give a correct example.

I have a class called TexturedQuad , which consists of the following:

// TexturedQuad.h enum { ATTRIB_POSITION, ATTRIB_TEXTURE_COORD }; @interface TexturedQuad : NSObject { GLfloat *textureCoords; // 8 elements for 4 points (u and v) GLfloat *vertices; // 8 elements for 4 points (x and y) GLubyte *indices; // how many elements does this need? // vertex buffer array IDs generated using glGenBuffers(..) GLuint vertexBufferID; GLuint textureCoordBufferID; GLuint indexBufferID; // ...other ivars } // @synthesize in .m file for each property @property (nonatomic, readwrite) GLfloat *textureCoords; @property (nonatomic, readwrite) GLfloat *vertices; @property (nonatomic, readwrite) GLubyte *indices; @property (nonatomic, readwrite) GLuint vertexBufferID; @property (nonatomic, readwrite) GLuint textureCoordBufferID; @property (nonatomic, readwrite) GLuint indexBufferID; // vertex buffer object methods - (void) createVertexBuffers; - (void) createTextureCoordBuffers; - (void) createIndexBuffer; 

TexturedQuad.m creates vertex buffers:

 - (void) createVertexBuffers { glGenBuffers(1, &vertexBufferID); glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); } - (void) createTextureCoordBuffers { glGenBuffers(1, &textureCoordBufferID); glBindBuffer(GL_ARRAY_BUFFER, textureCoordBufferID); glBufferData(GL_ARRAY_BUFFER, sizeof(textureCoords), textureCoords, GL_STATIC_DRAW); } - (void) createIndexBuffer { glGenBuffers(1, &indexBufferID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * 16, indices, GL_STATIC_DRAW); } 

The above VBO creation methods are called by the special AtlasLibrary class , which initializes each instance of TexturedQuad.

Firstly, the vertices are located in the following format:

 // bottom left quad.vertices[0] = xMin; quad.vertices[1] = yMin; // bottom right quad.vertices[2] = xMax; quad.vertices[3] = yMin; // top left quad.vertices[4] = xMin; quad.vertices[5] = yMax; // top right quad.vertices[6] = xMax; quad.vertices[7] = yMax; 

Secondly, the texture coordinates are located in the following format (inverted to reflect the OpenGL ES tendency to mirror):

 // top left (of texture) quad.textureCoords[0] = uMin; quad.textureCoords[1] = vMax; // top right quad.textureCoords[2] = uMax; quad.textureCoords[3] = vMax; // bottom left quad.textureCoords[4] = uMin; quad.textureCoords[5] = vMin; // bottom right quad.textureCoords[6] = uMax; quad.textureCoords[7] = vMin; 

... further, VBO creation methods are called (in AtlasLibrary)

 [quad createVertexBuffers]; [quad createTextureCoordBuffers]; [quad createIndexBuffer]; 

Now meat and potatoes. Class SceneObject . SceneObjects are objects in the game that are renderable. They reference a TexturedQuad instance and contain information about rotation, translation, and scaling.

Here is the rendering method in SceneObject:

 - (void) render { // binds texture in OpenGL ES if not already bound [[AtlasLibrary sharedAtlasLibrary] ensureContainingTextureAtlasIsBoundInOpenGLES:self.containingAtlasKey]; glPushMatrix(); glTranslatef(translation.x, translation.y, translation.z); glRotatef(rotation.x, 1, 0, 0); glRotatef(rotation.y, 0, 1, 0); glRotatef(rotation.z, 0, 0, 1); glScalef(scale.x, scale.y, scale.z); // change alpha glColor4f(1.0, 1.0, 1.0, alpha); // vertices glBindBuffer(GL_ARRAY_BUFFER, texturedQuad.vertexBufferID); glVertexAttribPointer(ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT), &texturedQuad.vertices[0]); // texture coords glBindBuffer(GL_ARRAY_BUFFER, texturedQuad.textureCoordBufferID); glVertexAttribPointer(ATTRIB_TEXTURE_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT), &texturedQuad.textureCoords[0]); // bind index buffer array glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, texturedQuad.indexBufferID); // draw glDrawElements(GL_TRIANGLE_STRIP, sizeof(texturedQuad.indices) / sizeof(texturedQuad.indices[0]), GL_UNSIGNED_BYTE, texturedQuad.indices); glPopMatrix(); } 

I have a strong feeling that either the array of indices is structured incorrectly or the glDrawElements (..) function is called incorrectly.

To answer this question, please:

  • determine what I'm doing wrong, which will cause OpenGL ES not to draw my SceneObjects.
  • indicate the correct way to do what I'm trying to do (according to my structure, please)
  • provide any suggestions or links that may help (optional)

Thank you very much!

+4
source share
2 answers

I do not experience differences between OpenGL and OpenGL ES, but I do not see any glEnableVertexAttribArray () calls in your code.

The function is suspiciously missing in the OpenGL ES 1.1 docs , but it is in 2.0 and is used in the Apple OpenGL ES VBO article (thanks to JSPerfUnkn0wn ).

Here are some other good (though not ES) tutorials on Vertex Buffer Objects and Index Buffer Objects .

+1
source

If I am missing something, where do you download textures? You set the texture coordinates, but I do not see glBindTexture. And I also assume that alpha is a valid value.

See Apple's OpenGL ES VBO article , namely from Listing 9-1, and this OpenGL ES VBO Tutorial .

0
source

Source: https://habr.com/ru/post/1386950/


All Articles