2015-06-15 66 views
1

立方體我下面這個教程http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/瞭解如何觀看作品,但後來當我試圖把它在我的iOS應用程序我有這麼多的麻煩繪製iOS中使用OpenGL和GLKit

所以基本上我的理解是即:(?這個是什麼在iOS上的等價物)

  1. 模型最初是在原點,所以是相機
  2. 然後,使用GLM ::的lookAt到攝像機移動到合適的位置
  3. 應用投影變換從相機空間移動到同質單位立方體空間

從基本的iOS教程中,我發現了投影矩陣

float aspect = fabs(self.view.bounds.size.width/self.view.bounds.size.height); 
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); 
_modelViewProjectionMatrix = projectionMatrix; 

,我真的沒有下列計算明白......他們是怎麼想出65例如?

另一個教程這樣做:

glViewport(0, 0, self.view.bounds.size.width,self.view.bounds.size.height); 

實現: 我目前的程序只顯示藍屏(基本上是我的立方體的顏色) 這我假設是因爲相機是目前在原點

我有以下數據集

static const GLfloat cubeVertices[] = { 
    -1.0f,-1.0f,-1.0f, // triangle 1 : begin 
    -1.0f,-1.0f, 1.0f, 
    -1.0f, 1.0f, 1.0f, // triangle 1 : end 
    1.0f, 1.0f,-1.0f, // triangle 2 : begin 
    -1.0f,-1.0f,-1.0f, 
    -1.0f, 1.0f,-1.0f, // triangle 2 : end 
    1.0f,-1.0f, 1.0f, 
    -1.0f,-1.0f,-1.0f, 
    1.0f,-1.0f,-1.0f, 
    1.0f, 1.0f,-1.0f, 
    1.0f,-1.0f,-1.0f, 
    -1.0f,-1.0f,-1.0f, 
    -1.0f,-1.0f,-1.0f, 
    -1.0f, 1.0f, 1.0f, 
    -1.0f, 1.0f,-1.0f, 
    1.0f,-1.0f, 1.0f, 
    -1.0f,-1.0f, 1.0f, 
    -1.0f,-1.0f,-1.0f, 
    -1.0f, 1.0f, 1.0f, 
    -1.0f,-1.0f, 1.0f, 
    1.0f,-1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 
    1.0f,-1.0f,-1.0f, 
    1.0f, 1.0f,-1.0f, 
    1.0f,-1.0f,-1.0f, 
    1.0f, 1.0f, 1.0f, 
    1.0f,-1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 
    1.0f, 1.0f,-1.0f, 
    -1.0f, 1.0f,-1.0f, 
    1.0f, 1.0f, 1.0f, 
    -1.0f, 1.0f,-1.0f, 
    -1.0f, 1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 
    -1.0f, 1.0f, 1.0f, 
    1.0f,-1.0f, 1.0f 
}; 

這是我的設置,從iOS tutori非常基本的人

- (void)setupGL { 
    [EAGLContext setCurrentContext:self.context]; 
    [self loadShaders]; 

    glGenBuffers(1, &_vertexBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); 

    glVertexAttribPointer (GLKVertexAttribPosition, 
          3, 
          GL_FLOAT, GL_FALSE, 
          0, 
          BUFFER_OFFSET(0)); 
    glEnableVertexAttribArray(GLKVertexAttribPosition); 
    //glBindVertexArrayOES(0); 
} 

和我drawInRect和update方法

- (void)update { 
    //glViewport(0, 0, self.view.bounds.size.width, self.view.bounds.size.height); 
    float aspect = fabs(self.view.bounds.size.width/self.view.bounds.size.height); 
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); 
    _modelViewProjectionMatrix = projectionMatrix; 

} 

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 
    glClearColor(0.65f, 0.65f, 0.65f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT); 
    glUseProgram(_program); 
    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); 
    glDrawArrays(GL_TRIANGLES, 0, 12*3); 
} 

和我的頂點着色器

attribute vec4 position; 
uniform mat4 modelViewProjectionMatrix; 

void main() { 
    gl_Position = modelViewProjectionMatrix * position; 
} 

和我的片段着色器

void main() { 
    gl_FragColor = vec4 (0.165, 0.427, 0.620, 1.0); 
} 

