目前,我正在研究具有透明性的动态纹理(即在运行时创建)。我当前对位图的创建如下所示:
b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
final Canvas c = new Canvas(b);
c.drawColor(0, PorterDuff.Mode.CLEAR);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
c.save();
c.translate(paddingLeft, paddingTop);
view.draw(c);
c.restore();
由于我正在创建一个视图,因此需要将其用作位图,然后将其用作平面的纹理。这工作正常,我正在接收位图。如果我将其添加到ImageView并将其放在布局的顶部,就我所知,它也是透明的。
我在
getHolder().setFormat(PixelFormat.TRANSLUCENT);
和GLSurfaceView
中都使用了setEGLConfigChooser(8,8,8,8,16,0);
。纹理的生成如下所示:
GLES20.glGenTextures(1, textureHandle, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
// GLES20 tex parameters here as well... (min/mag filter)
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bmp, 0);
在片段着色器中,出于测试目的,我只是简单地应用
gl_FragColor = texture2D(u_Texture, v_TexCoordinate);
因此,没有灯光,仅采用纹理的颜色。
但是它不是透明的,它有黑色边框-因为我将位图创建为2的幂。这意味着,如果我的视图的尺寸为300x300,纹理将为512x512,带有透明边框-在OpenGL ES 2.0中绘制为黑色。
在渲染器中,我启用了如下混合:
GLES20.glClearColor(0, 0, 0, 0);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glEnable(GLES20.GL_CULL_FACE);
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
GLES20.glCullFace(GLES20.GL_BACK);
GLES20.glDepthFunc(GLES20.GL_LEQUAL);
但是我不确定这是否是正确的搅拌器功能。
因此最后,透明度被忽略,显示为黑色。
任何想法,我可能会丢失/做错了什么?非常感谢你。
最佳答案
如果我了解您在做什么,那听起来好像不是纹理。这是您添加的填充以四舍五入到不透明的2的幂。
最初我以为您没有清除整个位图,但是您使用的c.DrawColor()
调用应该解决这一问题。可以肯定的是,您可以在创建位图后立即尝试以下操作,并查看它是否有所不同:
b.eraseColor(Color.TRANSPARENT);
我可以想到的另一种方法是更干净,更好:在渲染期间,请勿使用添加的部分纹理来填充尺寸。您可以通过调整纹理坐标以仅对包含视图的纹理部分进行采样来做到这一点。使用示例中的尺寸(将300x300视图绘制为512x512纹理),用于渲染的纹理坐标范围应在各个方向上分别为
0.0f
至300.0f / 512.0f
,而不是通常的0.0f
至1.0f
。您使用的混合功能看起来不错。