OpenGL ES 设置透明度不能【双面透明】的问题解决办法

<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);

好吧,效果图就如大家看到的那样,大家可以自己测试!



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值