OpenGL ES 2.0渲染到具有透明背景的纹理

时间:2014-09-02 13:43:43

标签: android opengl-es-2.0 render-to-texture

我想创建一个可以放在任何东西上的交互式2D效果。因此,我想采取一种大多数透明效果,将其渲染为纹理,并将其放在任何我想要的地方,只需将其放在正方形上即可。

我遇到的问题是我无法摆脱背景颜色。当我将效果放在一个物体上时,效果的背景颜色会阻挡我想要效果的物体。

这是我的代码。谁能告诉我我错过了什么?

图:

GLES20.glClearColor(0.6f, 0.34f, 0.14f, 0.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);

ball.draw();  //This is the object a simple square draw with 2 triangles
particleSystem.renderToTexture(); //effect rendering to texture and drawing it

渲染到纹理代码:

public void renderToTexture(){
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[0]);
    GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTex[0], 0);
    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthRb[0]);
    int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);

    drawRender();  //draws the effect on a fbo and saving the texture to renderTex[0]

    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTex[0]);
    drawEffect(); //draws a square with the effect texture on it

问题应该在某处,但我不知道该怎么做。我尝试了我能想到的一切。我甚至想要在着色器中处理背景颜色。

2 个答案:

答案 0 :(得分:1)

发布的代码看起来非常好。您需要确保用于颜色渲染目标(renderTex[0])的纹理具有alpha分量。

请注意,ES 2.0中保证可颜色渲染的纹理格式数量非常有限。只有两个带有alpha组件(参见规范中的表4.5)是GL_RGBA4GL_RGB5_A1。最值得注意的是,包括GL_RGBA,每个组件8位。

因此,为了使用保证的alpha组件定义颜色可渲染纹理以在所有ES 2.0实现中工作,您必须使用GL_RGBA作为内部格式,并{{ 1}}或GL_UNSIGNED_SHORT_4_4_4_4代表GL_UNSIGNED_SHORT_5_5_5_1的类型参数。

最常见的设备(至少是我见过的所有设备)都支持OES_rgb8_rgba8扩展,这增加了对8位组件纹理渲染的支持。但是,如果您想要完全可移植,则应在使用具有这些格式的渲染目标之前检查此扩展是否存在。

答案 1 :(得分:0)

我知道这个问题已经过时了,但我现在也遇到了它,我的解决方案就是用GLSurfaceView做一些事情。只需在设置上下文

后添加这些行
glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 0, 0);
glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);

我已经使用了GL_RGBA格式,并且真的很恼火,没有其他工作正常,但这就像魔法一样。