簡體   English   中英

使用OpenGL和GLKit在iOS中繪制立方體

[英]Drawing a cube in iOS with OpenGL and GLKit

我一直在關注本教程http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/以了解查看的工作原理,但是當我嘗試將其應用到iOS應用程序時,遇到了很多麻煩

所以基本上我的理解是:

  1. 模型最初是在原點,相機也是
  2. 然后,我們使用glm :: lookAt將相機移至正確的位置(在iOS中相當於什么?)
  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教程

- (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);
}

首先, 您要尋找和缺少的是 GLKMatrix4MakeLookAt 剩下的只是您對更深入的了解感興趣。

您的假設似乎是正確的,但我認為您無法理解矩陣系統和openGL是如何工作的。 您似乎確實了解如何使用它。 首先,我們通常要看的是3個矩陣分量,然后可以將它們作為乘積插入到着色器中,或者作為每個分量傳遞到着色器並在那里進行乘法。

第一部分是投影矩陣。 此組件反映屏幕上的投影,通常設置為“正交”或“視錐”。 “正交”是正交投影,這意味着無論距離多遠,物體都將顯示相同的大小。 “視錐”將產生一種效果,該效果將根據距離使對象顯得更大或更小。 在您的情況下,您正在使用帶有便利功能GLKMatrix4MakePerspective “ frustum”。 第一個參數描述的是視場,在您的示例中為65度角,第二個參數是應反映屏幕/視圖比率的長寬比,最后兩個是剪切平面。 與“ frustum”一起使用的等效項為:

    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平面。 定義此方法的目的是使Z值等於near任何頂點位置都將轉換為-1,而Z值等於far每個頂點位置都將轉換為1。 至於XY它們將根據轉換后的Z值進行縮放,這樣對於0處的Z將按0進行縮放,將Z near的將按1.0進行縮放,然后其余部分進行線性外推。

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

模型矩陣將使用基本向量和平移簡單地變換所有頂點位置。 此矩陣的相關部分是頂部3x3部分(即基本向量)和底部(或某些實現中的右邊)3x1向量(1x3),即平移。 想象這是在坐標系統內部定義的坐標系統的最簡單方法:零值(原點)在矩陣的平移部分,X軸是3x3矩陣的第一行(列),Y軸是第二行和Z第三。 這3個向量的長度表示所關注坐標的比例...所有這些都可以放在一起。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM