代码之家  ›  专栏  ›  技术社区  ›  John

将jogl和帧缓冲区呈现到纹理时出现问题:帧缓冲区操作错误无效

  •  3
  • John  · 技术社区  · 16 年前

    好的,所以我试着把一个场景渲染成一个32x32的小纹理,结果遇到了问题。我得到一个“无效帧缓冲区操作”错误,当我试图实际绘制任何纹理。我已经简化了下面的代码,以便它只尝试将一个四边形渲染为一个纹理,然后将该四边形绑定为另一个渲染到屏幕的四边形的纹理。所以我的问题是…错误在哪里?这是使用Jogl 1.1.1。错误发生在代码中的检查点2。

    import java.awt.event.*;
    
    import javax.media.opengl.*;
    import javax.media.opengl.glu.*;
    import javax.swing.JFrame;
    import java.nio.*;
    
    public class Main extends JFrame implements GLEventListener, KeyListener, MouseListener, MouseMotionListener, ActionListener{
    
    
    /* GL related variables */
    private final GLCanvas canvas;
    private GL gl;
    private GLU glu;
    
    private int winW = 600, winH = 600;
    
    private int texRender_FBO;
    private int texRender_RB;
    private int texRender_32x32;
    
    public static void main(String args[]) {
        new Main();
    }
    
    /* creates OpenGL window */
    public Main() {
        super("Problem Child");
        canvas = new GLCanvas();
        canvas.addGLEventListener(this);
        canvas.addKeyListener(this);
        canvas.addMouseListener(this);
        canvas.addMouseMotionListener(this);
        getContentPane().add(canvas);
        setSize(winW, winH);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
        canvas.requestFocus();
    }
    
    /* gl display function */
    public void display(GLAutoDrawable drawable) {
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, this.texRender_FBO);
        gl.glPushAttrib(GL.GL_VIEWPORT_BIT);
        gl.glViewport(0, 0, 32, 32);
        gl.glClearColor(1.f, 0.f, 0.f, 1.f);
        System.out.print("Checkpoint1: "); outputError();
        gl.glBegin(GL.GL_QUADS);
        {
            //gl.glTexCoord2f(0.0f, 0.0f);
            gl.glColor3f(1.f, 0.f, 0.f);
            gl.glVertex3f(0.0f, 1.0f, 1.0f);
            //gl.glTexCoord2f(1.0f, 0.0f);
            gl.glColor3f(1.f, 1.f, 0.f);
            gl.glVertex3f(1.0f, 1.0f, 1.0f);
            //gl.glTexCoord2f(1.0f, 1.0f);
            gl.glColor3f(1.f, 1.f, 1.f);
            gl.glVertex3f(1.0f, 0.0f, 1.0f);
            //gl.glTexCoord2f(0.0f, 1.0f);
            gl.glColor3f(1.f, 0.f, 1.f);
            gl.glVertex3f(0.0f, 0.0f, 1.0f);
        }
        gl.glEnd(); System.out.print("Checkpoint2: "); outputError(); //Here I get an invalid framebuffer operation
    
        gl.glPopAttrib();
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
        gl.glClearColor(0.f, 0.f, 0.f, 1.f);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
    
    
        gl.glColor3f(1.f, 1.f, 1.f);
        gl.glBindTexture(GL.GL_TEXTURE_1D, this.texRender_32x32);
        gl.glBegin(GL.GL_QUADS);
        {
            gl.glTexCoord2f(0.0f, 0.0f);
            //gl.glColor3f(1.f, 0.f, 0.f);
            gl.glVertex3f(0.0f, 1.0f, 1.0f);
            gl.glTexCoord2f(1.0f, 0.0f);
            //gl.glColor3f(1.f, 1.f, 0.f);
            gl.glVertex3f(1.0f, 1.0f, 1.0f);
            gl.glTexCoord2f(1.0f, 1.0f);
            //gl.glColor3f(1.f, 1.f, 1.f);
            gl.glVertex3f(1.0f, 0.0f, 1.0f);
            gl.glTexCoord2f(0.0f, 1.0f);
            //gl.glColor3f(1.f, 0.f, 1.f);
            gl.glVertex3f(0.0f, 0.0f, 1.0f);
        }
        gl.glEnd();
    }
    
    /* initialize GL */
    public void init(GLAutoDrawable drawable) {
        gl = drawable.getGL();
        glu = new GLU();
    
        gl.glClearColor(.3f, .3f, .3f, 1f);
        gl.glClearDepth(1.0f);
    
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrtho(0, 1, 0, 1, -10, 10);
        gl.glMatrixMode(GL.GL_MODELVIEW);
    
        //Set up the 32x32 texture
        this.texRender_FBO = genFBO(gl);
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, this.texRender_FBO);
    
        this.texRender_32x32 = genTexture(gl);
        gl.glBindTexture(GL.GL_TEXTURE_2D, this.texRender_32x32);
        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB_FLOAT32_ATI, 32, 32, 0, GL.GL_RGB, GL.GL_FLOAT, null);
        gl.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_COLOR_ATTACHMENT0_EXT, GL.GL_TEXTURE_2D, this.texRender_32x32, 0);
        //gl.glDrawBuffer(GL.GL_COLOR_ATTACHMENT0_EXT);
    
        this.texRender_RB = genRB(gl);
        gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, this.texRender_RB);
        gl.glRenderbufferStorageEXT(GL.GL_RENDERBUFFER_EXT, GL.GL_DEPTH_COMPONENT24, 32, 32);
        gl.glFramebufferRenderbufferEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_DEPTH_ATTACHMENT_EXT, GL.GL_RENDERBUFFER_EXT, this.texRender_RB);
    
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
        gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, 0);
        outputError();
    }
    
    private void outputError() {
        int c;
        if ((c = gl.glGetError()) != GL.GL_NO_ERROR)
            System.out.println(glu.gluErrorString(c));
    }
    
    private int genRB(GL gl) {
        int[] array = new int[1];
        IntBuffer ib = IntBuffer.wrap(array);
        gl.glGenRenderbuffersEXT(1, ib);
        return ib.get(0);
    }
    
    private int genFBO(GL gl) {
        int[] array = new int[1];
        IntBuffer ib = IntBuffer.wrap(array);
        gl.glGenFramebuffersEXT(1, ib);
        return ib.get(0);
    }
    
    private int genTexture(GL gl) {
        final int[] tmp = new int[1];
        gl.glGenTextures(1, tmp, 0);
        return tmp[0];
    }
    
    /* mouse and keyboard callback functions */
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        winW = width;
        winH = height;
    
        gl.glViewport(0, 0, width, height);
    }
    
    //Sorry about these, I just had to delete massive amounts of code to boil this thing down and these are hangers-on
    public void mousePressed(MouseEvent e) {}
    public void mouseDragged(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void keyPressed(KeyEvent e) {}
    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { }
    public void keyTyped(KeyEvent e) { }
    public void keyReleased(KeyEvent e) { }
    public void mouseMoved(MouseEvent e) { }
    public void actionPerformed(ActionEvent e) { }
    public void mouseClicked(MouseEvent e) { }
    public void mouseEntered(MouseEvent e) { }
    public void mouseExited(MouseEvent e) { }
    
    }
    
    2 回复  |  直到 15 年前
        1
  •  3
  •   Maurice Gilden    16 年前

    请为texrender_32x32尝试其他内部格式。我认为这必须是某种rgba格式,而不仅仅是rgb。

    编辑: 好吧,我想我找到了。您正在为纹理使用默认的最小过滤器,这意味着mipmapping。创建并绑定纹理后添加此行,所有操作都应正常:

    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
    
        2
  •  0
  •   Stephen Todd    15 年前

    我对这个例子也有意见。错误是

    gl.glBindTexture(GL.GL_TEXTURE_1D, this.texRender_32x32);
    

    应该是

    gl.glBindTexture(GL.GL_TEXTURE_2D, this.texRender_32x32);
    
    推荐文章