索引顶点
绘制一个金字塔需要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);