OpenGL ES 1.1顶点缓冲对象不起作用。

4

我正在使用OpenGL ES 1.1开发iPhone游戏,需要使用顶点缓冲对象来呈现500多个粒子,以避免性能下降。

在没有使用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;

在中,创建了顶点缓冲区:
- (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创建方法由自定义的AtlasLibrary类调用,该类初始化每个TexturedQuad实例。
首先,顶点按以下格式排列:
// 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;

接下来,在AtlasLibrary中调用了VBO创建方法。
[quad createVertexBuffers];
[quad createTextureCoordBuffers];
[quad createIndexBuffer];

现在进入正题,SceneObject类。SceneObjects是游戏中可渲染的对象。它们引用一个TexturedQuad实例,并包含有关旋转、平移和缩放的信息。
以下是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();
}

我强烈感觉我的索引数组或者glDrawElements(..)函数的调用有误。

为了回答这个问题,请:

  • 找出我哪里做错了,导致OpenGL ES无法绘制我的SceneObjects。
  • 提供正确的做法(请根据我的框架)
  • 提供任何可能有帮助的建议或链接(可选)

非常感谢!

2个回答

1

0
除非我漏掉了什么,你在哪里加载纹理?你正在设置纹理坐标,但我没有看到glBindTexture。我还假设alpha是一个有效的值。
请参见Apple OpenGL ES VBO article,特别是从列表9-1开始,以及这个OpenGL ES VBO tutorial

是的,纹理成功加载。 glBindTexture 调用在方法中执行: [[AtlasLibrary sharedAtlasLibrary] ensureContainingTextureAtlasIsBoundInOpenGLES:self.containingAtlasKey];我知道那部分代码可行,因为在我尝试使用 VBOs 之前它就能正常工作,并且自那以后没有对其进行任何更改。 因此,纹理加载和绑定工作正常。 - BigSauce
我记得我回复过(或者可能是我做了一些傻事,比如关闭了窗口)。如果我没记错的话,我的回复是关于sizeof(vertices)为4的事实,因为vertices是一个指针。在调用glVertexAttribPointer时,你需要给出缓冲区中的偏移量而不是指针。我还提供了一个链接,你可以将其与你的代码进行比较,但我现在完全不知道它是什么了。根据我12月28日的历史记录,它可能是VBO - just examples。希望能有所帮助。 - Keldon Alleyne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接