当我渲染到 FBO 时,深度测试似乎失败了,但当我不这样做时,它的效果很好。不过,奇怪的是,在更复杂的版本上(我没有测试过这个),当我在学校电脑上测试它时(当然不是我应该工作的时候!:-)),即使没有 FBO,它仍然失败。
不幸的是,我在这个网站上没有足够的声誉来张贴图片,所以我将把它作为链接发布在这里。(这个比较复杂,但是效果还是一样的(反正彩色立方体的渲染和这个版本一样))。
最后,代码如下:
主.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() 移动