gpt4 book ai didi

ios - 使用OpenGL和GLKit在iOS中绘制立方体

转载 作者:行者123 更新时间:2023-12-01 18:11:18 31 4
gpt4 key购买 nike

我正在按照本教程http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/来了解查看的工作原理,但是当我尝试将其应用到我的iOS应用程序时,我遇到了很多麻烦

所以基本上我的理解是:

  • 该模型最初位于原点,相机
  • 也是如此
  • 然后我们使用glm::lookAt将相机移到正确的位置
    (在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个边界值( leftrighttopbottom), near和far clipping平面。定义此方法是为了将 Z值等于 near的任何顶点位置都转换为-1,并将 Z值等于 far的每个位置都转换为1。所有中间位置都将进行线性插值。至于 XY,它们将根据转换后的 Z值进行缩放,这样对于0处的 Z将按0进行缩放,将 Z处的 near进行1.0缩放,然后其余部分进行线性外推。
    lookAt实际上与模型矩阵非常相似,但是相反。如果向后移动相机,则与向前移动对象相同;如果向左旋转,则该对象将显示为向右移动,依此类推...

    模型矩阵将使用基本向量和平移简单地变换所有顶点位置。此矩阵的相关部分是顶部3x3部分(即基本向量)和底部(或某些实现中的右边)3x1向量(1x3),即平移。想象这是在坐标系统内部定义的坐标系统的最简单方法:零值(原点)在矩阵的平移部分,X轴是3x3矩阵的第一行(列),Y轴是第二行和Z第三。这三个向量的长度表示所关注坐标的比例...所有这些都可以放在一起。

    关于ios - 使用OpenGL和GLKit在iOS中绘制立方体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30854053/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com