简体   繁体   English

Android Opengl ES 2.0 FrameBuffer无法正常工作

[英]Android Opengl ES 2.0 FrameBuffer not working

I'm working on a 2D Android project and I wish to draw stuff to an empty texture using an FBO and then draw that texture on screen. 我正在研究2D Android项目,我希望使用FBO将内容绘制到空纹理,然后在屏幕上绘制该纹理。 For debugging purposes, the FBO attached texture should immediately turn blue so I can tell that I am able to edit the texture because currently it won't even affect the texture. 出于调试目的,FBO附加纹理应立即变为蓝色,以便我可以告诉我能够编辑纹理,因为它目前甚至不会影响纹理。

FrameBuffer: 帧缓冲区:

public static class FrameBuffer{

    private final FaustEngine engine;
    private final int width;
    private final int height;
    private final int[] fboId = new int[1];
    private final int[] renId = new int[1];

    public FrameBuffer( FaustEngine Engine, int Width, int Height ){
        engine = Engine;
        width = Width;
        height = Height;

        GLES20.glGenRenderbuffers( 1, renId, 0 );
        GLES20.glBindRenderbuffer( GLES20.GL_RENDERBUFFER, renId[0] );
        GLES20.glRenderbufferStorage( GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT, width, height );

        GLES20.glGenFramebuffers( 1, fboId, 0 );
        GLES20.glBindFramebuffer( GLES20.GL_FRAMEBUFFER, fboId[0] );
        GLES20.glFramebufferRenderbuffer( GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, renId[0] );

        GLES20.glBindRenderbuffer( GLES20.GL_RENDERBUFFER, 0);
        GLES20.glBindFramebuffer( GLES20.GL_FRAMEBUFFER, 0);
    }

    public void bind( int texId, int texWidth, int texHeight ){
        GLES20.glBindFramebuffer( GLES20.GL_FRAMEBUFFER, fboId[0] );
        GLES20.glFramebufferTexture2D( GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, texId, 0 );
        GLES20.glViewport( 0, 0, texWidth, texHeight );
        GLES20.glClearColor(0f, 0f, 1f, 1f );
        GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT ); //Turn blue

        //Fix projection matrix
        Matrix.orthoM( engine.getOrthoMatrix() , 0, 0, texWidth, texHeight, 0, -1, 1 );
    }

    public void unbind(){
        GLES20.glBindFramebuffer( GLES20.GL_FRAMEBUFFER, 0 );
        GLES20.glViewport( 0, 0, engine.getScreenWidth(), engine.getScreenHeight() );

        //Reset projection matrix
        Matrix.orthoM( engine.getOrthoMatrix() , 0, 0, engine.getScreenWidth(), engine.getScreenHeight(), 0, -1, 1 );
    }
}

Rendering code: 渲染代码:

FrameBuffer fbo = new FrameBuffer( game.getEngine(), 1024, 1024 );
final int[] texIds = new int[1];
game.getEngine().createBlankTextures( texIds, 1024, 1024 );

fbo.bind( texIds[0], 1024, 1024 );
//texture should turn blue here since in the bind() function I placed a glClear with blue
fbo.unbind();

Texture creation: 纹理创建:

public void createBlankTextures( int[] texIds, int width, int height ){
    GLES20.glGenTextures( texIds.length, texIds, 0 );
    for( int i=0; i<texIds.length; i++ ){
        GLES20.glBindTexture( GLES20.GL_TEXTURE_2D, texIds[i] );
        GLES20.glTexParameteri( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST );
        GLES20.glTexParameteri( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST );
        GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null );
        GLES20.glGenerateMipmap( GLES20.GL_TEXTURE_2D );
    }
}

So I have 2 questions. 所以我有2个问题。

1.) Do I need a Renderbuffer with the Framebuffer? 1.)我是否需要使用Framebuffer的Renderbuffer? I don't want to keep track of the depth. 我不想跟踪深度。 I just want to edit an existing purely 2D texture. 我只想编辑现有的纯2D纹理。

2.) Why is this not working? 2.)为什么这不起作用?

You don't need to create a renderbuffer if you don't need a depth buffer for your FBO rendering. 如果您不需要FBO渲染的深度缓冲区,则无需创建渲染缓冲区。

GL_DEPTH_COMPONENT is not a valid value for the internalformat argument of glRenderbufferStorage() in ES 2.0. GL_DEPTH_COMPONENT不是ES 2.0中glRenderbufferStorage()internalformat参数的glRenderbufferStorage() If you look at the supported values ( http://www.khronos.org/opengles/sdk/docs/man/xhtml/glRenderbufferStorage.xml ), the only depth format is GL_DEPTH_COMPONENT16 . 如果查看支持的值( http://www.khronos.org/opengles/sdk/docs/man/xhtml/glRenderbufferStorage.xml ),唯一的深度格式是GL_DEPTH_COMPONENT16

As always, glGetError() is your friend. 和往常一样, glGetError()是你的朋友。 It should indicate a GL_INVALID_ENUM error from your glRenderbufferStorage() call. 它应该指示glRenderbufferStorage()调用中的GL_INVALID_ENUM错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM