GLFBO.java 4.11 KB
Newer Older
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
1 2
package com.projectseptember.RNGL;

Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
3 4
import android.util.Log;

Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
5 6 7 8 9
import java.util.ArrayList;
import java.util.List;

import static android.opengl.GLES20.*;

Gaëtan Renaudeau's avatar
wip  
Gaëtan Renaudeau committed
10
public class GLFBO {
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
11 12 13 14 15 16 17 18 19
    public final List<GLTexture> color = new ArrayList<>();
    private int handle;
    private int width = 0;
    private int height = 0;

    private static GLTexture initTexture (int width, int height, int attachment) {
        GLTexture texture = new GLTexture();
        texture.bind();
        texture.setShape(width, height);
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
20
        glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture.getHandle(), 0);
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
21 22 23
        return texture;
    }

Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
24
    /*
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
25 26 27 28 29 30 31 32 33 34
    int initRenderBuffer (int width, int height, int component, int attachment)
    {
        int[] handleArr = new int[1];
        glGenRenderbuffers(1, handleArr, 0);
        int handle = handleArr[0];
        glBindRenderbuffer(GL_RENDERBUFFER, handle);
        glRenderbufferStorage(GL_RENDERBUFFER, component, width, height);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, handle);
        return handle;
    }
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
35
    */
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
36

Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
37
    /*
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
    class FBOState {

        private int fbo;
        private int rbo;
        private int tex;

        public FBOState() {
            int[] fbo = new int[1], rbo = new int[1], tex = new int[1];
            glGetIntegerv(GL_FRAMEBUFFER_BINDING, fbo, 0);
            glGetIntegerv(GL_RENDERBUFFER_BINDING, rbo, 0);
            glGetIntegerv(GL_TEXTURE_BINDING_2D, tex, 0);
            this.fbo = fbo[0];
            this.rbo = rbo[0];
            this.tex = tex[0];
        }

        private void restore() {
            glBindFramebuffer(GL_FRAMEBUFFER, fbo);
            glBindRenderbuffer(GL_FRAMEBUFFER, rbo);
            glBindTexture(GL_FRAMEBUFFER, tex);
        }
    }
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
60
    */
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
61 62

    public GLFBO() {
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
63 64
        Log.i("GLFBO", "new");
        //FBOState state = new FBOState();
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
65 66 67 68 69 70 71 72 73 74 75 76

        int[] handleArr = new int[1];
        glGenFramebuffers(1, handleArr, 0);
        handle = handleArr[0];

        int numColors = 1;

        glBindFramebuffer(GL_FRAMEBUFFER, handle);

        for(int i=0; i<numColors; ++i) {
            color.add(initTexture(width, height, GL_COLOR_ATTACHMENT0 + i));
        }
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
77
        // state.restore();
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
78 79 80 81
    }

    @Override
    protected void finalize() throws Throwable {
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
82
        Log.i("GLFBO", "finalize");
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
83 84 85 86 87 88 89 90 91 92 93
        super.finalize();
        int[] handleArr = new int[] { handle };
        glDeleteFramebuffers(1, handleArr, 0);
    }


    void checkStatus () {
        int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
        if(status != GL_FRAMEBUFFER_COMPLETE) {
            switch (status) {
                case GL_FRAMEBUFFER_UNSUPPORTED:
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
94
                    throw new RuntimeException("Framebuffer unsupported");
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
95
                case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
96
                    throw new RuntimeException("Framebuffer incomplete attachment");
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
97
                case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
98
                    throw new RuntimeException("Framebuffer incomplete dimensions");
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
99
                case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
100
                    throw new RuntimeException("Framebuffer incomplete missing attachment");
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
101
                default:
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
102
                    throw new RuntimeException("Failed to create framebuffer: " + status);
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
103 104 105 106 107
            }
        }
    }

    public void bind () {
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
108
        Log.i("GLFBO", "bind");
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
109 110 111 112 113
        glBindFramebuffer(GL_FRAMEBUFFER, handle);
        glViewport(0, 0, width, height);
    }

    public void setShape(int w, int h) {
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
114
        Log.i("GLFBO", "setShape "+w+" "+h);
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
115 116 117 118
        if (w == width && h == height) return;
        int[] maxFBOSize = new int[1];
        glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, maxFBOSize, 0);
        if( w < 0 || w > maxFBOSize[0] || h < 0 || h > maxFBOSize[0]) {
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
119
            throw new IllegalArgumentException("Can't resize framebuffer. Invalid dimensions");
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
120 121 122 123
        }
        width = w;
        height = h;

Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
124
        //FBOState state = new FBOState();
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
125 126 127 128 129 130 131 132

        for (GLTexture clr: color) {
            clr.setShape(w, h);
        }

        glBindFramebuffer(GL_FRAMEBUFFER, handle);
        checkStatus();

Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
133
        //state.restore();
Gaëtan Renaudeau's avatar
WIP  
Gaëtan Renaudeau committed
134 135
    }
}