OpenGL ES一些函数详解(一)
glLoadIdentity的作用是将当前模型视图矩阵转换为单位矩阵(行数和列数相同的矩阵,并且矩阵的左上角至右下角的连线上的元素都为1,其它元素都为0),这样可以方便矩阵的乘法运算。
glMultMatrix矩阵的乘法.
如:
glLoadIdentity(); glMultiMatrix(A); glMultiMatrix(B); glMultiMatrix(C);
针对行向量和当前矩阵,上述代码可等价于:
(vx vy vz 1) *C*B*A
结果是一个1行4列的矩阵。
你可能会奇怪,为什么程序和实际矩阵的运算顺序是相反的呢。可以这么想像一下,glMultiMatrix先将矩阵加入到一个栈中保存,当所有的glMultiMatrix操作都完成后,再依次从栈中将缓存的矩阵取出并做相应的乘法操作。由于栈结构是先进后出的数据结构,所以可以猜想glMultiMatrix在执行时并没有直接将矩阵进行计算,而是先将矩阵放在了栈缓存中。
对当前模型视图进行缩放,在OpenGL ES 1.0中可以使用glScale*函数,而在2.0中需要自己设置缩放矩阵。
如,分别使用sx,sy,sz表示在x,y,z轴上的缩放比例,那么在1.0中可以这样缩放模型视图:
glScalef(sx, sy, sz);
在2.0中你需要这么做:
float scale[16] = {sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1 }; glMultiMatrixf(scale);
缩放矩阵的推导过程如下:
vS = (vx vy vz 1) = (vx*sx vy*sy vz*sz 1*1) = v '
OpenGL ES 模型视图之平移操作
对当前模型视图进行平移操作,在OpenGL ES 1.0中可以使用glTranslate*函数,而在2.0中需要自己设置平移矩阵。
如,分别使用tx,ty,tz表示在x,y,z轴上的移动距离,那么在1.0中可以这样平移模型视图:
glTranslatef(tx, ty, tz);
在2.0中你需要这么做:
float translation[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1 }; glMultiMatrixf(translation);
平移矩阵的推导过程如下:
vT = (vx vy vz 1) = (vx+tx vy+ty vz+tz 1*1) = v '
glRotate—— 使用一个旋转矩阵乘以当前矩阵
函数原型:
void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
void glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
函数参数:
angle 指定旋转角度,单位为度。
x, y, z 指定一个向量的 x, y, z 坐标
描述:
glRotate产生一个围绕vector(x,y,x),角度为angle的旋转操作。旋转矩阵乘以当前矩阵的积,将代替当前矩阵,当glMultMatrix以如下参数被调用时:
其中,c = cos(angle),s = sin(angle),并且||(x, y, z)|| = 1(如果不是,OpenGL ES会标准化它)。
如果矩阵模式设为GL_MODELVIEW 或 GL_PROJECTION,那么在glRotate后面绘制的所有对象都将被旋转。使用 glPushMatrix 或 glPopMatrix来保存或恢复缩放前的坐标系统。
注意:
旋转遵循右手规则,如果向量(x,y,z)点正对着用户的话,旋转是逆时针的。
OpenGL ES之glPushMatrix, glPopMatrix函数
glPushMatrix, glPopMatrix—— 压入和弹出矩阵栈
void glPushMatrix(void);
void glPopMatrix(void);
描述:
对于每一种矩阵模式都有一个矩阵栈。对于GL_MODELVIEW,栈的深度最少为16。对于GL_PROJECTION和GL_TEXTURE,栈的深度最少为2。任何模式的当前矩阵都是指该模式的矩阵栈顶的那个矩阵。
glPushMatrix 复制当前矩阵并将其加入栈中,此时它处于栈顶位置。
glPopMatrix 弹出当前矩阵栈,当前矩阵被弹出,之前处在其下的那个矩阵将变为栈顶。
默认的,每个栈都包含一个矩阵,唯一标识的矩阵。
向已经填满的栈压入矩阵或从仅有一个矩阵的栈中弹出矩阵都会引起错误。
注意:
每一个纹理单元都有自己的纹理矩阵栈,使用glActiveTexture选择想要的那个纹理矩阵栈。
glFrustum—— 使用一个透视矩阵乘以当前矩阵
函数原型:
void glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far);
void glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed near, GLfixed far);
函数参数:
left,right 指定左边和右边垂直切面的坐标
bottom,top 指定下边和上边水平切面的坐标
near,far 指定近端和远端深度切面的距离
描述:
glFrustum描述了一个产生透视投影的透视矩阵。这个矩阵乘以当前矩阵的积,将代替当前矩阵,当glMultMatrix以如下参数被调用时:
通常,矩阵模式是GL_PROJECTION, 假设眼睛的位置在(0,0,0), (left, bottom, -near) 和 (right, top, -near)指明了近切面的点,并且被映射到窗口的左下角和右上角。-far指明了远切面的位置。near 和 far都必须是正数
使用 glPushMatrix 或 glPopMatrix来保存或恢复缩放前的坐标系统。
注意:
深度缓冲区的精度受到指定的near和far值的影响。far和near的比例越大,区分临近表面的有效深度缓冲区就越少。如果,
那么,将有大概位的深度缓冲区精度被丢失。因为,当near接近0的时候,r就接近于无穷,所以near一定不要设置为0.
错误:
GL_INVALID_VALUE 如果near和far不为整数,left等于right,top等于bottom,near等于far,那么将产生GL_INVALID_VALUE错误。
OpenGL ES之glOrtho函数
glOrtho—— 使用一个正交矩阵乘以当前矩阵
函数原型:
void glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far);
void glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed near, GLfixed far);
函数参数:
left,right 指定左边和右边垂直切面的坐标
bottom,top 指定下边和上边水平切面的坐标
near,far 指定近端和远端深度切面的距离,如果面在观察者后面,这两个值都要为负数。
描述:
glOrtho描述了一个产生平行投影的变换。这个矩阵乘以当前矩阵的积,将代替当前矩阵,当glMultMatrix以如下参数被调用时:
通常,矩阵模式是GL_PROJECTION, 假设眼睛的位置在(0,0,0), (left, bottom, -near) 和 (right, top, -near)指明了近切面的点,并且被映射到窗口的左下角和右上角。-far指明了远切面的位置。near 和 far可以是正数或负数。
使用 glPushMatrix 或 glPopMatrix来保存或恢复缩放前的坐标系统。
错误:
GL_INVALID_VALUE 如果left等于right,top等于bottom,near等于far,那么将产生GL_INVALID_VALUE错误。
OpenGL ES之glOrtho和glFrustum的区别
glOrtho和glFrustum的参数是一样的,但是glFrustum的near和far参数都必须是整数并且near不能为0,而glOrtho的near和far参数没有这个限制。二者的left, right, bottom, top表达的意思是相同的,都是指某一切面的坐标位置。
glOrtho表达的是正交矩阵,效果是2D的,就像你正对着一个立方体的某一个面看,所以它没有“近大远小”的效果。
glFrustum表达的是透视矩阵,效果是3D的,它是一个平头锥体,具有“近大远小”的效果。
所以,如果你要绘制2D效果,可以使用glOrtho,要绘制3D效果,使用glFrustum。由于计算3D需要复杂的计算,所以要开启深度测试。
函数原型:
当你调用这个函数的时候,Quartz创建一个位图绘制环境,也就是位图上下文。当你向上下文中绘制信息时,Quartz把你要绘制的信息作为位图数据绘制到指定的内存块。一个新的位图上下文的像素格式由三个参数决定:每个组件的位数,颜色空间,alpha选项。alpha值决定了绘制像素的透明性。
CGContextRef CGBitmapContextCreate (
void *data, 指向要渲染的绘制内存的地址。这个内存块的大小至少是(bytesPerRow*height)个字节
size_t width, bitmap的宽度,单位为像素
size_t height, bitmap的高度,单位为像素
size_t bitsPerComponent, 内存中像素的每个组件的位数.例如,对于32位像素格式和RGB 颜色空间,你应该将这个值设为8
size_t bytesPerRow, bitmap的每一行在内存所占的比特数
CGColorSpaceRef colorspace, bitmap上下文使用的颜色空间。
CGBitmapInfo bitmapInfo 指定bitmap是否包含alpha通道,像素中alpha通道的相对位置,像素组件是整形还是浮点型等信息的字符串。
);
OpenGL ES之glTexImage2D函数
glTexImage2D—— 指定一个二维的纹理图片
纹理映射一个指定的纹理图像的每一部分到相应的图元中。调用带GL_TEXTURE_2D参数的glEnable和glDisable函数来启用和禁止二维材质贴图。默认,二维材质贴图是禁用的。
调用glTexImage2D来定义材质图片
函数原型:
void glTexImage2D( GLenum target, 指定目标纹理,这个值必须是GL_TEXTURE_2D GLint level, 执行细节级别。0是最基本的图像级别,你表示第N级贴图细化级别。 GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels );
函数参数:
target 指定目标纹理,这个值必须是GL_TEXTURE_2D。
level 执行细节级别。0是最基本的图像级别,你表示第N级贴图细化级别。
internalformat 指定纹理中的颜色组件,这个取值和后面的format取值必须相同。可选的值有
GL_ALPHA,
GL_RGB,
GL_RGBA,
GL_LUMINANCE,
GL_LUMINANCE_ALPHA 等几种。width 指定纹理图像的宽度,必须是2的n次方。纹理图片至少要支持64个材质元素的宽度
height 指定纹理图像的高度,必须是2的m次方。纹理图片至少要支持64个材质元素的高度
border 指定边框的宽度。必须为0。
format 像素数据的颜色格式,必须和internalformatt取值必须相同。可选的值有
GL_ALPHA,
type 指定像素数据的数据类型。可以使用的值有
GL_RGB,
GL_RGBA,
GL_LUMINANCE,
GL_LUMINANCE_ALPHA 等几种。
GL_UNSIGNED_BYTE,
GL_UNSIGNED_SHORT_5_6_5,
GL_UNSIGNED_SHORT_4_4_4_4,
GL_UNSIGNED_SHORT_5_5_5_1pixels 指定内存中指向图像数据的指针
glShadeModel—— 选择flat或smooth着色
函数原型:
void glShadeModel(GLenum mode)
函数参数:
mode 指明使用哪种着色技术,可以取值GL_FLAT和GL_SMOOTH。默认取值是GL_SMOOTH(颜色渐变)。
描述:
原文翻译太复杂,我在这里总结一下:在使用顶点数据绘制几何图形时,如果为每个顶点指定了顶点颜色,此时若使用GL_SMOOTH,每个顶点使用对应的顶点颜色来着色,而顶点之间的片元颜色则使用差值的方式来计算获得,结果就是渐变色;而若使用GL_FLAT,假设几何图形由n个三角形构成,则只会使用顶点颜色数组中最后n个颜色进行着色。
GL_SMOOTH着色模式
GL_FLAT着色模式