回答

4

要的答案開始,什麼喲你正在尋找和失蹤的是GLKMatrix4MakeLookAt。剩下的就是如果你有興趣進一步瞭解。

你的假設似乎是正確的,但我認爲你沒有理解矩陣系統和openGL是如何工作的。你似乎明白如何使用它。因此,首先我們看到的是3個矩陣組件,然後可以將它們作爲產品插入到着色器中,或者作爲每個組件傳遞到着色器並在其中相乘。

第一個分量是投影矩陣。該組件反映屏幕上的投影,通常設置爲「正視」或「平截頭」。 「ortho」是一個正投影,意思是無論距離如何,物體都會呈現相同的大小。 「平截頭體」會產生一種效果,根據距離的不同,這些效果會使物體顯得更大或更小。在你的情況下,你正在使用帶有便利功能GLKMatrix4MakePerspective的「平截頭」。第一個參數描述了視角和您的樣本中的角度爲65度,第二個參數是縱橫比應該反映屏幕/視圖比例,最後兩個是裁剪平面。使用具有「平截頭體」的等效物將是:

GLfloat fieldOfView = M_PI_2; 
    GLfloat near = .1f; 
    GLfloat far = 1000.0f; 
    GLfloat screenRatio = 1.0f/2.0f; 

    GLfloat right = tanf(fieldOfView)*.5f * near; // half of the tagens of field of view 
    GLfloat left = -right; // symetry 
    GLfloat top = right*screenRatio; // scale by screen ratio 
    GLfloat bottom = -top; // symetry 

    GLKMatrix4MakeFrustum(left, right, bottom, top, near, far); 

第二個是通常用作「相機」的視圖矩陣。要使用這一個,最簡單的方法是調用某種形式的「lookAt」,在你的情況下是GLKMatrix4MakeLookAt。這應該回答你的問題「在iOS中相當於什麼?」。

第三個是描述座標系中物體位置的模型矩陣。這通常用於您可以將模型放置到所需的位置,設置特定的旋轉並在需要時對其進行縮放。

所以如何將它們放在一起就是在某一點上乘以所有的矩陣,並稱之爲模型視圖投影矩陣。這個矩陣然後用來乘以每個頂點位置來描述它的屏幕投影。

glViewport根本沒有這部分。這個函數將定義你正在繪製的緩衝區的哪一部分,而不是更多。嘗試將所有值分成一半,看看會發生什麼(比其他解釋更好)。

僅僅從數學的角度來解釋一下,openGL的實現如下:openGL只繪製所有座標軸[-1,1]內的片段(像素)。這意味着投影沒有任何魔法可以覆蓋它,但是頂點位置會發生變化,因此正確的值適合於此。

對於frustum例如需要4個邊界值(leftrighttopbottom),near和遠clipping飛機。該方法被定義爲使得具有等於near的值的任何頂點位置將被變換爲-1並且具有等於farZ值的每個位置將被變換爲1.所有的中間將採用線性內插。至於XY它們將取決於轉化Z值進行縮放,使得用於Z在0將由0,Znear 1.0縮放的,而其餘的則線性外推。

lookAt實際上與模型矩陣非常相似但相反。如果向後移動相機,則與向前移動對象相同,如果向左旋轉對象將顯示爲已移動並向右旋轉,依此類推...

模型矩陣將簡單地將所有頂點位置使用基本向量和翻譯。矩陣的相關部分是頂部3x3部分,它們是基本向量和底部(或在某些實現中的右側)3x1向量(1x3),即翻譯。想象最簡單的方法是在座標系內定義的座標系:零值(原點)位於矩陣的平移部分,X軸是3x3矩陣的第一行(列),Y是第二個Z三號。這3個向量的長度代表了重要座標的尺度......它們都融合在一起。

+0

非常有用的解釋比你這麼多!它爲我連接了點,因爲我在這裏和那裏閱讀的作品不能連接它們 – nevermind

+0

是的,這些系統可能非常令人沮喪,因爲有些很難理解。你可以找到幾百個例子,而不是兩個看起來一樣的例子。我很高興我的解釋對你有所幫助,雖然這對於這個領域的非專家來說非常重要。我很高興它幫助你。 –