Question

When I render to FBO, the depth testing appears to fail, but when I don't it works beautifully. Weirdly, though, on the more complex version (I haven't tested this one), when I tested it on school computers (Not when I should be working of course! :-)), even without FBOs, it still failed.

Unfortunately, I haven't got enough reputation on this site to post a picture, so I will post it as a link here. (This is the more complex one, but the effect is still the same (The coloured cube is rendered the same as in this version anyway)).

Finally, here's the code:

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;
    }
}

Note that I left in a couple of wrappers - Camera and CamController - they just allow you to move around with glTranslate() and glRotate()

Was it helpful?

Solution

You are crating an FBO without a depth buffer - so the depth test will of course not work. You should create a Renderbuffer with some depth-renderable format and attach it as GL_DEPTH_ATTACHMENT, like this:

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 and height schould match the size of your color buffer, of course.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top