OpenGL ES 1.1顶点缓冲区对象不起作用 [英] OpenGL ES 1.1 Vertex Buffer Object Not Working

查看:123
本文介绍了OpenGL ES 1.1顶点缓冲区对象不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我的游戏能够使用非VBO方法成功绘制,但是现在我尝试合并VBO,因此不再绘制任何图形.

My game was able to draw successfully using the non-VBO method, but now that I've attempted to incorporate VBOs, nothing is drawing anymore.

请帮助我确定我在做什么错,并提供正确的示例.

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

我有一个名为 TexturedQuad 的类,该类包含以下内容:

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 中,创建了顶点缓冲区:

In TexturedQuad.m, the vertex buffers are created:

- (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实例.

The above VBO creation methods are invoked by a custom AtlasLibrary class which initializes each TexturedQuad instance.

首先,顶点按以下格式排列:

Firstly, the vertices are arranged 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;

第二,纹理坐标以以下格式排列(翻转以说明OpenGL ES镜像的趋势):

Secondly, texture coordinates are arranged in the following format (flipped to account for OpenGL ES's tendency to mirror images):

// 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中)

...next, the VBO-creation methods are called (in AtlasLibrary)

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

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

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

这是SceneObject中的渲染方法:

Here is the render 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();
}

我强烈感到索引数组的结构不正确,或者glDrawElements(..)函数的调用不正确.

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

要回答此问题,请:

  • 确定我做错了什么,这会导致OpenGL ES无法绘制我的SceneObjects.
  • 提供正确的方法来完成我想做的事情(请根据我的框架)
  • 提供任何可能有用的建议或链接(可选)

非常感谢!

推荐答案

我对OpenGL和OpenGL ES之间的区别没有经验,但是我没有看到对

I'm not experienced in the differences between OpenGL and OpenGL ES, but I'm not seeing any calls to glEnableVertexAttribArray() in your code.

OpenGL ES 1.1文档中可疑地缺少该功能>,但位于 2.0 中,并且正在 Apple的OpenGL ES VBO文章(感谢 JSPerfUnkn0wn ).

The function is suspiciously absent in the OpenGL ES 1.1 docs, but is in 2.0, and is being used in Apple's OpenGL ES VBO article (thanks JSPerfUnkn0wn).

关于 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