I am writing a deferred shader and as one of the first steps, to get familiar with GLSL and using shaders and the framebuffer I am trying to change the color of a mesh through a shader. I have it linked to one of the buffers by calling glDrawBuffers with an array that holds the attachement and then binding the texture to my framebuffer:
glReadBuffer(GL_NONE);
GLint color_loc = glGetFragDataLocation(pass_prog,"out_Color");
GLenum draws [1];
draws[color_loc] = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1, draws);
glBindTexture(GL_TEXTURE_2D, diffuseTexture);
glFramebufferTexture(GL_FRAMEBUFFER, draws[color_loc], diffuseTexture, 0);
I have an out_Color variable in my fragment shader (otherwise it wouldn't even compile), but I can't manage to change the color of the mesh by setting it through that variable inside the shader. Does anyone has any idea why and could explain that to me?
Thanks
Edit: My shaders: Vertex Shader
#version 330
uniform mat4x4 u_Model;
uniform mat4x4 u_View;
uniform mat4x4 u_Persp;
uniform mat4x4 u_InvTrans;
in vec3 Position;
in vec3 Normal;
out vec3 fs_Normal;
out vec4 fs_Position;
void main(void) {
fs_Normal = (u_InvTrans*vec4(Normal,0.0f)).xyz;
vec4 world = u_Model * vec4(Pos开发者_运维技巧ition, 1.0);
vec4 camera = u_View * world;
fs_Position = camera;
gl_Position = u_Persp * camera;
}
Fragment shader
#version 330
uniform float u_Far;
in vec3 fs_Normal;
in vec4 fs_Position;
out vec4 out_Normal;
out vec4 out_Position;
out vec4 out_Color;
void main(void)
{
out_Normal = vec4(normalize(fs_Normal),0.0f);
out_Position = vec4(fs_Position.xyz,1.0f); //Tuck position into 0 1 range
out_Color = vec4(1.0f, 0.0f, 0.0f, 1.0f);//first three diffuse, last specular
}
And I am not doing a deferred shader in order to learn GLSL. I am learning GLSL in order to make a deferred shader. =)
More source code from setting up the textures:
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &depthTexture);
glGenTextures(1, &normalTexture);
glGenTextures(1, &positionTexture);
glGenTextures(1, &diffuseTexture);
//DEPTH TEXTURE
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
//NORMAL TEXTURE
glBindTexture(GL_TEXTURE_2D, normalTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0);
//POSITION TEXTURE
glBindTexture(GL_TEXTURE_2D, positionTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0);
//DIFFUSE TEXTURE
glBindTexture(GL_TEXTURE_2D, diffuseTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0);
//create a framebuffer object
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
//Instruct openGL that we won't bind a color texture with the currently binded FBO
glReadBuffer(GL_NONE);
GLint normal_loc = glGetFragDataLocation(pass_prog,"out_Normal");
GLint position_loc = glGetFragDataLocation(pass_prog,"out_Position");
GLint color_loc = glGetFragDataLocation(pass_prog,"out_Color");
GLenum draws [3];
draws[normal_loc] = GL_COLOR_ATTACHMENT0;
draws[position_loc] = GL_COLOR_ATTACHMENT1;
draws[color_loc] = GL_COLOR_ATTACHMENT2;
glDrawBuffers(3, draws);
glBindTexture(GL_TEXTURE_2D, depthTexture);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0);
glBindTexture(GL_TEXTURE_2D, normalTexture);
glFramebufferTexture(GL_FRAMEBUFFER, draws[normal_loc], normalTexture, 0);
glBindTexture(GL_TEXTURE_2D, positionTexture);
glFramebufferTexture(GL_FRAMEBUFFER, draws[position_loc], positionTexture, 0);
glBindTexture(GL_TEXTURE_2D, diffuseTexture);
glFramebufferTexture(GL_FRAMEBUFFER, draws[color_loc], diffuseTexture, 0);
check FBO status
FBOstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(FBOstatus != GL_FRAMEBUFFER_COMPLETE) {
printf("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO\n");
checkFramebufferStatus(FBOstatus);
}
switch back to window-system-provided framebuffer
glClear(GL_DEPTH_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
Edit: I solved it. Thanks.
You should do something like this. I assume that out_color is declared as out vec4 out_Color:
Compile shaders and attach them to the program.
glBindFragDataLocation(program, 0, "out_Color");
glLinkProgram(program);
glUseProgram(program);
GLenum drawBuffers[1] = { GL_COLOR_ATTACHMENT0 }
glDrawBuffers(1, drawBuffers);
Setup FBO.
The it should work, if it doesn't, post your fragment shader and more source code. By the way, i should also say that creating a deferred renderer to learn GLSL is not a good idea. There are easier ways to learn GLSL.
精彩评论