当我渲染到FBO时,深度测试似乎失败了,但是当我不这样做时,它的工作效果非常好。奇怪的是,在更复杂的版本(我没有测试过这个版本)上,当我在学校的计算机上测试它时(当然我不应该工作!:-)),即使没有FBO,它仍然会失败。 / p>
很遗憾,我在此网站上没有足够的声誉来发布图片,因此我会将其发布为链接here。 (这是更复杂的一个,但效果仍然相同(无论如何,彩色立方体的渲染方式与此版本相同)。)
最后,这是代码:
Main.java:
package Main;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.util.glu.GLU.gluPerspective;
import java.nio.ByteBuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
public class Main {
//This just allows me to move around the scene - it's surely not the cause of the bug...
CamController camera;
int /*ID of FBO*/fboID, /*Texture FBO will render to*/renderTexture;
public Main() {
//Init display
try {
Display.setDisplayMode(new DisplayMode(1280, 720));
Display.setTitle("Example of a fail");
//Display.setVSyncEnabled(true);
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
setTo3d();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Mouse.setGrabbed(true);
//Tested it with, and without this...
glClearDepth(1);
glEnable(GL_DEPTH_TEST);
glShadeModel (GL_SMOOTH); // Select Smooth Shading
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
init();
initFBO();
loop();
}
/**Initiates any objects I use.*/
public void init(){
camera = new CamController();
}
public void initFBO(){
renderTexture = createTexture(1280, 720, false);
fboID = glGenFramebuffers();
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTexture, /*Mipmap Level*/0);
int i = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(i != GL_FRAMEBUFFER_COMPLETE){
System.err.println("Framebuffer is not working! Fault: "+org.lwjgl.util.glu.GLU.gluErrorString(i));
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
/*Main running loop*/
public void loop(){
while(!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//Checks the keyboard, and mouse to move camera
camera.update();
setTo3d();
//Rotates and translates the image to camera's perspective.
camera.camera.lookThrough();
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
draw();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
setTo2d();
drawFBO();
Display.update();
glFlush();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
/*Draws objects to FBO - I can use VBOs, but was just saving time.*/
public void draw(){
glBegin(GL_QUADS);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glColor3f(1.0f, 0.5f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd();
glColor3f(1,1,1);
}
//Draws the FBO rect - Again, can use VBOs, just saving time...
public void drawFBO(){
glBindTexture(GL_TEXTURE_2D, renderTexture);
glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex2f(0,0);
glTexCoord2f(1,0);
glVertex2f(1280,0);
glTexCoord2f(1,1);
glVertex2f(1280,720);
glTexCoord2f(0,1);
glVertex2f(0,720);
glEnd();
}
public static void main(String[] args) {
new Main();
}
/*I know there are better ways of doing this, but I'm doing it this way for the sake of time...*/
public void setTo2d(){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1280, 0, 720, 1, -1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
public void setTo3d(){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//The problem is not caused by too small a zNear value - I've already tested that...
gluPerspective(/*FOV in degrees*/30f, /*Aspect ratio*/ 1280f/720f, /*zNear*/ 0.001f, /*zFar*/50000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
//This code taken from TheCPlusPlusGuy, so should work
public int createTexture(int w, int h, boolean isDepth){
int handle;
handle = glGenTextures();
glBindTexture(GL_TEXTURE_2D, handle);
if(isDepth){
GL11.glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, (ByteBuffer) null);
}else{
GL11.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_FLOAT, (ByteBuffer) null);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
return handle;
}
}
请注意,我留下了几个包装器--Camera和CamController - 它们只允许你使用glTranslate()和glRotate()
移动答案 0 :(得分:2)
你正在装箱没有深度缓冲器的FBO - 因此深度测试当然不起作用。您应该创建一个具有深度可渲染格式的Renderbuffer,并将其附加为GL_DEPTH_ATTACHMENT
,如下所示:
GLuint depthbuffer;
glGenRenderbuffers(1, &depthbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, wisth, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer);
当然, width
和height
可以匹配颜色缓冲区的大小。