Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I've added functionality so that I can render to a framebuffer (for post-processing and stuff). I can successfully render to my framebuffer and then render that framebuffer, but anything with a shader does not render to my framebuffer. Rendering with the same shader worked before I added the framebuffer step.

Here's how I create my framebuffer:

// create the color texture
colorBuffer = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, colorBuffer);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

// create the depth texture
depthBuffer = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, depthBuffer);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Depth24Stencil8, width, height, 0, PixelFormat.DepthStencil, PixelType.UnsignedInt, IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

// create the fbo
GL.GenFramebuffers(1, out fbo);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, fbo);
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, colorBuffer, 0);
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthStencilAttachment, TextureTarget.Texture2D, depthBuffer, 0);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);

And this is my shader code:

// VERTEX SHADER
#version 330

uniform mat4 world;
uniform mat3 worldIT;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 textureTransformation;

in vec3 rPosition;
in vec3 rNormal;
in vec2 rTexCoord;
in vec3 rColor;

out vec3 vWorldPosition;
out vec3 vNormal;
out vec2 vTexCoord;
out vec3 vColor;

void main(void)
{
    vec4 tempWorld = world * vec4(rPosition, 1.0f);
    gl_Position = projection * view * tempWorld;

    vWorldPosition = tempWorld.xyz;
    mat3 normalSpace = mat3(world);
    vNormal = normalize(normalSpace * rNormal);
    vTexCoord = (textureTransformation * vec4(rTexCoord, 0.0f, 1.0f)).xy;
    vColor = rColor;
}

// FRAGMENT SHADER
#version 330

uniform sampler2D colorMap;

in vec3 vWorldPosition;
in vec3 vNormal;
in vec2 vTexCoord;
in vec3 vColor;

out vec4 fColor;

const vec3 ambientLight = vec3(0.1f, 0.1f, 0.1f);
const vec3 lightDir = vec3(0.0f, -1.0f, 1.0f);
const vec3 lightColor = vec3(1.0f, 1.0f, 1.0f);

void main(void)
{
    vec4 texel = texture(colorMap, vTexCoord);

    vec3 n = normalize(vNormal);
    vec3 l = normalize(lightDir);
    float nDotL = max(dot(n, l), 0.0f);

    vec4 diffuse = vec4((ambientLight + nDotL * lightColor) * vColor, 1.0f) * texel;

    vec4 specular = vec4(0.0f, 0.0f, 0.0f, 0.0f);

    fColor = diffuse + specular;
}

EDIT: It seems to be that, for some odd reason, my shader stopped outputting at all when I added the framebuffer support.

share|improve this question
    
Possible that you need to bind fColor to location 0 to make sure it goes to the right color attachment. Since you say you could render to the 0 framebuffer with these shaders, this might not be the problem, but it's worth checking. –  ktodisco Apr 27 '12 at 1:24
    
As in use GL.BindAttribLocation(shaderProgram, 0, "fColor")? Or something else? –  Boreal Apr 27 '12 at 1:55
    
Yea, give that a shot. –  ktodisco Apr 27 '12 at 7:55
add comment

2 Answers

Maybe you are unbinding your framebuffer with the last call:

GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);

void glBindFramebuffer(GLenum target, GLuint id)

The first parameter, target, should be GL_FRAMEBUFFER, and the second parameter is the ID of a framebuffer object. Once a FBO is bound, all OpenGL operations affect onto the current bound framebuffer object. The object ID 0 is reserved for the default window-system provided framebuffer. Therefore, in order to unbind the current framebuffer (FBO), use ID 0 in glBindFramebuffer().

-- From the Songho OpenGL tutorials

share|improve this answer
    
I updated your post and added a source link for a result I think you pulled that quote from. Please update your post if it's incorrect. –  Jonathan Hobbs May 18 '12 at 1:15
    
It's correct, thanks! –  avixz May 20 '12 at 18:41
add comment

After fbo creation call assert

assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 

I hope this will lead you to the right answer. See code errors here.

share|improve this answer
    
No, the framebuffer is being initialized correctly. –  Boreal Apr 27 '12 at 10:58
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.