2011-12-18 115 views
4

我正在开发一款使用OpenGL ES 1.1的iPhone游戏,并且需要使用顶点缓冲区对象才能渲染500多个粒子,而不会降低性能。OpenGL ES 1.1顶点缓冲区对象不工作

我的游戏能够使用非VBO方法成功绘制,但现在我已经尝试合并VBO,没有任何东西正在绘制。

请帮我确定我做错了什么,并提供一个正确的例子。

我有一个名为TexturedQuad类由以下部分组成:

// 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,顶点缓冲器被创建:

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

上面VBO创建方法由初始化每个TexturedQuad实例的自定义AtlasLibrary类调​​用。

首先,顶点被布置在以下格式:

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

其次,纹理坐标被设置在下面的格式(翻转以考虑的OpenGL ES的倾向镜像图像):

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

...接下来,VBO创作方法调用(在AtlasLibrary)

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

现在的肉和土豆。 SceneObject类。 SceneObjects是可呈现的游戏中的对象。它们引用TexturedQuad实例并包含有关旋转,平移和缩放的信息。

这里是在场景对象的渲染方法:

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

我有一个强烈的感觉,无论是我的指数阵列结构不正确或该glDrawElements(..)函数被调用不正确。

要回答这个问题,请:

  • 确定我在做什么不正确,会导致OpenGL ES的不画我SceneObjects。
  • 提供正确的方式做什么,我试图做的(根据我的框架,请)
  • 提供任何建议或链接可以帮助(可选)

非常感谢!

回答

0

除非我错过了什么,你在哪里加载纹理?你正在设置纹理坐标,但我看不到glBindTexture。而且我还假设alpha是一个有效值。

请参阅Apple OpenGL ES VBO article,即代码清单9-1和OpenGL ES VBO tutorial

+0

是的,纹理加载成功。 glBindTexture调用在方法 [[AtlasLibrary sharedAtlasLibrary] ensureContainingTextureAtlasIsBoundInOpenGLES:self.containingAtlasKey]中进行; 我知道那部分工作是因为它在我尝试使用VBOs之前工作,并且从那以后没有改变任何东西。所以纹理加载和绑定正在工作。 – BigSauce 2011-12-28 15:23:33

+0

可能已经发誓我回应了(或者我做了一些像关闭窗户一样愚蠢的事情)。 IIRC我的回答是关于'sizeof(vertices)'是4的事实,因为顶点是一个指针。当调用'glVertexAttribPointer'而不是一个指针时,将偏移量赋予缓冲区。我还提供了一个链接,您可以比较您的代码,但我完全不知道它现在是什么。它可能是[VBO - 只是例子](http://www.opengl.org/wiki/VBO_-_just_examples)根据我的历史来看,12月28日希望它有帮助 – 2012-01-01 17:33:25