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;

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;

第 2 に、テクスチャ座標は次の形式で配置されます (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 インスタンスを参照し、回転、移動、およびスケールに関する情報を含みます。

SceneObject の render メソッドは次のとおりです。

- (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 を描画しない原因となる間違った操作を特定します。
  • 私がやろうとしていることを行う正しい方法を提供してください(私のフレームワークに従ってください)
  • 役立つ可能性のある提案やリンクを提供してください(オプション)

本当にありがとう!

4

2 に答える 2

1

OpenGL と OpenGL ES の違いについては経験がありませんが、コードでglEnableVertexAttribArray()の呼び出しが見られません。

この関数は、OpenGL ES 1.1 docsには疑わしいほど存在しませんが、2.0にはあり、 Apple の OpenGL ES VBO 記事( JSPerfUnkn0wn に感謝)で使用されています。

Vertex Buffer ObjectsおよびIndex Buffer Objectsに関するその他の優れた (ES 以外の) チュートリアルを次に示します。

于 2012-03-08T15:22:37.467 に答える
0

何かが欠けていない限り、テクスチャはどこにロードされていますか? テクスチャ座標を設定していますが、glBindTexture が表示されません。alphaまた、有効な値であると想定しています。

リスト 9-1 のApple OpenGL ES VBO 記事と、このOpenGL ES VBO チュートリアルを参照してください。

于 2011-12-27T20:46:56.707 に答える