opengles3.0 学习,顶点着色器(六)
顶点着色器输入包括:
属性: 用顶点数组提供的逐顶点数据
统一变量和统一变量缓冲区:顶点着色器使用的不变数据
采样器:代表顶点着色器使用的纹理的特殊统一变量类型
着色器程序:顶点着色器的源码。
顶点着色器的输出乘坐顶点着色器输出变量。再图元光栅化阶段,为每个生产的片段计算这些变量,并作为片段
计算这些变量,并作为拍那段着色器的输入传入.
顶点着色器的位置输入保存为物体坐标,而输出为裁剪坐标。
内建特殊变量:
gl_VertexID是一个输入变量,用于保存顶点的整数索引。
gl_InstanceID是一个输入变量,用于保存实例化绘图调用中的图元的实例编号。
gl_Position用于输出顶点位置的裁剪坐标。
gl_PonitSize用于写入以像素表示的点精灵尺寸。
gl_FrontFaceing是一个特殊的变量。
内建统一状态:
顶点着色器内可用的唯一内建统一状态是窗口坐标中的深度范围,这由内建统一变量名gl_DepthRange给出。
内建常量:
矩阵:
组成MVP矩阵的每个单独矩阵执行的变换如下:
模型矩阵:将物体坐标变为世界坐标
视图矩阵:将世界坐标变为眼坐标
投影矩阵:将眼睛坐标变为裁剪坐标
模型-视图矩阵:
模型和视图矩阵合并为一个矩阵,称做模型-视图矩阵
这个4X4的矩阵将顶点位置从物体坐标变换为眼睛坐标,组合了从物体坐标到世界坐标和世界坐标到眼坐标的转换。再固定功能
opengl中,模型-视图矩阵可以用glRotatef,glTra-nslatef和glScalef等函数的创建。因为这些函数再Opengles2.0或者3.0中是不存在的。
因此这些矩阵的处理只能应用程序来处理。
void ESUTIL_API
esTranslate ( ESMatrix *result, GLfloat tx, GLfloat ty, GLfloat tz )
{
result->m[3][0] += ( result->m[0][0] * tx + result->m[1][0] * ty + result->m[2][0] * tz );
result->m[3][1] += ( result->m[0][1] * tx + result->m[1][1] * ty + result->m[2][1] * tz );
result->m[3][2] += ( result->m[0][2] * tx + result->m[1][2] * ty + result->m[2][2] * tz );
result->m[3][3] += ( result->m[0][3] * tx + result->m[1][3] * ty + result->m[2][3] * tz );
}
void ESUTIL_API
esRotate ( ESMatrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
{
GLfloat sinAngle, cosAngle;
GLfloat mag = sqrtf ( x * x + y * y + z * z );
sinAngle = sinf ( angle * PI / 180.0f );
cosAngle = cosf ( angle * PI / 180.0f );
if ( mag > 0.0f )
{
GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs;
GLfloat oneMinusCos;
ESMatrix rotMat;
x /= mag;
y /= mag;
z /= mag;
xx = x * x;
yy = y * y;
zz = z * z;
xy = x * y;
yz = y * z;
zx = z * x;
xs = x * sinAngle;
ys = y * sinAngle;
zs = z * sinAngle;
oneMinusCos = 1.0f - cosAngle;
rotMat.m[0][0] = ( oneMinusCos * xx ) + cosAngle;
rotMat.m[0][1] = ( oneMinusCos * xy ) - zs;
rotMat.m[0][2] = ( oneMinusCos * zx ) + ys;
rotMat.m[0][3] = 0.0F;
rotMat.m[1][0] = ( oneMinusCos * xy ) + zs;
rotMat.m[1][1] = ( oneMinusCos * yy ) + cosAngle;
rotMat.m[1][2] = ( oneMinusCos * yz ) - xs;
rotMat.m[1][3] = 0.0F;
rotMat.m[2][0] = ( oneMinusCos * zx ) - ys;
rotMat.m[2][1] = ( oneMinusCos * yz ) + xs;
rotMat.m[2][2] = ( oneMinusCos * zz ) + cosAngle;
rotMat.m[2][3] = 0.0F;
rotMat.m[3][0] = 0.0F;
rotMat.m[3][1] = 0.0F;
rotMat.m[3][2] = 0.0F;
rotMat.m[3][3] = 1.0F;
esMatrixMultiply ( result, &rotMat, result );
}
}
投影矩阵:
将眼睛坐标变为裁剪坐标
void ESUTIL_API
esFrustum ( ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ )
{
float deltaX = right - left;
float deltaY = top - bottom;
float deltaZ = farZ - nearZ;
ESMatrix frust;
if ( ( nearZ <= 0.0f ) || ( farZ <= 0.0f ) ||
( deltaX <= 0.0f ) || ( deltaY <= 0.0f ) || ( deltaZ <= 0.0f ) )
{
return;
}
frust.m[0][0] = 2.0f * nearZ / deltaX;
frust.m[0][1] = frust.m[0][2] = frust.m[0][3] = 0.0f;
frust.m[1][1] = 2.0f * nearZ / deltaY;
frust.m[1][0] = frust.m[1][2] = frust.m[1][3] = 0.0f;
frust.m[2][0] = ( right + left ) / deltaX;
frust.m[2][1] = ( top + bottom ) / deltaY;
frust.m[2][2] = - ( nearZ + farZ ) / deltaZ;
frust.m[2][3] = -1.0f;
frust.m[3][2] = -2.0f * nearZ * farZ / deltaZ;
frust.m[3][0] = frust.m[3][1] = frust.m[3][3] = 0.0f;
esMatrixMultiply ( result, &frust, result );
}
void ESUTIL_API
esPerspective ( ESMatrix *result, float fovy, float aspect, float nearZ, float farZ )
{
GLfloat frustumW, frustumH;
frustumH = tanf ( fovy / 360.0f * PI ) * nearZ;
frustumW = frustumH * aspect;
esFrustum ( result, -frustumW, frustumW, -frustumH, frustumH, nearZ, farZ );
}
aspect =width/height;
fovy:视野角度(0-180)
计算MVP矩阵------模型-视图矩阵和投影矩阵的乘积。
esMatrixMultiply(&userData->mvpMatrix, &modelview, &projection)
MVP矩阵用glUniformMatrix4fv加载到统一变量中,供着色器使用:
userdata->mvpLoc = glGetUniformLocation(userData->programObject, "u_mvpMatrix");
加载MVP
glUniformMatrix4fx(userData->mvpLoc,1,GL_FALSE,(GLfloat*)&userData->mvpMatrix,m[0][0])