iOS 使用GLSL实现旋转金字塔

索引顶点

绘制一个金字塔需要5个面,4个侧边三角形和底部两个三角形。如果使用glDrawArray绘制金字塔,需要6个三角形,共18个顶点。
这次使用索引绘图

    /*
     参数列表:
     mode:要呈现的画图的模型 
                GL_POINTS
                GL_LINES
                GL_LINE_LOOP
                GL_LINE_STRIP
                GL_TRIANGLES
                GL_TRIANGLE_STRIP
                GL_TRIANGLE_FAN
     count:绘图个数
     type:类型
             GL_BYTE
             GL_UNSIGNED_BYTE
             GL_SHORT
             GL_UNSIGNED_SHORT
             GL_INT
             GL_UNSIGNED_INT
     indices:绘制索引数组
     */
     void glDrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices);

使用索引绘制金字塔需要5个顶点,使用索引数组告诉哪三个顶点组成一个三角形。

    //顶点数组
   GLfloat attrArr[] =
    {
           //顶点坐标                颜色坐标
        -0.5f, 0.5f, 0.0f,      1.0f, 0.0f, 1.0f, //左上0
        0.5f, 0.5f, 0.0f,       1.0f, 0.0f, 1.0f, //右上1
        -0.5f, -0.5f, 0.0f,     1.0f, 1.0f, 1.0f, //左下2
        0.5f, -0.5f, 0.0f,      1.0f, 1.0f, 1.0f, //右下3
        0.0f, 0.0f, 1.0f,       0.0f, 1.0f, 0.0f, //顶点4
    };

顶点数组attrArr共有5个,下标从0到4,下图是金字塔的俯视图。


俯视图

以底部正方形为例,需要两个三角形才能组成一个正方形。
顶点数组中 第 0、3、2个顶点可以组成一个三角形,第0、1、3个顶点可以组成另一个三角形。

矩阵变换

在openGL中顶点矩阵变换需要经过,model -> view -> projection 变换。因此需要将projection Matrix 和 modeView Matrix 传递到顶点着色器中,进行矩阵变换得到最后的顶点坐标。
顶点着色器代码

attribute vec4 position;
attribute vec4 positionColor;

uniform mat4 projectionMatrix; //透视矩阵
uniform mat4 modeViewMatrix; //

varying lowp vec4 varyColor;//传递到片元着色器的颜色值

void main(){
    varyColor = positionColor;
    
    vec4 vPos;
    //矩阵变换后的顶点位置
    vPos = projectionMatrix * modeViewMatrix * position;
    gl_Position = vPos;
}

注意顶点在OpenGL中是以列向量的形式存在, 变换矩阵左乘顶点。

    GLuint projectionMatrixSlot = glGetUniformLocation(self.myProgram, "projectionMatrix");
    GLuint modeviewMatrixSlot =glGetUniformLocation(self.myProgram, "modeViewMatrix");
    
    float width = self.frame.size.width;
    float height = self.frame.size.height;
    float aspect = width / height;
    //投影矩阵
    KSMatrix4 _projectionMatrix;
    //加载单元矩阵
    ksMatrixLoadIdentity(&_projectionMatrix);
    //投影变换
    ksPerspective(&_projectionMatrix, 30, aspect, 5, 20);
    
    //将投影矩阵传递到顶点着色器中
    glUniformMatrix4fv(projectionMatrixSlot, 1, GL_FALSE,(GLfloat *) &_projectionMatrix.m[0][0]);
    
    //模型视图矩阵
    KSMatrix4 _modelviewMatrix;
    ksMatrixLoadIdentity(&_modelviewMatrix);
    //矩阵后移10
    ksTranslate(&_modelviewMatrix, 0, 0, -10);
    //旋转矩阵
    KSMatrix4 _rotationMatrix;
    ksMatrixLoadIdentity(&_rotationMatrix);
    ksRotate(&_rotationMatrix, xDegree, 1, 0, 0); // x轴旋转度数
    ksRotate(&_rotationMatrix, yDegree, 0, 1, 0); // y轴旋转度数
    ksRotate(&_rotationMatrix, zDegree, 0, 0, 1); // z轴旋转度数
    
    //模型视图矩阵与选择矩阵进行叉乘
    ksMatrixMultiply(&_modelviewMatrix, &_rotationMatrix, &_modelviewMatrix);
    //将叉乘后的modelviewMatrix传入顶点着色器
    glUniformMatrix4fv(modeviewMatrixSlot, 1, GL_FALSE, (GLfloat *)&_modelviewMatrix);
    
    glEnable(GL_CULL_FACE);
    
    // 使用索引绘制图形
    glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(indices[0]), GL_UNSIGNED_INT, indices);

你可能感兴趣的:(iOS 使用GLSL实现旋转金字塔)