我使用纹理通过OpenGL绘制位图。
TextureId的生成方式如下:
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureIdForDrawingBitMap);
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);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
下面我用这个代码绘制框架:
//Enable blend for display a RGBA bitmap
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
GLES20.glUseProgram(ShaderHelper.programTexture);
GLES20.glEnableVertexAttribArray(ShaderHelper.a_Position_Texture);
GLES20.glEnableVertexAttribArray(ShaderHelper.a_texCoord_Texture);
GLES20.glVertexAttribPointer(ShaderHelper.a_Position_Texture, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);
GLES20.glVertexAttribPointer(ShaderHelper.a_texCoord_Texture, 2, GLES20.GL_FLOAT, false, 0, uvBuffer);
GLES20.glUniform1f(ShaderHelper.alphaFactor_Image, alphaFactor);
GLES20.glUniformMatrix4fv(ShaderHelper.u_MVPMatrix_Texture, 1, false, mPVMatrix, 0);
GLES20.glUniform1i(ShaderHelper.u_texture_Texture, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureIdForDrawingBitMap);
//Upload bitmap to texture
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, mBitmap, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, indicesBuffer);
GLES20.glDisableVertexAttribArray(ShaderHelper.a_Position_Texture);
GLES20.glDisableVertexAttribArray(ShaderHelper.a_texCoord_Texture);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
我只需要在背景上绘制一个位图(之前绘制过)。叠加位图具有RGBA格式。
当位图只包含alpha等于0或255的颜色时,上面的代码非常有效。(如果alpha == 0,则像素是透明的,alpha == 1,像素是不透明的。)
但是,当alpha等于100(例如)时,像素显示不正确。如果颜色的十六进制值为0xAAFFFFFF,则显示的结果似乎为0xAA000000。
我想也许blendFunction不仅可以混合alpha chanel,还可以混合RGB chanel(基于alpha chanel的值)。
我可以做些什么来解决这个问题?我只想在OpenGL上绘制我的叠加位图,就像我以前使用Paint和Canvas一样。
===========================更新解决方案================== ==
我尝试使用
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
它适用于我的情况。它精确地绘制叠加纹理,无论alpha等于0.0,1.0还是介于这些之间。唯一值得注意的是当我想要从Fragment Shader更改alpha通道时,结果颜色是意外的。在这种情况下,我使用了:
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
它并没有完全解决问题,但对我来说没问题。
答案 0 :(得分:1)
我认为也许blendFunction不仅可以混合alpha chanel,还可以混合RGB chanel(基于alpha chanel的值)
正确,混合会影响所有四个频道。如果您只混合了Alpha通道,那么您将无法获得所需的效果(文本精灵的颜色值将被写为所有像素的白色,而不管字体字形实际位于何处)。
我可以做些什么来解决这个问题?
如果你想要完全透明或完全不透明,那么显而易见的答案只能传递0.0(透明)或(1.0)不透明的alpha值,这样可以正常工作(正如你已经注意到的)。
如果确实需要,您可以在着色器中将部分值舍入为0.0或1.0。
可以通过扩展名为颜色和Alpha通道设置不同的混合:
https://www.khronos.org/registry/gles/extensions/OES/OES_blend_equation_separate.txt
...但我实际上并不认为这就是你想要的。
答案 1 :(得分:1)
你试过了吗?
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_COLOR);