好的,所以我试图将一个场景渲染成一个小的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) { }
}
答案 0 :(得分:3)
为texRender_32x32尝试不同的internalFormat。我认为这必须是一些RGBA格式而不仅仅是RGB。
编辑: 好的,我想我找到了。您正在使用纹理的默认最小过滤器,这意味着mipmapping。在创建&之后添加此行绑定纹理,一切都应该工作:
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
答案 1 :(得分:0)
我也遇到过这个例子的问题。错误是
gl.glBindTexture(GL.GL_TEXTURE_1D, this.texRender_32x32);
应该是
gl.glBindTexture(GL.GL_TEXTURE_2D, this.texRender_32x32);