2011-12-18 122 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