深入了解OpenGL
深入了解 OpenGL [html] view plaincopy大家好。这一讲,我们讲介绍 OpenGL 的颜色混合模式。其实颜色混合用到的场合很多, 比如多张图片的合成,动画游戏中的一些画面特效等都可以 通过颜色混合进行实现。最常用的混合方式就是实现物体与 背景的半透明效果。另外,在制作 2D 游戏时颜色混合可以 用来通过制作目标物体的蒙板实现移动。通过蒙板来消除旧 位置的物体对象可以不必重绘当前整帧内容,而仅仅是发生 变化的那些物体。为了各位从事 iPhone 开发的考虑。后面 的代码例子对 OpenGL API 的使用都会用 OpenGL2.1 与 OpenGL ES1.1 相互兼容的接口。 首先介绍一下 OpenGL 对 源对象和目标对象进行颜色混合的实现。这里,源对象是指 你将要绘制的对象;目标对象是指已在帧缓存中的颜色。比 如调用 glClearGL_COLOR_BUFFER_BIT;后留在帧缓存 中的颜色。在进行计算时,源和目标的混合都是在绘制源对 象时进行计算的,在绘制对象以外的帧缓存像素不会受任何 影响。为了方便颜色混合,我们往往采用 RGBA 这种颜色模 式。其中 RGB 表示色彩分量,而 A 就是混合因子(blend factor) 。A,我们在图形、图像处理中常常表示为 alpha, 它在图像处理中常用作为透明系数。我们指定了源和目标的 混合因子后, OpenGL会对绘制对象的最终颜色做如下计算 设源对象的某个顶点的颜色为Rs, Gs, Bs, As目 的对象对应此源对象顶点的颜色为Rd, Gd, Bd, Ad 源混合因子为 Sr, Sg, Sb, Sa目的混合因子为 Dr, Dg, Db, Da那么,该顶点最终目标颜色为Rs * Sr opRd * Dr,Gs * SgopGd * Dg,Bs * SbopBd * Db,As * SaopAd * Da 其中,op可以是加法(+) ,减法(-) , 逆向减法, 最小值, 最大值或按位逻辑操作, 并且其优先级小于乘法 (*) 。 下面,我们介绍相关的OpenGL 接口。首先是开启混合,使 用 glEnableGL_BLEND;即可。然后我们使用 glBlendEquation来指定混合操作,参数可以是 GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX。 但这里要注意的是,OpenGL ES1.1 没有 glBlendEquation 接口,因此只能做加法操作。glBlendFunc接口用于指定源 混合因子与目标混合因子。参数请参考红宝石书中文版的第 140 页,表 6-1。下面给出示例代码[plain] view plaincopy// //MyView.m//OpenGLTest////Created by Zenny Chen on 4/25/10.//Copyright 2010 GreenGames Studio. All rights reserved.//P44 import “MyView.h“include OpenGL/OpenGL.h include math.himplementation MyView- idinitWithFrameNSRectframe {self [super initWithFrameframe];if self {// Initialization code here.}return self;}// Destination a rectanglestatic c*****t struct VertexInfo {GLfloat vertices[3];}vertexList[] {{-0.5f, 0.5f, -1.0f},{-0.5f, -0.5f, -1.0f},{0.5f, 0.5f, -1.0f}, {0.5f, -0.5f, -1.0f}};- voidprepareOpenGL {glEnableGL_CULL_FACE; glEnableGL_BLEND; glEnableClientStateGL_VERTEX_ARRAY; glVertexPointer3, GL_FLOAT, 0, vertexList; glFrontFaceGL_CCW;glCullFaceGL_BACK; glShadeModelGL_SMOOTH;// Set Background colorframe buffer color glClearColor1.0, 0.0, 0.0, 1.0;glViewport0, 0, 320, 320; glMatrixModeGL_PROJECTION;glLoadIdentity; glOrtho-1.0, 1.0, -1.0, 1.0, 1.0, 5.0; glMatrixModeGL_MODELVIEW;glLoadIdentity; // destination colorglColor4f1.0f, 1.0f, 1.0f, 0.3f; glBlendEquationGL_FUNC_ADD; glBlendFuncGL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA;}- voiddrawRectNSRectdirtyRect {// Drawing code here. glClearGL_COLOR_BUFFER_BIT; glDrawArraysGL_TRIANGLE_STRIP, 0, 4; gl;}end上述代码第 67 行的 glBlendFuncGL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA;用于指定 源混合因子As, As, As, As,这里是0.3, 0.3, 0.3, 0.3 目标混合因子则是 1, 1, 1, 1 - As, As, As, As, 结果是0.7, 0.7, 0.7, 0.7。 这里我们能够看到,为目标和源指定混合因子可以是源、目 标的任一颜色分量或 alpha 因子,或是[0, 1]范围内的补。 对于上述代码,我们可以用等价的方式实现。 已知,目的像素颜色值为1.0, 0.0, 0.0, 1.0;源像素颜色 值为1.0f, 1.0f, 1.0f, 0.3f。 目的混合因子为 0.7, 0.7, 0.7, 0.7; 源混合因子为 0.3, 0.3, 0.3, 0.3 OK。 我们可以直接把最终目标像素颜色值给算出来1.0 * 0.3 1.0 * 0.7,1.0 * 0.3 0.0 * 0.7,1.0 * 0.3 0.0 * 0.7,0.3 * 0.3 1.0 * 0.7 1.0,0.3,0.3,0.79。 因此,我们可以将 67 行的 glBlendFuncGL