Opengl-FrameBuffer对象无法在真实设备

时间:2015-11-13 14:06:58

标签: android opengl-es

我想在使用FrameBuffer对象的纹理中捕获我的Android openGl App中的渲染场景。

EveryThing在模拟器中很好,但在Real Device上,frameBuffer对象不起作用,

意味着Nothing转到我的纹理,这是FBO类(用于创建FrameBuffer并创建它的纹理):

public class FBO {
    int [] fb, renderTex;
    int [] TextureBank;
    int top;
    int texW; 
    int texH;    
    int maxTextures;
    public FBO(int width,int height,int maxTextures){
        texW = width; 
        texH = height;
        fb = new int[1];
        renderTex= new int[1];
        top=-1;
        this.maxTextures = maxTextures;
        TextureBank = new int[maxTextures];
    }
    public void setup(GL10 gl){
        // generate
        ((GL11ExtensionPack)gl).glGenFramebuffersOES(1, fb, 0); 
        gl.glEnable(GL10.GL_TEXTURE_2D);
        gl.glGenTextures(1, renderTex, 0);// generate texture
        gl.glBindTexture(GL10.GL_TEXTURE_2D, renderTex[0]);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                GL10.GL_CLAMP_TO_EDGE); 
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                GL10.GL_CLAMP_TO_EDGE);  
        //texBuffer = ByteBuffer.allocateDirect(buf.length*4).order(ByteOrder.nativeOrder()).asIntBuffer();
        //gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,GL10.GL_MODULATE);
        gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, texW, texH, 0, GL10.GL_RGBA, GL10.GL_FLOAT, null);
        gl.glDisable(GL10.GL_TEXTURE_2D); 
        if(top>=maxTextures-1){ 
            Log.e("OUT OF TEXTURE COUNTS", "OUT OF TEXTURE COUNTS Texture WIll Not Be added to Stack");
        }
        else{
        TextureBank [++top]= renderTex[0];
        Log.d("TOP= ", "" + top);
        }
    }  


    public boolean RenderStart(GL10 gl){
        // Bind the framebuffer
        ((GL11ExtensionPack)gl).glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, fb[0]);

        // specify texture as color attachment
        ((GL11ExtensionPack)gl).glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, GL10.GL_TEXTURE_2D, renderTex[0], 0);

        int error = gl.glGetError();
        if (error != GL10.GL_NO_ERROR) {
            Log.d("err", "FIRST Background Load GLError: " + error+"      ");
        }
        int status = ((GL11ExtensionPack)gl).glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
        if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES)
        {
            Log.d("err", "SECOND Background Load GLError: " + status+"      ");;
            return true;
        }
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        return true;
    } 

    public void RenderEnd(GL10 gl){
        ((GL11ExtensionPack)gl).glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        gl.glEnable(GL10.GL_TEXTURE_2D);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
        gl.glColor4f(1,1,1,1);
        gl.glDisable(GL10.GL_TEXTURE_2D);
    }

    public int getTexture(){
        return renderTex[0];
    }


} 

这是我使用此FBO的OnDrawFrame方法:

public synchronized void onDrawFrame(GL10 gl) {
    mObserver.onDrawFrame();
    gl.glClearColor(Color.red(mBackgroundColor) / 255f,
            Color.green(mBackgroundColor) / 255f,
            Color.blue(mBackgroundColor) / 255f,
            Color.alpha(mBackgroundColor) / 255f);
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

    gl.glLoadIdentity();




    if(capture){

    if(AttachTexture){
    int h = gl.glGetError();
    /**
    Setup FBO
    */
    frameBuffer.setup(gl);
    if(h!=0){
        Log.d("ERROR", "ERROR Happend"+h+"");
    }
    AttachTexture = false;
    }

    /**
    Start Rendering In FBO
    */
    frameBuffer.RenderStart(gl);  


    if (USE_PERSPECTIVE_PROJECTION) { 
        double x = mCurlMesh.GetMinX()* mCurlMesh.GetMinY();
        gl.glTranslatef((float)(-1.000-mCurlMesh.GetMinX()),(float)(-1.000-mCurlMesh.GetMinY()), -6f);
    } 

    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity(); 


    GLU.gluOrtho2D(gl, (float)mCurlMesh.GetMinX(), (float)mCurlMesh.GetMaxX(),
            (float)mCurlMesh.GetMinY(), (float)mCurlMesh.GetMaxY());
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();    
    gl.glViewport(0, 0,texW,texH);
    mCurlMesh.onDrawFrame(gl);    

    /**
    End Rendering In FBO
    */
    frameBuffer.RenderEnd(gl); 

    }  

    //Reset Every Thing to Its Normal State
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    GLU.gluOrtho2D(gl, -1.1f,1.1f,-1.1f, 1.1f);
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();
    gl.glViewport(0, 0, mViewportWidth, mViewportHeight);



    mCurlMesh.onDrawFrame(gl);
}

我应该提一下我的纹理尺寸是2 ^ n:

frameBuffer  = new FBO(1024, 1024, 8); 

0 个答案:

没有答案