<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">今天用OpenGL ES 绘制一个立方体,在立方体内部打上小孔,也就是在内部画上圆柱体</span>
立方体的面和圆柱体都是有颜色的,所以在内部的圆柱体就不能被看到,只能设置立方体透明。
效果图:
放大图:
之前的代码实现是半透明的,从一侧能看到另一侧,另一侧就不能看透。
在public void onSurfaceCreated(GL10 gl, EGLConfig config)中的代码如下:
<span style="white-space:pre"> </span><span style="font-size:18px;">// 告诉系统对透视进行修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
// 设置背景为白色
float[] rgba = ColorUtil.getColorRgba("#FFADADAD");
gl.glClearColor(rgba[0], rgba[1], rgba[2], rgba[3]);
// gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
// 启用混合模式
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
// 设置透明显示
gl.glEnable(GL10.GL_ALPHA_TEST);
gl.glAlphaFunc(GL10.GL_GREATER, 0.2f);
// 关闭裁剪
gl.glDisable(GL10.GL_CULL_FACE);
gl.glEnable(GL10.GL_CCW);
// 启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
// 启用深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);</span>
关于透明度的设置,参考了别人的文章:
原文地址:http://blog.chinaunix.net/uid-24448954-id-3059568.html
关于透明,OpenGL/ES 中可以通过 blend (混色) 来简单实现,混色的基本原理就是把要绘制的物体的颜色与屏幕上已经绘制好的颜色以一定比例来混合,最后的颜色看上去就像半透明一样。
要使用混合先要通过 glEnable 函数来启用
1
|
glEnable(GL10.GL_BLEND);
|
然后通过 glBlendFunc 来设置下要使用的混合方法
1
|
glBlendFunc(sfactor, dfactor);
|
sfactor 及 dfactor 分别代表源和目标颜色在混合时所占比重的枚举常量。其中 sfactor 可取值包括:GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA_SATURATE ; 而 dfactor 可取值包括:GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA。
glBlendFunc(GL_ONE, GL_ONE); 即源与目标颜色的RGBA分别相加。
glBlendFunc(GL_ONE, GL_ZERO); 即只取源颜色,这也是默认值。
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 是比较典型的半透明效果,如果源色 alpha 为0,则取目标色,如果源色alpha为1,则取源色,否则视源色的alpha大小各取一部分。源色的alpha越大,则源色取的越多,最终结果源色的表现更强;源色的alpha越小,则目标色“透过”的越多。
此外在一般的渲染过程中,都会把有半透明效果的渲染放到后边,先把不透明的部分在深度测试启用的情况下渲染完, 再关闭深度测试写入(glDepthMask(false)),并渲染半透明的部分。这样就不会出现由于半透明且离镜头近的面被先渲染时污染深度缓冲了。
于是,我觉得找到了方式,把代码修改如下,成功是实现双面透明效果:
<span style="white-space:pre"> </span>// 告诉系统对透视进行修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
// 设置背景为白色
float[] rgba = ColorUtil.getColorRgba("#FFADADAD");
gl.glClearColor(rgba[0], rgba[1], rgba[2], rgba[3]);
// gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
<span style="color:#ff0000;"><strong>if (isCylinder) {
// 关闭深度测试
gl.glDisable(GL10.GL_DEPTH_TEST);
//启用混合模式
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
// 设置透明显示
gl.glEnable(GL10.GL_ALPHA_TEST);
gl.glAlphaFunc(GL10.GL_GREATER, 0.2f);
} else {
// 启用深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
}</strong></span>
// 关闭裁剪
gl.glDisable(GL10.GL_CULL_FACE);
gl.glEnable(GL10.GL_CCW);
// 启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
好吧,效果图就如大家看到的那样,大家可以自己测试!