我發現這樣做的最好方法是使用VAO和VBO。
我會先回答你使用VBOs的問題。
首先,假設你有存儲在以下陣列的兩個對象的兩個網格:
GLuint _vertexBufferCube1;
GLuint _vertexBufferCube2;
其中:
GLfloat gCubeVertexData1[36] = {...};
GLfloat gCubeVertexData2[36] = {...};
而且你還必須vertix緩衝區:
GLuint _vertexBufferCube1;
GLuint _vertexBufferCube2;
現在,繪製這兩個立方體(沒有VAO),你必須這樣做: 在繪製函數(從OpenGLES模板):
//Draw first object, bind VBO, adjust your attributes then call DrawArrays
glGenBuffers(1, &_vertexBufferCube1);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferCube1);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData1), gCubeVertexData1, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glDrawArrays(GL_TRIANGLES, 0, 36);
//Repeat for second object:
glGenBuffers(1, &_vertexBufferCube2);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferCube2);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData2), gCubeVertexData2, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glUseProgram(_program);
glDrawArrays(GL_TRIANGLES, 0, 36);
這將回答您的問題。但現在使用VAOs,你繪製函數的代碼要簡單得多(這是好事,因爲它是重複功能):
首先,你將它定義成VAOs:
GLuint _vertexArray1;
GLuint _vertexArray2;
,然後你會做所有的先前在繪圖方法中完成的步驟,您將在setupGL函數中完成,但綁定到VAO之後。然後在你的繪圖函數中,你只需綁定到你想要的VAO。
VAO這裏就像一個包含很多屬性的配置文件(想象一下智能設備配置文件)。每當你想改變顏色,桌面,字體等等時,不要改變顏色,桌面,字體等等,你只需要做一次,然後將其保存在配置文件名稱下。然後你只需切換配置文件。
所以你在setupGL中做了一次,然後在draw中切換它們。
當然你可以說你可以把代碼(沒有VAO)放在函數中並調用它。這是真的,但VAOs更高效根據蘋果:
http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html#//apple_ref/doc/uid/TP40008793-CH107-SW1
我們的代碼:
在setupGL:
glGenVertexArraysOES(1, &_vertexArray1); //Bind to first VAO
glBindVertexArrayOES(_vertexArray1);
glGenBuffers(1, &_vertexBufferCube1); //All steps from this one are done to first VAO only
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferCube1);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData1), gCubeVertexData1, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glGenVertexArraysOES(1, &_vertexArray2); // now bind to the second
glBindVertexArrayOES(_vertexArray2);
glGenBuffers(1, &_vertexBufferCube2); //repeat with the second mesh
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferCube2);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData2), gCubeVertexData2, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glBindVertexArrayOES(0);
然後終於在你的繪製方法:
glBindVertexArrayOES(_vertexArray1);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArrayOES(_vertexArray2);
glDrawArrays(GL_TRIANGLES, 0, 36);
感謝您的快速解答,我現在明白了。 –
這是一個很好問的問題。 – 3yanlis1bos
大多數示例都使用一個對象視圖進行旋轉和平移一次。要以不同的角度和位置繪製兩個對象,請在第一個對象之後應用相反的操作。例如。 translate1,rotate1,draw1,-rotate1,-translate1,translate2,rotate2,draw2 -rotate2,-translate2,ill快速發佈示例 –