Android Programjaim

Android, Flutter/Dart, Kotlin, Java, Unity, HarmonyOS

OpenGL-ES 1.1 Android + FBO motionblur

2012. augusztus 02. 12:57 - lacas8282

Először is GL11ExtensionPack kell hozzá, ami alapból ott van.
Mivel manapság a telók 95+%-a tud GL-ES 2.0-át, így valszeg az 1.1 is támogatott rajtuk.

Ez ugye még FFP, Fixed Function Pipeline, nem shaderes megoldásokkal dolgozik.

Nézzük mi az FBO, FrameBufferObject, ezzel gyakorlatilag a GLReadPixels-t tudjuk felváltani, mivel az nagyon lassú.

Példa: a képernyőnket mentsük el egy FBO-ba (offscreen renderelés), majd ezek után rakjuk a képet egy textúrára pl orthografikusan a 3d világ elé.

Nézzük hogy is kell ezt:

FBO_init:

//1-2

    int[][] viewFramebuffer     = new int[MAX_FBOS][3];
    int[][] viewRenderbuffer     = new int[MAX_FBOS][3];
    int[][] depthRenderbuffer     = new int[MAX_FBOS][1];
    int[][] mFBOTextures        = new int[MAX_FBOS][1];

//3
        Meshes.addSquare2D("fbo", Shared.screen.width, Shared.screen.height, false);
        Meshes.selectById("fbo").setTextureCoords(new float[] {
                                                        1, 1,
                                                        1, 0,
                                                        0, 1,
                                                        0, 0});
//4

        for (int i=0; i<MAX_FBOS; i++) {
            OpenGL.gl.glGenTextures(1, mFBOTextures[i], 0);
            OpenGL.gl.glBindTexture(GL11.GL_TEXTURE_2D, mFBOTextures[i][0]);

            OpenGL.gl.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height, 0,GL11.GL_RGB, GL11.GL_UNSIGNED_SHORT_5_6_5, null);
    
//...filterek   
            gl11ep.glGenFramebuffersOES(1, viewFramebuffer[i], 0);
            gl11ep.glGenRenderbuffersOES(1, viewRenderbuffer[i], 0);
            
            gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, viewFramebuffer[i][0]);
            gl11ep.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, viewRenderbuffer[i][0]);
            gl11ep.glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,    GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES,    GL11.GL_TEXTURE_2D,     mFBOTextures[i][0], 0);
            //gl11ep.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, GL11ExtensionPack.GL_RENDERBUFFER_OES, viewRenderbuffer[i][0]);
            gl11ep.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,    GL11ExtensionPack.GL_DEPTH_ATTACHMENT_OES,    GL11ExtensionPack.GL_RENDERBUFFER_OES, depthRenderbuffer[i][0]);
            
            gl11ep.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, depthRenderbuffer[i][0]);
            gl11ep.glRenderbufferStorageOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, GL11ExtensionPack.GL_DEPTH_COMPONENT16, width, height);
            gl11ep.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, GL11ExtensionPack.GL_DEPTH_ATTACHMENT_OES, GL11ExtensionPack.GL_RENDERBUFFER_OES, depthRenderbuffer[i][0]);
        }

1-2: hány FBO-nk legyen
1-2: létrehozunk egy orthografikus négyzetet (vertexeket a vertexbufferben, és a textúrakoordinátákat beállítjuk, hogy felénk nézzen)
3: az összes FBO-ra létrehozunk egy új textúrát, és inicializáljuk a filtereket rá, valamint a buffereket is

FBO draw:

        //először kirajzoljuk magát a 3d képernyőjét, kamerákkal, cullinggal, mindenfélével
        OpenGL.gl.glPushMatrix();
            GLengine.renderer.drawScene(true);
        OpenGL.gl.glPopMatrix();

        //kell az extensionPack
        GL11ExtensionPack gl11ex = (GL11ExtensionPack) OpenGL.gl;
        
        //az aktuális FBO-ba kirajzoljuk az egész Scene-t (nem a képernyőre magára)
            for (int i=0; i<MAX_FBOS; i++) {
                gl11ex.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, viewFramebuffer[i][0]);
                    OpenGL.gl.glPushMatrix();
                        GLengine.renderer.drawScene(true);
                    OpenGL.gl.glPopMatrix();
                gl11ex.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
            }

          //orthografikus módot állítunk be, azaz 2d-be rajzolunk majd a 3d-s kép fölé
                opengl.setOrthoStart();
                    //maga a mesh, ami 4*2 pontból áll, egy sima téglalap
                    final Mesh mesh = Meshes.selectById("fbo");
                      //blendeljünk egyet, ezáltal blur-ösebb lesz majd a cucc
                        opengl.setAlphaBlendEnabled(false, GL11.GL_ONE, GL11.GL_ONE);
                        
                            //kirajzoljuk az összes FBO-ban lévő képet a meshre
                            for (int i=0; i<MAX_FBOS; i++) {
                                OpenGL.gl.glBindTexture(GL11.GL_TEXTURE_2D, mFBOTextures[i][0]);
    
                                    opengl.colorFromHEX("ffffff", 0.9f);
                                        mesh
                                        .saveMatrix()
                                                .bindBuffers()
                                                .translate(0, 0)
                                                .scale(-1f, 1, 1)
                                                .draw(false)
                                        .loadMatrix();
                            }
                            
                        opengl.setAlphaBlendDisabled(false);

                opengl.setOrthoEnd();

komment
süti beállítások módosítása