Question

I want to setup a really simple two-pass effect. The first pass draws a texture object to a texture. The second pass creates a full screen quad in the geometry shader and textures it with the texture written in pass one.

The texture and framebuffer is set up in the following way:

gl.glGenFramebuffers(1, frameBufferHandle, 0);
gl.glBindFramebuffer(GL3.GL_FRAMEBUFFER, frameBufferHandle[0]);

texture = new Texture(gl, new TextureData(gl.getGLProfile(), GL3.GL_RGB, viewportWidth, viewportHeight,
    0, GL3.GL_RGB, GL3.GL_UNSIGNED_BYTE, false, false, false, null, null));
texture.setTexParameteri(gl, GL3.GL_TEXTURE_MAG_FILTER, GL3.GL_LINEAR);
texture.setTexParameteri(gl, GL3.GL_TEXTURE_MIN_FILTER, GL3.GL_LINEAR);
gl.glFramebufferTexture(GL3.GL_FRAMEBUFFER, GL3.GL_COLOR_ATTACHMENT0, texture.getTextureObject(), 0);

int drawBuffers[] = {GL3.GL_COLOR_ATTACHMENT0};
gl.glDrawBuffers(1, drawBuffers, 0);

if (gl.glCheckFramebufferStatus(GL3.GL_FRAMEBUFFER) != GL3.GL_FRAMEBUFFER_COMPLETE)
    throw new Exception("error while creating framebuffer");

The render function looks like:

// 1st pass
gl.glBindFramebuffer(GL3.GL_FRAMEBUFFER, frameBufferHandle[0]);
gl.glClearColor(0.2f, 0.2f, 0.2f, 1.0f); 
gl.glClear(GL3.GL_STENCIL_BUFFER_BIT | GL3.GL_COLOR_BUFFER_BIT | GL3.GL_DEPTH_BUFFER_BIT);

texturePass.apply();
texturePass.updatePerObject(world);
texturePass.updateTexture(object.getDiffuseMap());
object.draw(gl);    

// 2nd pass
gl.glBindFramebuffer(GL3.GL_FRAMEBUFFER, 0);
gl.glClearColor(0.2f, 0.2f, 0.2f, 1.0f); 
gl.glClear(GL3.GL_STENCIL_BUFFER_BIT | GL3.GL_COLOR_BUFFER_BIT | GL3.GL_DEPTH_BUFFER_BIT);

fullscreenQuadPass.apply();
fullscreenQuadPass.updateTexture(texture)

; gl.glDrawArrays(GL3.GL_POINTS, 0, 1);

The picture below shows the result of applying this effect: Render-to-Texture error

As you hopefully can see, one can see through the golem and see his right hand. It seems like there is some kind of depth-test or transparency error.

Everything looks fine if I comment the 2nd pass out and replace

gl.glBindFramebuffer(GL3.GL_FRAMEBUFFER, frameBufferHandle[0]);

by

gl.glBindFramebuffer(GL3.GL_FRAMEBUFFER, 0);

Does anyone have an idea, what goes on here?

EDIT: In fact, I'm actually missing a depth buffer for the 2nd pass. Thus, I've updated my initialization sequence to

// Create framebuffer
gl.glGenFramebuffers(1, frameBufferHandle, 0);
gl.glBindFramebuffer(GL4.GL_FRAMEBUFFER, frameBufferHandle[0]);

// Set up color texture
colorTexture = new Texture(gl, new TextureData(gl.getGLProfile(),
    GL4.GL_RGBA, width, height, 0, GL4.GL_RGBA, GL4.GL_UNSIGNED_BYTE,
        false, false, false, null, null));
gl.glFramebufferTexture(GL4.GL_FRAMEBUFFER, GL4.GL_COLOR_ATTACHMENT0,
    colorTexture.getTextureObject(), 0);

// Create and set up depth renderbuffer
gl.glGenRenderbuffers(GL4.GL_RENDERBUFFER, depthRenderBufferHandle, 0);
gl.glBindRenderbuffer(GL4.GL_RENDERBUFFER, depthRenderBufferHandle[0]);
gl.glRenderbufferStorage(GL4.GL_RENDERBUFFER, GL4.GL_DEPTH_COMPONENT,
    width, height);
gl.glFramebufferRenderbuffer(GL4.GL_FRAMEBUFFER, GL4.GL_DEPTH_ATTACHMENT,
    GL4.GL_RENDERBUFFER, depthRenderBufferHandle[0]);

int drawBuffers[] = {GL4.GL_COLOR_ATTACHMENT0};
gl.glDrawBuffers(1, drawBuffers, 0);

However, now my system crashes with a "fatal error" by the Java Runtime Environment. If I comment the newly added lines out, everything "works fine". What's the point now?

EDIT2: I've no idea why I've written

gl.glGenRenderbuffers(GL4.GL_RENDERBUFFER, depthRenderBufferHandle, 0);

Of course, it should be

gl.glGenRenderbuffers(1, depthRenderBufferHandle, 0);

That solved my problem.

Was it helpful?

Solution

Your Framebuffer Object currently lacks a depth attachment.

Here is some C pseudo-code that will address your problem:

GLuint depth_rbo;
glGenRenderbuffers (1, &depth_rbo);

glBindRenderbuffer (GL_RENDERBUFFER, depth_rbo);

glRenderbufferStorage     (GL_RENDERBUFFER, GL_DEPTH_COMPONENT,  width, height);
glFramebufferRenderbuffer (GL_FRAMEBUFFER,  GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_rbo);

In fact, it also lacks a stencil attachment, so I am not sure why you are clearing the stencil buffer?

If you have stencil operations to perform you will need to allocate storage for it as well. Moreover, if you need both depth and stencil in an FBO, you must use a packed Depth-Stencil format (GL_DEPTH_STENCIL_ATTACHMENT).

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