glCallList(num2+10);
glPopMatrix();
3.3反射效果的实现
创建镜面反射显示效果,使用蒙板缓存技术。首先,需要先把各个缓存清空,包括蒙板缓存。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
接着,需要设置作为反射面的对象。在这里,把序号为1的显示列表对象floor作为发射平面。因为,反射生成的影像都绘制在反射面上,不需要深度检测。另外,反射面只是作为蒙板的参考,不需要显示,所以设置了颜色掩码,把参数设为GL_FALSE,这样就不会在屏幕上绘制任何东西。
glDisable(GL_DEPTH_TEST); //关闭深度检测
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); //设置颜色掩码
接着,启用蒙板测试,这样就可以修改蒙板缓存中的值了。蒙板函数用于确定一个颜色片段是应该丢弃还是保留(被绘制)。蒙板缓存区中的值与参考值进行比较,比较标准是glStencilFunc所指定的比较函数。参考值和蒙板缓存区的值都可以与掩码进行为AND操作。蒙板测试的结果还导致蒙板缓存区根据glStencilOp函数所指定的行为进行修改。
glEnable(GL_STENCIL_TEST); //启用蒙板测试
//用glStencilFunc函数所指定的参考值替换蒙板参数值
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 1, 0xffffffff); //总是通过蒙板测试
glCallList(1); //floor
//恢复opengl的状态
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); //允许绘制
glEnable(GL_DEPTH_TEST); //允许深度检测
glStencilFunc(GL_EQUAL, 1, 0xffffffff); //当绘制时,不改变蒙板缓存区的值
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); //保持当前的蒙板缓存区值
启用了蒙板缓存,只能在蒙板中值为1的地方绘制,反射的实质就是在反射屏幕的对应位置再绘制一个物体,并把它放置在反射平面中,而这个物体的的Y向正好是反的:
glScalef(1.0, -1.0, 1.0);
由于在蒙板缓存上绘制的对象要与实际显示的floor融合在一起,所以需要把OpenGL的融合打开,并设置相应的融合系数。
|