JOGL 和帧缓冲区渲染到纹理的问题:无效的帧缓冲区操作错误
好的,我尝试将场景渲染为小型 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) { }
}
Okay, so I am trying to render a scene to a small 32x32 texture and ran into problems. I get an "invalid framebuffer operation" error when I try to actually draw anything to the texture. I have simplified the code below so that it simply tries to render a quad to a texture and then bind that quad as a texture for another quad that is rendered to the screen. So my question is this... where is the error? This is using JOGL 1.1.1. The error occurs at Checkpoint2 in the code.
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) { }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为 texRender_32x32 尝试不同的内部格式。我认为这必须是某种 RGBA 格式而不仅仅是 RGB。
编辑:
好吧,我想我找到了。您正在对纹理使用默认的最小过滤器,这意味着 mipmap。创建 & 之后添加此行绑定纹理,一切都应该正常:
Try a different internalFormat for texRender_32x32. I think that has to be some RGBA format and not just RGB.
EDIT:
Ok, I think I found it. You are using the default min-filters for the texture which would imply mipmapping. Add this line after creating & binding the texture and everything should work:
我对这个例子也有问题。错误
应该是
I had problems with this example too. The error was
should be