JOGL 和帧缓冲区渲染到纹理的问题:无效帧缓冲区操作错误
Posted
技术标签:
【中文标题】JOGL 和帧缓冲区渲染到纹理的问题:无效帧缓冲区操作错误【英文标题】:Problem with JOGL and Framebuffer Render-to-texture: Invalid Framebuffer Operation Error 【发布时间】:2010-04-16 15:04:54 【问题描述】:好的,所以我尝试将场景渲染为 32x32 的小纹理,但遇到了问题。当我尝试向纹理实际绘制任何内容时,出现“无效帧缓冲区操作”错误。我已经简化了下面的代码,它只是尝试将一个四边形渲染到一个纹理,然后将该四边形绑定为另一个渲染到屏幕上的四边形的纹理。所以我的问题是......错误在哪里?这是使用 JOGL 1.1.1。错误发生在代码中的Checkpoint2。
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)
【问题讨论】:
我还必须添加这个:gl.glEnable(GL.GL_TEXTURE_2D); 【参考方案1】:为 texRender_32x32 尝试不同的 internalFormat。我认为必须是某种 RGBA 格式,而不仅仅是 RGB。
编辑: 好吧,我想我找到了。您正在为纹理使用默认的最小过滤器,这意味着 mipmapping。在创建和绑定纹理后添加这一行,一切都应该正常工作:
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
【讨论】:
好的,我把这行改成 gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA_FLOAT32_ATI, 32, 32, 0, GL.GL_RGBA, GL.GL_FLOAT, null);但仍然没有运气。【参考方案2】:这个例子我也有问题。错误是
gl.glBindTexture(GL.GL_TEXTURE_1D, this.texRender_32x32);
应该是
gl.glBindTexture(GL.GL_TEXTURE_2D, this.texRender_32x32);
【讨论】:
以上是关于JOGL 和帧缓冲区渲染到纹理的问题:无效帧缓冲区操作错误的主要内容,如果未能解决你的问题,请参考以下文章
Android GLES 2.0:帧缓冲渲染到半浮点纹理适用于某些设备,而不是其他设备