Android OpenGL ES 2.0的透明度
我目前正在使用OpenGLES2.0为Android开发一款游戏。我几乎所有的东西都使用纹理和顶点颜色,但是当我在纹理中使用透明度时,透明部分会被点染。以下是它的屏幕截图: 图中所示的圆铃(蓝色圆圈)顶部有三层平面,眼睛、嘴巴和牙齿。所有的图层都有相同的尺寸和透明度,而且我添加的图层越多,点状效果就越差。这是渲染器的onCreate方法:Android OpenGL ES 2.0的透明度,android,opengl-es-2.0,Android,Opengl Es 2.0,我目前正在使用OpenGLES2.0为Android开发一款游戏。我几乎所有的东西都使用纹理和顶点颜色,但是当我在纹理中使用透明度时,透明部分会被点染。以下是它的屏幕截图: 图中所示的圆铃(蓝色圆圈)顶部有三层平面,眼睛、嘴巴和牙齿。所有的图层都有相同的尺寸和透明度,而且我添加的图层越多,点状效果就越差。这是渲染器的onCreate方法: mMVPMatrix = new float [16]; mViewMatrix = new float [16]; mProject
mMVPMatrix = new float [16];
mViewMatrix = new float [16];
mProjectionMatrix = new float [16];
mModelMatrix = new float [16];
Matrix.setLookAtM(mViewMatrix, 0, 0.0f, 0.0f, mZoom, 0.0f, 0.0f, -0.1f, 0.0f, 1.0f, 0.0f);
Matrix.setIdentityM(mModelMatrix, 0);
mTexturePointer = new int [32];
loadTextures();
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
mShaderPointer = loadProgram();
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
GLES20.glUseProgram(mShaderPointer);
mMVPMatrixPointer = GLES20.glGetUniformLocation(mShaderPointer, "uMVPMatrix");
mPositionPointer = GLES20.glGetAttribLocation(mShaderPointer, "a_position");
mTexCoordPointer = GLES20.glGetAttribLocation(mShaderPointer, "a_texCoord");
mSamplerPointer = GLES20.glGetUniformLocation(mShaderPointer, "s_texture");
mColorPointer = GLES20.glGetAttribLocation(mShaderPointer, "a_color");
这是片段着色器:
"precision mediump float; \n"
+ "uniform sampler2D s_texture; \n"
+ " \n"
+ "varying vec4 v_color; \n"
+ "varying vec2 v_texCoord; \n"
+ " \n"
+ "void main() \n"
+ "{ \n"
+ " \n"
+ " vec4 final_color = vec4(texture2D(s_texture, v_texCoord).r * v_color.r, "
+ " texture2D(s_texture, v_texCoord).g * v_color.g, "
+ " texture2D(s_texture, v_texCoord).b * v_color.b, "
+ " texture2D(s_texture, v_texCoord).a + v_color.a);\n"
+ " \n"
+ " //Set the Fragments colour \n"
+ " gl_FragColor = final_color; \n"
+ "} \n";
和顶点着色器:
"attribute vec4 a_position; \n"
+ "uniform mat4 uMVPMatrix; \n"
+ " \n"
+ "attribute vec2 a_texCoord; \n"
+ "attribute vec4 a_color; \n"
+ " \n"
+ "varying vec4 v_color; \n"
+ "varying vec2 v_texCoord; \n"
+ " \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = uMVPMatrix * a_position; \n"
+ " v_texCoord = a_texCoord; \n"
+ " v_color = a_color; \n"
+ "} \n";
最后但并非最不重要的是绘制(这是每个对象的绘制方法):
loadTexture()方法:
我已经仔细研究过了。PNG不是问题所在。我尝试将顶点颜色alpha设置为-1,是的,纹理消失了,但圆点仍然存在。当我禁用混合时,所有透明度变为黑色,圆点消失。我不知道下一步该怎么做,当片段着色器输出alpha 0.0时,它仍然会出现虚线
任何关于尝试的反馈都将不胜感激。谢谢大家! 您的“loadTextures()”函数看起来像什么?这可能是glTexParameteri(…)问题,您可以在其中设置纹理的过滤。(插值可能不正确)这似乎是一个颜色深度问题。您应该将曲面和窗口设置为32位模式,看看这是否有帮助:
glview.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
及
既然窗口和曲面使用了相同数量的位,就不必抖动任何内容,但有时它可以提供更好的结果,因此您可以尝试为窗口和openGL启用该功能。尝试启用抖动(
GLES20.glEnable(GLES20.GL_dither)
)。@Jave现在尝试了,但没有改变。谢谢你的建议!但它看起来确实像某种颜色深度问题。您还可以尝试将窗口和曲面深度都设置为32位:glview.setEGLConfigChooser(8,8,8,16,0)代码>和getWindow().setFormat(PixelFormat.RGBA_8888)代码>(可能会在窗口和opengl中添加抖动)@Jave非常感谢!这就是问题所在。当窗口和曲面深度设置为32位且启用和不启用抖动时,该功能有效。你救了我一天:)很好:)如果你愿意的话,我可以把它作为一个答案发布?对不起,错过了那个方法。原来的帖子现在被编辑了。非常感谢。
public void loadTextures(){
Log.d("loadTextures()", "Loading textures");
Bitmap tBitmap = null;
// Tell OpenGL to generate textures.
GLES20.glGenTextures(32, mTexturePointer, 0);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inTempStorage = new byte [16 * 1024];
options.inScaled = false;
// TEXTURE 0
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexturePointer[0]);
// Scale up if the texture if smaller.
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
tBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ingame_boll_spritesheet_new_style, options);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, tBitmap, 0);
tBitmap.recycle();
// TEXTURE 1
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexturePointer[1]);
// Scale up if the texture if smaller.
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
tBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ingame_boll_mouth, options);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, tBitmap, 0);
tBitmap.recycle();
// And so on for all textures
Log.d("loadTextures()", "Loaded textures");
}
glview.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
getWindow().setFormat(PixelFormat.RGBA_8888);