2015-06-15 67 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

是的,这些系统可能非常令人沮丧,因为有些很难理解。你可以找到几百个例子,而不是两个看起来一样的例子。我很高兴我的解释对你有所帮助,虽然这对于这个领域的非专家来说非常重要。我很高兴它帮助你。 –