Libgdx中如何绘制带透明度的3D模型相关实现代码 2种方案
2017-12-01 18:11
387 查看
问题?如何解决在绘制带透明度的3D模型时候,深度和透明度混合之间的矛盾问题。
第一种方法:
采取透明度测试,在glsl里面,先开启透明度测试只通过不透明的部分,然后再绘制绘制透明的部分即可。
public void draw (Batch batch, float parentAlpha) {
batch.flush();
batch.end();
Gdx.gl.glDisable(GL20.GL_BLEND);
Gdx.gl.glDepthMask(true);
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
matrix4.idt().set(getStage().getCamera().combined);
if (isEnableRatate) {
rotateAxisAngle(matrix4, xToAngle(deltaX), xToAngle(deltaY), 0);
} else {
deltaX = 0;
deltaY = 0;
}
shader.begin();
shader.setUniformMatrix("u_projTrans", matrix4);
shader.setUniformi("alphatest", 1);//glsl实现开启透明度测试
this.texture.bind();
glCircle.mesh.render(this.shader, GL20.GL_TRIANGLE_STRIP,0,glCircle.getIndexCount());
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glDepthMask(false);
shader.setUniformMatrix("u_projTrans", matrix4);
shader.setUniformi("alphatest", -1);
this.texture.bind();
glCircle.mesh.render(this.shader, GL20.GL_TRIANGLE_STRIP,0,glCircle.getIndexCount());
batch.begin();
}
第二种方式(我采用的第二种实现):
采取绘制2次做法,需要绘制2次因为如果图片不带透明度就比较吃亏了。
第一次绘制:开启前面裁剪模式,绘制后面。
第二次绘制:开启背面裁剪模式,绘制前面即可。
代码如下:
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
shader.begin();
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glDepthMask(false);//禁用深度缓冲
Gdx.gl.glEnable(GL20.GL_CULL_FACE);
Gdx.gl.glCullFace(GL20.GL_FRONT);
shader.setUniformMatrix("u_projTrans", matrix4);
shader.setUniformi("alphatest", 0);
shader.setUniformf("t_colorAlpha", parentAlpha);//实现透明度渐变
shader.setUniformi("preAlpha", -1);//不需要预乘alpha
if(texturebg==null) {
shader.setUniformi("hasbg", -1);
textureRegion.getTexture().bind();
}else{
shader.setUniformi("hasbg", 1);
shader.setUniformf("bgAlpha", radio);
//注意该纹理的绑定顺序,有点奇葩,必须前后对调,感觉很不爽
//绑定图标层
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0);
textureRegion.getTexture().bind(1);
shader.setUniformi("u_texture", 1); //passing first texture!!!
//绑定背景
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE1);
texturebg.getRegion().getTexture().bind(0);
shader.setUniformi("u_texture2", 0); //passing first texture!!!
}
this.mesh.render(this.shader, GL20.GL_TRIANGLE_STRIP, 0, spriteVertices.length / 6);
Gdx.gl.glCullFace(GL20.GL_BACK);
shader.setUniformMatrix("u_projTrans", matrix4);
shader.setUniformf("t_colorAlpha", parentAlpha);//实现透明度渐变
shader.setUniformi("preAlpha", -1);//不需要预乘alpha
if(texturebg==null) {
shader.setUniformi("hasbg", -1);
textureRegion.getTexture().bind();
}else{
shader.setUniformi("hasbg", 1);
shader.setUniformf("bgAlpha", radio);
//注意该纹理的绑定顺序,有点奇葩,必须前后对调,感觉很不爽
//绑定图标层
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0);
textureRegion.getTexture().bind(1);
shader.setUniformi("u_texture", 1); //passing first texture!!!
//绑定背景
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE1);
texturebg.getRegion().getTexture().bind(0);
shader.setUniformi("u_texture2", 0); //passing first texture!!!
}
this.mesh.render(this.shader, GL20.GL_TRIANGLE_STRIP, 0, spriteVertices.length / 6);
shader.end();
Gdx.gl.glDisable(GL20.GL_CULL_FACE);
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl20.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
Gdx.gl.glDepthMask(false);
第一种方法:
采取透明度测试,在glsl里面,先开启透明度测试只通过不透明的部分,然后再绘制绘制透明的部分即可。
public void draw (Batch batch, float parentAlpha) {
batch.flush();
batch.end();
Gdx.gl.glDisable(GL20.GL_BLEND);
Gdx.gl.glDepthMask(true);
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
matrix4.idt().set(getStage().getCamera().combined);
if (isEnableRatate) {
rotateAxisAngle(matrix4, xToAngle(deltaX), xToAngle(deltaY), 0);
} else {
deltaX = 0;
deltaY = 0;
}
shader.begin();
shader.setUniformMatrix("u_projTrans", matrix4);
shader.setUniformi("alphatest", 1);//glsl实现开启透明度测试
this.texture.bind();
glCircle.mesh.render(this.shader, GL20.GL_TRIANGLE_STRIP,0,glCircle.getIndexCount());
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glDepthMask(false);
shader.setUniformMatrix("u_projTrans", matrix4);
shader.setUniformi("alphatest", -1);
this.texture.bind();
glCircle.mesh.render(this.shader, GL20.GL_TRIANGLE_STRIP,0,glCircle.getIndexCount());
batch.begin();
}
第二种方式(我采用的第二种实现):
采取绘制2次做法,需要绘制2次因为如果图片不带透明度就比较吃亏了。
第一次绘制:开启前面裁剪模式,绘制后面。
第二次绘制:开启背面裁剪模式,绘制前面即可。
代码如下:
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
shader.begin();
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glDepthMask(false);//禁用深度缓冲
Gdx.gl.glEnable(GL20.GL_CULL_FACE);
Gdx.gl.glCullFace(GL20.GL_FRONT);
shader.setUniformMatrix("u_projTrans", matrix4);
shader.setUniformi("alphatest", 0);
shader.setUniformf("t_colorAlpha", parentAlpha);//实现透明度渐变
shader.setUniformi("preAlpha", -1);//不需要预乘alpha
if(texturebg==null) {
shader.setUniformi("hasbg", -1);
textureRegion.getTexture().bind();
}else{
shader.setUniformi("hasbg", 1);
shader.setUniformf("bgAlpha", radio);
//注意该纹理的绑定顺序,有点奇葩,必须前后对调,感觉很不爽
//绑定图标层
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0);
textureRegion.getTexture().bind(1);
shader.setUniformi("u_texture", 1); //passing first texture!!!
//绑定背景
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE1);
texturebg.getRegion().getTexture().bind(0);
shader.setUniformi("u_texture2", 0); //passing first texture!!!
}
this.mesh.render(this.shader, GL20.GL_TRIANGLE_STRIP, 0, spriteVertices.length / 6);
Gdx.gl.glCullFace(GL20.GL_BACK);
shader.setUniformMatrix("u_projTrans", matrix4);
shader.setUniformf("t_colorAlpha", parentAlpha);//实现透明度渐变
shader.setUniformi("preAlpha", -1);//不需要预乘alpha
if(texturebg==null) {
shader.setUniformi("hasbg", -1);
textureRegion.getTexture().bind();
}else{
shader.setUniformi("hasbg", 1);
shader.setUniformf("bgAlpha", radio);
//注意该纹理的绑定顺序,有点奇葩,必须前后对调,感觉很不爽
//绑定图标层
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0);
textureRegion.getTexture().bind(1);
shader.setUniformi("u_texture", 1); //passing first texture!!!
//绑定背景
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE1);
texturebg.getRegion().getTexture().bind(0);
shader.setUniformi("u_texture2", 0); //passing first texture!!!
}
this.mesh.render(this.shader, GL20.GL_TRIANGLE_STRIP, 0, spriteVertices.length / 6);
shader.end();
Gdx.gl.glDisable(GL20.GL_CULL_FACE);
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl20.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
Gdx.gl.glDepthMask(false);
相关文章推荐
- Three.js实现绘制字体模型示例代码
- Unity中如何用代码实现横版游戏路径的绘制
- TensorFlow使用C++加载使用训练好的模型,.cc文件代码实现的相关类及方法总结
- Unity中修改3D模型的透明度,实现3D模型渐变出现的效果(附源码)
- 如何实现3D效果(绘制长方体/立方体)
- OpenGL实现3D模型自由旋转——之代码解析
- three.js实现3D模型展示的示例代码
- 【HTML5】3D模型--百行代码实现旋转立体魔方
- SkylineGlobe 6.5 如何实现简单多边形的动态绘制 C#示例代码
- python中Matplotlib实现绘制3D图的示例代码
- OpenGL实现3D模型自由旋转——之代码解析
- 如何用Javascript代码实现浏览器菜单命令
- 【原创】如何去掉有源代码管理的项目中的相关信息
- 『原创』DX图形显示基本流程(基于MESH静态模型绘制----托管代码)
- 市面上所有号称"虚拟机","防火墙"的实时监控杀毒软件无一不是使用的IFSHOOK技术.但是同时也有一些朋友不断写MAIL给我打听如何实现读写的监控.下面给出用VTOOLSD写的代码.也就是所有实时杀毒软件的奥秘.同时,很多拦截文件操作的软件,例如对目录加
- 《Asp.Net Forums2.0深入分析》之 Asp.Net Forums是如何实现代码分离和换皮肤的
- 如何让.Net控件在设计时InitializeComponent()中不生成相关代码
- 【导读】本文介绍如何利用带进度条的ASP无组件实现断点续传下载,给出详细代码
- 如何用Javascript代码实现浏览器菜单命令
- J2ME 3D学习笔记——实现简单的界面(附代码)