I have a shader 1 depth map texture attached to it.
glGenFramebuffers(1, &depthMapFrameBuffer);
glGenTextures(1, &depthMapTexture);
glBindTexture(GL_TEXTURE_2D, depthMapTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,depthMapTextureSize, depthMapTextureSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFrameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMapTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
App::checkFrameBufferError(__FILE__,__LINE__);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
std::cerr << "Framebuffer not complete!" << std::endl;
}
Scene::debugTextures[5] = depthMapTexture;
#version 400 core
layout (location = 0) in vec3 ModelSpaceVertexPosition;
uniform mat4 LightSpaceMatrix;
uniform mat4 ModelMatrix;
uniform mat4 CameraSpaceTransformMatrix;
//uniform mat4 CameraSpaceScaleMatrix;
void main(){
//todo bug here.. translate to sorun yok ama scale yara rotasyon olmussa camera space matrixi kayiyor. kameraya gore translate oluyorlar
gl_Position = LightSpaceMatrix * CameraSpaceTransformMatrix * ModelMatrix * vec4(ModelSpaceVertexPosition, 1.0);
}
Is it possible to have more than 1 depth texture attached to different LightSpaceMatrixes in one shader?
Or should I do it in different frame buffers?
Instead of using the fixed function depth pipeline you could just attach multiple depth maps as color attachments(using an explicitly typed texture format), then you can write various values to the different attachments from within the fragment shader.
However if you wanted to render multiple light sources or e.g. cascades in one go you'd need to transform the same vertex multiple times ... which requires more sophisticated techniques.
Related
I'm making a 3d game using OpenGL and I have encountered a problem I can't find the answer to. For some reason, when I load the textures it is still interpolated.
My image loading:
glGenTextures(1, &chunkTex);
glBindTexture(GL_TEXTURE_2D, chunkTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
int width, height, chan;
stbi_set_flip_vertically_on_load(true);
unsigned char *data = stbi_load("res/images/atlas.png", &width, &height, &chan, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
data);
glGenerateMipmap(GL_TEXTURE_2D);
} else {
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
My vertex shader:
#version 330 core
in vec3 aPos;
in vec3 aColor;
in vec3 aNormal;
in vec2 uv;
uniform mat4 mvp;
out vec3 ourColor;
out vec2 puv;
out vec3 pNormal;
void main()
{
gl_Position = mvp * vec4(aPos, 1.0);
ourColor = aColor;
puv = uv;
pNormal = aNormal;
}
My fragment shader:
#version 330 core
out vec4 col;
in vec3 ourColor;
in vec2 puv;
in vec3 pNormal;
uniform sampler2D tex;
uniform vec3 lightDir;
void main()
{
col = texture(tex, puv) * max(dot(pNormal, -lightDir), 0.1);
}
If you could help me fix this I would appreciate it!
Edit: Here are my window hints:
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
Here you create a nex texture object and set the texture parameters for it:
glGenTextures(1, &chunkTex);
glBindTexture(GL_TEXTURE_2D, chunkTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
But here you unbind it and bind texture object 0 instead:
glBindTexture(GL_TEXTURE_2D, 0);
and load the texture image to that one:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
Now, in legacy and compatibility profile GL, texture object 0 even exists (actually, there even do exist different texture objects named 0 for different texture types), and is usable. But for that one, you never have set the texture filters and will use the default ones. And it looks like you keep textur eobject 0 bound also for rendering, and not the (empty and incomplete) chunkTex one.
I am trying to create a depth map in OpenGL and for some reason the framebuffer wont write to the texture, I tried multiple things to fix it but it doesn't seem to work.
Here is what I did:
This is the generation of the framebuffer and the texture:
glGenFramebuffers(1, &_DepthMapFBO);
glBindFramebuffer(GL_FRAMEBUFFER, _DepthMapFBO);
glGenTextures(1, &_DepthMapTex);
glBindTexture(GL_TEXTURE_2D, _DepthMapTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, DEPTH_TEXTURE_WIDTH, DEPTH_TEXTURE_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _DepthMapTex, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, _DepthMapTex, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
(In the above I tried replacing glTexImage2D with glTexStorage2D and I tried replace glFramebufferTexture with glFramebufferTexture2D, both didn't work)
Then (There is stuff before this but they work find, I checked) I rendered the framebuffer as follows:
_DepthProgram.Use();
// Setting uniforms here
glViewport(0, 0, DEPTH_TEXTURE_WIDTH, DEPTH_TEXTURE_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, _DepthMapFBO);
glClear(GL_DEPTH_BUFFER_BIT);
// Rendering the scene here
glBindFramebuffer(GL_FRAMEBUFFER, 0);
These are the shaders I use:
(Vertex)
#version 410 core
layout(location = 0) in vec3 Position;
uniform mat4 LightSpaceMatrix;
uniform mat4 Model;
void main()
{
gl_Position = LightSpaceMatrix * Model * vec4(Position, 1.0);
}
(Fragment)
#version 410 core
void main()
{
// gl_FragDepth = 0.0;
}
I tried rendering the texture to a plane and it came out totally white (I Checked there was supposed to be other values), As you can see in the fragment shader, I tried to explicitly write to the gl_FragDepth but it didn't change the texture, it kept it white (1.0).
I looked all over the internet and looked at learnopengl.com and everybody seem to be doing the same as me, did I miss something?
(I double checked and I am rendering the texture to the plane right, I replaced the glBindTexture with another one and it rendered the texture)
If I am missing some information please let me know.
EDIT: By the way, I don't get any error with glGetError.
I am having trouble viewing depth rendered to a texture. I can view it when I render depth as RGB to texture, but when I try to render depth only I get only black. I have searched for many hours and implemented fixes from other similar questions, but to no avail. I've disabled GL_TEXTURE_COMPARE_MODE, added glDrawBuffer(GL_NONE) and glReadBuffer(GL_NONE).
I'm running on OSX 10.9 and OpenGL 4.1. I've removed gl error checking from the pasted code for conciseness.
The setup for the depth FBO/texture is this:
glGenFramebuffers(1, &FramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glGenTextures(1, &renderedTexture);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glTexImage2D(GL_TEXTURE_2D, 0,
GL_DEPTH_COMPONENT,
fbWidth,
fbHeight,
0,
GL_DEPTH_COMPONENT,
GL_FLOAT,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
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_COMPARE_FUNC, GL_LEQUAL);
// glTexParameteri (GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, renderedTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
assert(false && "framebuffer NOT OK");
depth fragment - I can see depth when rendering RGB
#version 150 core
#if RENDER_RGB
out vec4 outColor;
void main(){
vec3 color = gl_FragCoord.z);
outColor = vec4(color, 1.0);
}
#else
void main(){
gl_FragDepth = gl_FragCoord.z;
}
#endif
Reading back the depth texture, I am using this fragment shader:
#version 150 core
in vec2 UV;
uniform sampler2D renderedTexture;
out vec4 outColor;
void main(){
vec3 color = vec3( texture(renderedTexture, UV).r );
outColor = vec4(color, 1.0);
}
Nevermind, it does work! My problem was the depth-only FBO setup for the depth texture was never called.
I've been trying to add SSAO (based on the tutorial here: http://john-chapman-graphics.blogspot.co.nz/2013/01/ssao-tutorial.html) to a project of mine and I've gotten stuck on rendering the depth correctly.
I have created a framebuffer texture to draw the depth to each frame. The texture itself looks correct when I draw it to a quad but I can't figure out how to correctly apply it to the whole scene.
Here's what the regular scene looks like:
And here's the applied depth texture:
Currently in my fragment shader I just use my regular texture coordinates (TexCoord0) to draw the depth texture. I'm guessing I need to change this but I don't have a clue what to change it to.
Here's the relevant fragment shader code:
#version 330 core
in vec2 TexCoord0;
smooth in vec3 vNormal;
smooth in vec3 vWorldPos;
in mat4 ProjectionMatrix;
uniform sampler2D uDepthTex;
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = texture(uDepthTex, TexCoord0);
}
I'm at a bit of a loss as to how to fix this. I've read a lot of sample code online which seems to use regular texture coordinates to draw the depth.
EDIT:
Here's my framebuffer setup code:
glGenFramebuffers(1, &ssaoFramebufferID);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFramebufferID);
glGenTextures(1, &ssaoDepthTextureID);
glBindTexture(GL_TEXTURE_2D, ssaoDepthTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
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);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, ssaoDepthTextureID, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
And the depth pass code I call each frame before regular draw:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFramebufferID);
glViewport(0, 0, 1024, 1024);
depthShader.Bind();
depthShader.SetUniformMatrixfv("depthMVP", camera.GetViewMatrix() * Matrix4::Perspective(60, aspectRatio, 0.1f, 10.0f));
DrawScene(true);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, width, height);
My depth shaders, vertex:
#version 330 core
layout(location = 0) in vec3 Position;
uniform mat4 depthMVP;
void main() {
gl_Position = depthMVP * vec4(Position, 1.0);
}
fragment:
#version 330 core
layout(location = 0) out float fragmentdepth;
void main() {
fragmentdepth = gl_FragCoord.z;
}
EDIT2:
The glClear call where it currently is gives me a completely black texture. Putting it below the first glViewport call gives the depth image I displayed above though:
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFramebufferID);
glViewport(0, 0, 1024, 1024);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
I managed to get it working thanks to some help in the comments:
My code is now as follows, fragment shader:
#version 330 core
in vec2 TexCoord0;
smooth in vec3 vNormal;
smooth in vec3 vWorldPos;
in mat4 ProjectionMatrix;
uniform sampler2D uDepthTex;
uniform float uWidth;
uniform float uHeight;
layout(location = 0) out vec4 FragColor;
void main()
{
vec2 res = gl_FragCoord.xy / vec2(uWidth, uHeight);
FragColor = texture(uDepthTex, res);
}
Framebuffer creation:
glGenFramebuffers(1, &ssaoFramebufferID);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFramebufferID);
glGenTextures(1, &ssaoDepthTextureID);
glBindTexture(GL_TEXTURE_2D, ssaoDepthTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 768, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
Depth draw code:
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFramebufferID);
glViewport(0, 0, 1024, 768);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
depthShader.Bind();
glDisable(GL_ALPHA_TEST);
depthShader.SetUniformMatrixfv("depthMVP", Matrix4::Perspective(60, aspectRatio, 0.1f, 10.0f) * camera.GetViewMatrix());
DrawScene();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, width, height);
glEnable(GL_ALPHA_TEST);
I've been stuck with this problem for about four days now. I'm trying to get my geometry to rendered into an FBO (G-buffer) with three textures (albedo, normal, depth). So far, I've 'somewhat' implemented MRT functionality, but when I use gDEBugger to inspect the textures, they just appear black. No matter what I change, they result in solid black. The actual values outputted are correct, I checked by disabling MRT to make the fragment shader output to back buffer. The textures are being initialized properly, gDEBugger properly displays the parameters I have put for them. But they all just have a solid black (0, 0, 0, 255) fill.
There's hardly any elaborate information on MRTs for GLSL 3.30. I've relied entirely on answered questions here, along with the OpenGL/GLSL docs and tutorials across the web (outdated, but I updated the code). I've probably spent a full day looking for a solution for this problem on Google. If there's something wrong with the ordering of the code, or syntax, please point it out. I don't even know if this implementation is correct anymore...
I'm using Visual C++ 2010, OpenGL 3.30 and GLSL 3.30 (as said in the title). For my libraries, GLFW 3.0 is being used for the windows, input, and OpenGL context, and GLEW 1.10.0 for extensions.
Keep in mind that all of this code is taken from my wrapper class. The ordering of the code is how it is all run at runtime (in other words, it's like as if I didn't have a wrapper class, and all of the code was in main ()).
Initialization Stage
// Initialize textures
glGenTextures (3, tex_ids);
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, tex_ids[0]); // Diffuse
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);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB8, res.x, res.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glBindTexture (GL_TEXTURE_2D, tex_ids[1]); // Normal
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf (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);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB8, res.x, res.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glBindTexture (GL_TEXTURE_2D, tex_ids[2]); // Depth
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf (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);
glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, res.x, res.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glBindTexture (GL_TEXTURE_2D, 0);
glDisable (GL_TEXTURE_2D);
// Initialize FBO
glEnable (GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex_ids[0]);
glFramebufferTexture2D ( GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
tex_ids[0],
0 ); // diffuse
glBindTexture(GL_TEXTURE_2D, tex_ids[1]);
glFramebufferTexture2D ( GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT1,
GL_TEXTURE_2D,
tex_ids[1],
0 ); // normal
glBindTexture(GL_TEXTURE_2D, tex_ids[2]);
glFramebufferTexture2D ( GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D,
tex_ids[2], 0 ); // depth
glBindFramebuffer (GL_FRAMEBUFFER, 0);
glDisable (GL_TEXTURE_2D);
// Initialize shaders
// Snipped out irrelevant code relating to getting shader source & compiling shaders
glBindFragDataLocation (renderer_1prog, GL_COLOR_ATTACHMENT0, "diffuse_out");
glBindFragDataLocation (renderer_1prog, GL_COLOR_ATTACHMENT1, "normal_out");
glBindFragDataLocation (renderer_1prog, GL_DEPTH_ATTACHMENT, "depth_out");
// More snipped out code relating to linking programs and finalizing
Draw Stage - called on every frame
// Bind everything
glUseProgram (renderer_1prog);
glBindFramebuffer (GL_DRAW_FRAMEBUFFER, fbo_id);
GLenum targ [3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_DEPTH_ATTACHMENT };
glDrawBuffers (3, targ);
// Draw mesh
glEnable (GL_CULL_FACE);
glEnable (GL_DEPTH_TEST);
teshmesh.draw ();
// Unbind fbo
glDisable (GL_CULL_FACE);
glDisable (GL_DEPTH_TEST);
glBindFramebuffer (GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0);
Vertex Shader
#version 330
layout(location = 0)in vec4 v;
layout(location = 1)in vec3 c;
layout(location = 2)in vec3 n;
out vec4 pos;
out vec3 col;
out vec3 nrm;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 world;
void main () {
gl_Position = projection * view * world * v;
pos = view * world * v;
pos.z = -pos.z / 500.0;
col = c.xyz;
nrm = n;
}
Fragment Shader
#version 330
in vec3 col;
in vec3 nrm;
in vec4 pos;
layout(location = 0) out vec3 diffuse_out;
layout(location = 1) out vec3 normal_out;
layout(location = 2) out vec3 depth_out;
out vec3 o;
void main () {
diffuse_out = col;
normal_out = (nrm / 2.0) + 0.5;
depth_out = vec3 (pos.z, pos.z, pos.z);
}
There are a few problems here. Starting with the smallest:
glBindFragDataLocation (renderer_1prog, GL_COLOR_ATTACHMENT0, "diffuse_out");
glBindFragDataLocation (renderer_1prog, GL_COLOR_ATTACHMENT1, "normal_out");
glBindFragDataLocation (renderer_1prog, GL_DEPTH_ATTACHMENT, "depth_out");
These are pointless. You used layout(location) syntax in your shader to specify this, and that takes priority over OpenGL-provided location settings.
Also, these are wrong. You don't put the FBO buffer attachment name into the location; you put an index into the location. So even if you didn't use layout(location), this is simply incorrect. glBindFragDataLocation will emit an OpenGL error, since the location will most assuredly be larger than GL_MAX_DRAW_BUFFERS​.
Considering how many OpenGL errors your code should emit, I'm rather surprised that your use of gDEBugger didn't tell you about any of these.
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB8, res.x, res.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
GL_RGB8 is not one of the required image formats for render targets. Therefore, the implementation is not required to support it; it may but it doesn't have to. And since you never bothered to check the completeness of the FBO (FYI: you should always do that), you didn't test that this combination of formats is valid.
Never render to a 3-component image. Pick 4, 2, or 1 instead.
GLenum targ [3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_DEPTH_ATTACHMENT };
glDrawBuffers (3, targ);
This is probably your main problem: your glDrawBuffers call fails. glDrawBuffers sets the color buffer outputs. The depth buffer is not a color buffer. There's only one depth buffer, so there's no need to set it.
To write to the depth buffer... well, you shouldn't be writing a user-calculated value to the depth buffer. Just let the regular depth buffer writing handle it. But if you want to (and let me remind you again, you do not), you write to gl_FragDepth. That's what it's for.