[英]Drawing a cube in iOS with OpenGL and GLKit
我一直在關注本教程http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/以了解查看的工作原理,但是當我嘗試將其應用到iOS應用程序時,遇到了很多麻煩
所以基本上我的理解是:
從基本的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個邊界值( left
, right
, top
, bottom
), near
和遠clipping
平面。 定義此方法的目的是使Z
值等於near
任何頂點位置都將轉換為-1,而Z
值等於far
每個頂點位置都將轉換為1。 至於X
和Y
它們將根據轉換后的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.