简述:
混合就是在绘制时,不是直接把新的颜色覆盖在原来旧的颜色上,而是将新的颜色与旧的颜色经过一定的运算,从而产生新的颜色。新的颜色称为源颜色,原来旧的颜色称为目标颜色。
OpenGL里面的操作,很多是基于对矩阵的操作的,比如位移,旋转,缩放。glMatrixMode ( ) 是用来指定哪一个矩阵是当前矩阵,而它的参数为GL_PROJECTION时是对投影矩阵操作;而GL_MODELVIEW是对模型视景矩阵操作;或者GL_TEXTURE是对纹理矩阵进行随后的操作。
1、glEnable / glDisable
开启 / 关闭服务器端GL功能。
void glEnable(GLenum cap); void glDisable(GLenum cap);
① 参数cap ,指明一个GL功能的标识符。glEnable / glDisable 用来开启 / 关闭各种功能。使用gllsEnabled 或glGet 来获取当前设置的GL功能。GL_DITHER和GL_MULTISAMPLE的初始值为GL_TURE,其他功能的初始值为GL_FALSE.② glEnable / glDisable 都只接受一个cap 参数。glEnable不能写在 glBegin 和 glEnd 两个函数之间。
③ cap 参数值如下:
cap 值 含义 GL_ALPHA_TEST alpha测试功能,参考glAlphaFunc函数 GL_BLEND 启用颜色混合功能,将片元颜色和颜色缓冲区的颜色进行混合,参考glBlendFunc。
例如实现半透明效果GL_COLOR_LOGIC_OP 将当前的逻辑操作应用于经过计算的片元颜色和颜色缓冲区值,参考glLogicOp
启用每一像素的色彩为位逻辑运算GL_CLIP_PLANE 剪切用户定义的剪裁面,参考glClipPlane GL_COLOR_MATERIAL 使用环境和漫反射材质来跟踪当前颜色
执行后,图形(材料)将根据光线的照耀进行反射GL_CULL_FACE 根据在窗口坐标中的弯曲来剔除多边形
根据函数glCullFace要求启用隐藏图形材料的面GL_DEPTH_TEST 进行深度比较和更新深度缓冲。注意,即使深度缓冲区存在并且表示深度缓冲区
的掩码也不为0,但是如果深度测试被禁止的话,也是不会更新深度缓冲区的。
参考glDepthFunc和glDepthRange
启用深度测试,根据坐标的远近自动隐藏被遮住的图形(材料)GL_DITHER 在写入颜色缓冲区之前抖动颜色组件。启用抖动。
GL_FOG 将一个雾(fog)颜色混合进一个贴图后的颜色,参考glFog
雾化效果,例如距离越远越模糊GL_LIGHT 使用光进行光照方程式计算,参考 glLightModel和 glLight GL_LIGHTING 使用当前光照计算顶点颜色。否则只是将当前的颜色和顶点简单的关联在一起,
参考glMaterial, glLightModel, 和glLight
启用灯源GL_LINE_SMOOTH 使用正确的过滤来绘制线,参考glLineWidth
执行后,过滤线段的锯齿GL_MULTISAMPLE 使用多个片元采样来计算最终的像素颜色,参考glSampleCoverage GL_NORMALIZE 在转换之后和光照之前将法线向量标准化成单位长度。通常效率要比
GL_RESCALE_NORMAL低,参考 glNormal 和 glNormalPointerGL_POINT_SMOOTH 使用合适的过滤器来绘制点,参考glPointSize
执行后,过滤线点锯齿GL_POINT_SPRITE_OES 激活点精灵。参考glPointSize和 glTexEnv GL_POLYGON_OFFSET_FILL 在深度对比之前,给多边形片元的深度值加上一个偏移量。参考glPolygonOffset GL_RESCALE_NORMAL 在转换之后和光照之前,通过一个由模型矩阵计算出来的因子来对法线向量
进行缩放。如果模型矩阵缩放空间保持一致,那么和存储转换后的法线为单
位长度的效果是一样的。这个功能通常要比GL_NORMALIZE的效率高。参
考glNormal和glNormalPointer。GL_SAMPLE_ALPHA_TO_COVERAGE 计算一个临时的覆盖值,该值的每一位都由相应的采样位置的alpha值决定。
临时覆盖值和片元覆盖值进行与操作GL_SAMPLE_ALPHA_TO_ONE 使用最大的可展现的alpha值来代替每一个采样alpha值 GL_SAMPLE_COVERAGE 片元覆盖值和临时覆盖值进行与操作。如果GL_SAMPLE_COVERAGE_INVERT
的值被设置为 GL_TRUE,那么将会反转覆盖值。参考glSampleCoverage。GL_SCISSOR_TEST 丢弃在剪切区域外的片元,参考glScissor GL_STENCIL_TEST 进行模板测试和模板缓冲区更新。参考glStencilFunc,glStencilMask,glStencilOp GL_TEXTURE_2D 对活动的材质单元进行二维贴图。参考glActiveTexture,
glTexImage2D,glCompressedTexImage2D, glCopyTexImage2D
2、glBlendFunc ( ) :颜色混合函数
① OpenGL 会把源颜色和目标颜色各自取出,并乘以一个系数(源颜色乘以的系数称为“源因子”,目标颜色乘以的系数称为“目标因子”),然后相加(也可以不相加,新颁布的OpenGL可以设置运算方式,包括加、减、取或者中最大/最小、逻辑运算等),这样就得到了新的颜色。
② 假设源颜色的四个分量(指红色、绿色、蓝色及alpha值)是(Rs,Gs,Bs,As),目标颜色的四个分量是(Rd,Gd,Bd,Ad),又设源因子为(Sr,Sg,Sb,Sa),目标因子为(Dr,Dg,Db,Da),则混合生成的新颜色可以表示为:(Rs*Sr+Rd*Dr , Gs*Sg+Gd*Dg , Bs*Sb+Bd*Db , As*Sa+Ad*Da)。如果颜色某一分量超过了1.0,则它会自动截取为1.0,不需要考虑越界的问题。
③ 源因子和目标因子是通过glBlendFunc函数来进行设置的。glBlendFunc 函数有两个参数,前者表示源因子,后者表示目标因子
void glBlendFunc(GLenum sfactor,GLenum dfactor);
因子 含义 GL_ZERO 表示使用0.0作为因子,实际上相当于不使用这种颜色参与混合运算 GL_ONE 表示使用1.0作为因子,实际上相当于完全的使用了这种颜色参与混合运算 GL_SRC_ALPHA 表示使用源颜色的alpha值来作为因子 GL_DST_ALPHA 表示使用目标颜色的alpha值来作为因子 GL_ONE_MINUS_SRC_ALPHA 表示用1.0减去源颜色的alpha值来作为因子 GL_ONE_MINUS_DST_ALPHA 表示用1.0减去目标颜色的alpha值来作为因子 GL_SRC_COLOR 把源颜色的四个分量分别作为因子的四个分量 GL_DST_COLOR 把目标颜色的四个分量分别作为因子的四个分量 GL_ONE_MINUS_SRC_COLOR GL_ONE_MINUS_DST_COLOR GL_CONST_COLOR 设定一种常数颜色,将其四个分量分别作为 因子的四个分量 GL_CONST_ALPHA GL_ONE_MINUS_CONST_COLOR GL_ONE_MINUS_CONST_ALPHA GL_SRC_ALPHA_SATURATE
④ 举例来说,如果设置了glBlendFunc (GL_ONE ,GL_ZERO) ; 则表示完全使用源颜色,而不使用目标颜色,因此画面效果和不使用混合效果的时候一致(效率可能会低一点点)。如果没有设置源因子和目标因子,则默认情况就是这样。如果设置了glBlendFunc ( GL_ZERO, GL_ONE ) ; 则表示完全不使用源颜色,因此无论你想画什么,最后都不会被画上去了。如果设置了glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA) ; 则表示源颜色乘以自身的alpha值,目标颜色乘以1.0减去源颜色的alpha值,因此,源颜色的alpha值越大,则产生的新颜色中源颜色所占的比例就越大,而目标颜色所占的比例减小,这是最常用的混合方式。如果设置了glBlendFunc ( GL_ONE , GL_ONE) ; 表示完全使用源颜色和目标颜色,最终的颜色实际上就是两种颜色的简单相加。
⑤ 注意:所谓源颜色和目标颜色,是跟绘制的顺序有关的。假如先绘制一个红色的物体,再在其上绘制绿色的物体,则绿色是源颜色,红色是目标颜色。
⑥ 要启用OpenGL的混合功能,需要调用glEnable ( GL_BLEND ),要关闭OpenGL的混合功能,需要调用glDisable ( GL_BLEND );注意,只有在RGBA模式下,才能使用混合功能,颜色索引模式下是无法使用混合功能的。
3、glMatrixMode ( ) :设置当前矩阵模式
① 该函数指定了哪一个矩阵是当前矩阵。
void glMatrixMode(GLenum mode)
mode值 说明 GL_MODDLVIEW 对模型视景矩阵堆栈应用随后的矩阵操作 GL_PROJECTION 对投影矩阵堆栈应用随后的矩阵操作 GL_TEXTURE 对纹理矩阵堆栈应用随后的矩阵操作
② glMatrixMode ( ) 与glLoadIdentity ( )一同使用。glLoadIdentity ( )重置当前指定的矩阵为单位矩阵。
③ 如果glMatrixMode ( ) 的参数是GL_PROJECTION,就是投影的意思,要对投影相关进行操作,即把物体投影到一个屏幕上,就像照相一样,把3维物体投影到2维的平面上,这样,接下来的语句可以是跟透视相关的函数,比如 glFrustum ( ) 或 gluPerspective ( )。
在操作投影矩阵以前,需要调用函数:
glMatrixMode(GL_PROJECTION);//将当前矩阵指定为投影矩阵
然后把矩阵设为单位矩阵:
然后调用透视投影函数glFrustum ( ) 或透视投影函数 gluPerspective ( ),它们生成的矩阵会与当前的矩阵相乘,生成透视的效果。glLoadIdentity();
投影函数glFrustum ( ) :将当前矩阵与glFrustum ( ) 指定的矩阵相乘实现透视投影变换
void glFrustum(GLdouble left, GLdouble Right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear, GLdouble zFar);
④如果glMatrixMode ( ) 的参数是GL_MODELVIEW,这个是对模型视景的操作,接下来的语句描绘一个以模型为基础的适应,这样来设置参数,接下来用到的就是像gluLookAt()这样的函数;
⑤ 若glMatrixMode ( ) 的参数是GL_TEXTURE,就是对纹理相关进行操作
⑥ 范例
如.要使用透视(3D),那么先要设置透视投影 glMatrixMode(GL_PROJECTION); //切换到投影矩阵. //...设置透视投影 设置完成后开始画图,需要切换到模型视图矩阵才能正确画图. glMatrixMode(GL_MODELVIEW); // 画一个物体A (看起来是3D的), // 如这时候需画一个2D效果的物体A,那么又需要透视投影 glMatrixMode(GL_PROJECTION); //切换到投影矩阵.. // ..设置正交投影 //..设置完成,切换回模型视图矩阵..... glMatrixMode(GL_MODELVIEW); // 再画一个物体A (看起来是2D的) // 如从头到尾都是画3D/2D, 只需初始化时设置一次. // 如果有交替,那么就需要glMatrixMode() 切换 // 因这样设置很烦人,所以又有glPushMatrix()保存当前矩阵
4、glLoadIdentity ( )
重置当前指定的矩阵为单位矩阵void glLoadIdentity(void)
调用glLoadIdentity ( ) 之后:
A. X坐标轴从左至右,Y坐标抽从下至上,Z坐标轴从里向外
B. OpenGL屏幕中心的坐标轴是X和Y轴上的0.0f 点
C. 中心左面的坐标值是负值,右面是正值
移向屏幕顶端是正值,移向屏幕底端是负值
移入屏幕深处是负值,移出屏幕则是正值