2012-03-17 21 views
4

私は、OpenGL ES 1.1のiPhone用ゲームで幾分複雑なモデルのレンダリングを改善するためにVertex Buffer Objects(VBOs)を使用したいと思います。 SOとこの(http://playcontrol.net/ewing/jibberjabber/opengl_vertex_buffer_object.html)チュートリアルのいくつかの記事を読んだ後、私はまだVBOを理解することができず、Cheetah 3Dのエクスポートモデル形式を使ってVBOを実装する方法を理解していません。誰かがVBOを実装し、それを使って与えられたデータ構造で頂点を描画し、その構文を説明する例を教えてください。私はどんな助けにも大いに感謝します!iPhone Cheetah 3D OpenGL ES頂点バッファオブジェクト(VBO)の例

#define body_vertexcount 434 
#define body_polygoncount 780 

// The vertex data is saved in the following format: 
// u0,v0,normalx0,normaly0,normalz0,x0,y0,z0 
float body_vertex[body_vertexcount][8]={ 
{0.03333, 0.00000, -0.68652, -0.51763, 0.51063, 0.40972, -0.25028, -1.31418}, 
{...}, 
{...} 
} 

GLushort body_index[body_polygoncount][3]={ 
{0, 1, 2}, 
{2, 3, 0} 
} 

私はPro OpenGL ES(Appress)の第9章の助けを借りて次のコードを書いています。私はDrawElementsコマンドでEXC_BAD_ACCESSを取得していますが、なぜその理由がわかりません。誰かが光を放つことができるだろうか?おかげで - ここ

// First thing we do is create/setup the index buffer 
glGenBuffers(1, &bodyIBO); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bodyIBO); 

// For constrast, instead of glBufferSubData and glMapBuffer, 
// we can directly supply the data in one-shot 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, body_polygoncount*sizeof(GLubyte), body_index, GL_STATIC_DRAW); 

// Define our data structure 
int numXYZElements = 3; 
int numNormalElements = 3; 
int numTextureCoordElements = 2; 
long totalXYZBytes; 
long totalNormalBytes; 
long totalTexCoordinateBytes; 
int numBytesPerVertex; 

// Allocate a new buffer 
glGenBuffers(1, &bodyVBO); 

// Bind the buffer object to use 
glBindBuffer(GL_ARRAY_BUFFER, bodyVBO); 

// Tally up the size of the data components 
numBytesPerVertex = numXYZElements; 
numBytesPerVertex += numNormalElements; 
numBytesPerVertex += numTextureCoordElements; 
numBytesPerVertex *= sizeof(GLfloat); 

// Actually allocate memory on the GPU (Data is static here) 
glBufferData(GL_ARRAY_BUFFER, numBytesPerVertex * body_vertexcount, 0, GL_STATIC_DRAW); 

// Upload data to the cache (memory mapping) 
GLubyte *vboBuffer = (GLubyte *)glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); 

// Caclulate the total number of bytes for each data type 
totalXYZBytes = numXYZElements * body_vertexcount * sizeof(GLfloat); 
totalNormalBytes = numNormalElements * body_vertexcount * sizeof(GLfloat); 
totalTexCoordinateBytes = numTextureCoordElements * body_vertexcount * sizeof(GLfloat); 

// Set the total bytes property for the body 
self.bodyTotalBytes = totalXYZBytes + totalNormalBytes + totalTexCoordinateBytes; 

// Setup the copy of the buffer(s) using memcpy() 
memcpy(vboBuffer, body_vertex, self.bodyTotalBytes); 

// Perform the actual copy 
glUnmapBufferOES(GL_ARRAY_BUFFER); 

が、私は例外を取得していた描画コマンドです:

