2012-02-03 66 views
5

我正在用OpenGL ES 2.0構建一個iOS遊戲,其中包含一個包含大約100個不同「對象」的場景,我需要能夠彼此獨立地進行轉換。我是OpenGL ES的新手。因此,我最初認爲我應該從OpenGL ES 1.1開始,然後將應用程序遷移到2.0以利用增強的視覺效果。然而,正如我對1.1的熟悉程度一樣,我意識到,部分基於蘋果公司以2.0爲中心的OpenGL Xcode模板,它將比直接進入2.0的價值戰鬥更麻煩,所以我咬緊牙關。如何在OpenGL ES 2.0中獨立處理對象?

現在,我發現很難掌握足夠的概念來對我的頂點數組對象進行簡單的變換,而彼此獨立。我在OpenGLES 2.0文檔中看到,最好的方法是使用多個VBO,每個頂點數組使用一個VBO。但是,我似乎無法在不影響整個場景的情況下轉換其中一個。

我開始與蘋果公司的OpenGL ES模板項目和精簡它,使得setupGL方法是這樣的:

-(void)setupGL 
{ 
    // Setup 
    [EAGLContext setCurrentContext:self.context];   
    [self loadShaders]; 
    self.effect = [[GLKBaseEffect alloc] init]; 
    self.effect.light0.enabled = GL_TRUE; 
    self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); 
    glEnable(GL_DEPTH_TEST); // do depth comparisons and update the depth buffer 

    // Initialize first buffer 
    glGenVertexArraysOES(1, &_vertexArray); 
    glBindVertexArrayOES(_vertexArray);  
    glGenBuffers(1, &_vertexBuffer);  
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);  
    glBufferData(GL_ARRAY_BUFFER, sizeof(gPyramidVertexData), gPyramidVertexData, GL_DYNAMIC_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); 

    // Initialize second buffer 
    glGenVertexArraysOES(2, &_vertexArray2); 
    glBindVertexArrayOES(_vertexArray2); 
    glGenBuffers(2, &_vertexBuffer2); 
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, 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); 
} 

我知道這是令人難以置信的草率代碼 - 我基本上是複製和粘貼緩衝區創建部分設置爲在不同的緩衝區中試驗兩個不同的vertextArrays。這似乎已經奏效,因爲我可以在drawInRect方法呈現兩個緩衝區:

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect 
{ 
    glBindVertexArrayOES(_vertexArray); 
    glUseProgram(_program); 
    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); 
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);  
    glDrawArrays(GL_TRIANGLES, 0, numberOfVerteces); 

    glBindVertexArrayOES(_vertexArray2); 
    glUseProgram(_program); 
    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); 
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); 
    glDrawArrays(GL_TRIANGLES, 0, numberOfVerteces2); 
} 

我的問題是當我嘗試做一個頂點數組轉換,而不會影響另外一個。我試圖在glDrawArrays調用之前在上面的方法中添加轉換,但沒有成功 - 我認爲這隻適用於1.1。看來我必須變換的更新方法中完成:

-(void)update 
{ 
    float aspect = fabsf(self.view.bounds.size.width/self.view.bounds.size.height); 
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);   
    self.effect.transform.projectionMatrix = projectionMatrix; 

    GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); 
    baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _sceneRotation, 1.0f, 1.0f, 1.0f); 

    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, zoomFactor); 
    modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _objectRotation, 0.0f, 1.0f, 0.0f); 
    modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); 

    _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); 
    _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);  
} 

但是,這是我得到真正confused--它不是完全清楚,我怎麼能修改此方法做變換到一個VBO或其他。上面的代碼甚至都沒有明確指出某個特定的緩衝區。

最終我想通過將每個遊戲對象的代碼移動到自定義類的實例中來擴展我的遊戲,該自定義類將處理轉換等。但是,我想知道如果我完全誤導了我在這樣做之前。

回答

4

如果這對任何有類似問題的人有幫助,我在Ian Terrell的優秀博客Games by Ian Terrell上找到了我正在尋找的答案。

特別是,this tutorial及其附帶的示例代碼正是我需要掌握這個非常複雜的主題。希望這可以幫助!

+0

所以這個想法是有一個GLKViewController並使用NSObject來放置對象?然後,你可以操縱每個NSObject .. – 2013-03-20 14:25:16

+0

是的,這基本上是正確的。我最終將所有形狀重構成了很好的封裝NSObject,這使得它們更容易處理。我上面鏈接的教程是一個很好的開始。 – todd412 2013-03-23 00:46:52

0

GLKMatrix4 _modelViewProjectionMatrix [5]; GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(-1.0f,1.0f,-1.0f/aspect,1.0f/aspect,-10.0f,10.0f);以及其中,

for (int i=0; i<5;i++) { 
    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(i*0.2+ 0.3f, 0.0f, 0.0f); 
    modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, GLKMatrix4MakeZRotation(0.0 - _rotation)); 
    modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, GLKMatrix4MakeXRotation(0.0 - _rotation)); 
    modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, GLKMatrix4MakeYRotation(0.20 - _rotation)); 

    _modelViewProjectionMatrix[i] = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); 
}