// Activate the VBOs to draw 
    glBindBuffer(GL_ARRAY_BUFFER, bodyVBO); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bodyIBO); 

    // Setup drawing 
    glMatrixMode(GL_MODELVIEW); 
    glEnable(GL_TEXTURE_2D); 
    glClientActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D,lightGreyInt); 

    // Setup pointers 
    glVertexPointer(3, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 0); 
    glTexCoordPointer(2, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 12); 
    glNormalPointer(GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 24); 

    // Now draw the body 
    glDrawElements(GL_TRIANGLES, body_polygoncount,GL_UNSIGNED_SHORT, (GLvoid*)((char*)NULL)); 
    //glDrawElements(GL_TRIANGLES, body_polygoncount, GL_UNSIGNED_SHORT, nil); 
    //glDrawElements(GL_TRIANGLES,body_polygoncount*3,GL_UNSIGNED_SHORT,body_index); 
+0

頂点配列とその他のOpenGLがどのように動作するかを知っていると仮定すると、これは非常にうまく説明できる学習リソースがないとは思えません(**あなたの** OpenGL ES 1.1ゲームの示唆)。あなたは[こちら](http://www.songho.ca/opengl/gl_vbo.html)も見ているかもしれませんが、あなたの質問からリンクされたチュートリアルは妥当性があります(私はそれを見渡しました)。 –

+0

あなたはどの部分に問題がありますか?私たちは単にコードを書くつもりではありません。データ構造と構文については理解できませんか?私たちは合理的な答えを定式化することができるように、できるだけ明示的にしてください。 – user1118321

+0

私は自分のコードを貼り付けました。特に、glDrawElements呼び出しでインタリーブされたデータをレンダリングする際に問題があります。私はEXC_BAD_ACCESSを手に入れています。本当に助けていただければ幸いです。 – PhilBot

答えて

3

まあ最初に、すべてのインデックスバッファのが、小さすぎると、あなただけのbody_polygoncountインデックスを持っていませんが、 body_polygoncount * 3。あなたのデータは最初のテクスチャが含まれているので、あなたはまた、彼らはショートパンツだから、あなたがGLushortなくGLubyte必要、種類を台無しにするので、それはその後、

glBufferData(GL_ELEMENT_ARRAY_BUFFER, body_polygoncount*3*sizeof(GLushort), 
      body_index, GL_STATIC_DRAW); 

されるべきであり、あなたは、あなたの属性のオフセットを台無しにglDrawElementsは、三角形の数が、要素(インデックス)の数を与えていないあなたを呼び出すにCOORDSは、その後、通常とは、各頂点の位置が、それはそう、ついに

glVertexPointer(3, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 20); //3rd, after 5*4 byte 
glTexCoordPointer(2, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 0); //1st 
glNormalPointer(GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 8);  //2nd, after 2*4 bytes 

すべきであり、それはする必要があります

glDrawElements(GL_TRIANGLES, body_polygoncount*3, 
       GL_UNSIGNED_SHORT, (GLvoid*)((char*)NULL)); 

それ以外の場合は、コードは合理的です(もちろん、マッピングは無意味で、ちょうどglBufferDataを使用したかもしれませんが、学習のためにやったと思います)。

しかし、VBOなしでクライアント側の頂点配列を使っただけで、OpenGL ES 1.1には即時モードglBegin/glEndがないと思っても、これらのエラーはすべて発生しているのではないでしょうか。だから私はあなたのゲームがなぜこれらのエラーを認識していない場合、VBOなしで以前に働いたのだろうかと思います。

+0

ありがとうございます。私は間違いを見ています。私は以前のように描画していました:// gunX描画 - 描画とテクスチャproceedure for gunX // glBindTexture(GL_TEXTURE_2D、lightGreyInt); glVertexPointer(3、GL_FLOAT、sizeof(vertexStruct)、&interpolatedVerticesGun [0] [5]); glTexCoordPointer(2、GL_FLOAT、sizeof(vertexStruct)、&interpolatedVerticesGun [0] [0]); glNormalPointer(GL_FLOAT、sizeof(vertexStruct)、&interpolatedVerticesGun [0] [2]); glDrawElements(GL_TRIANGLES、gun2_polygoncount * 3、GL_UNSIGNED_SHORT、gun2_index); – PhilBot

関連する問題