Reputation: 107
I want to load two textures in my FBO, one texture contains a HDR image, and my first target is to "copy" the image from first texture to second (which is empty), and called 'DownSamplingTex'.
So I create FBO, load the texture I want to write in COLOR_ATTACHMENT_0, and bind it; then init my shader program and render a quad, with texture I want to read bound in GL_TEXTURE_0.
Then I unbind the FBO and bind 'DownSamplingTex', and draw a quad.
I don't know if the process is correct, the output I have is a black screen.
Here's the render code:
glBindFramebuffer(GL_FRAMEBUFFER, fboA);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
FBOtex->bind(); // Set read texture bound in GL_TEXTURE_0
glDrawBuffer(GL_COLOR_ATTACHMENT0); // draw to write texture (DownSamplingTex)
fboShad->bind(); // use program of FBO shader
fboShad->setUniformValue4f("MVP", glm::value_ptr(MVP)); // Shader attribute
drawQuad(); // Draw
fboShad->unbind();
FBOtex->unbind();
// Main FB rendering
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
fboShad->bind();
fboShad->setUniformValue4f("MVP", glm::value_ptr(MVP));
DownSamplingTex->bind();
drawQuad();
DownSamplingTex->unbind();
fboShad->unbind();
Vertex shader:
#version 420
in vec4 vUV;
in vec4 vVertex;
smooth out vec2 vTexCoord;
uniform mat4 MVP;
void main()
{
vTexCoord = vUV;
gl_Position = MVP*vVertex;
}
Fragment shader:
#version 420
smooth in vec2 vTexCoord;
layout(location = 0) out vec4 color;
layout(binding=0) uniform sampler2D texHDR;
void main(void)
{
color = texture(texHDR,vTexCoord);
}
Inside 'drawQuad()' I set vVertex value with glGetAttribLocation() and glVertexAttribPointer().
std::vector<GLfloat> quadVerts = {
-1, -1, 0, 0, 1,
-1, 1, 0, 0, 0,
1, 1, 0, 1, 0,
-1, -1, 0, 0, 1,
1, 1, 0, 2, 0,
1, -1, 0, 1, 1 };
GLuint quadVbo;
glGenBuffers(1, &quadVbo);
glBindBuffer(GL_ARRAY_BUFFER, quadVbo);
glBufferData(GL_ARRAY_BUFFER, 6*3*4, &quadVerts[0], GL_STATIC_DRAW);
GLuint vVertex = fboShad->getLocation("vVertex");
GLuint vUV = fboShad->getLocation("vUV");
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), NULL);
glEnableVertexAttribArray(vVertex);
glVertexAttribPointer(vVertex, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0);
glEnableVertexAttribArray(vUV);
glVertexAttribPointer(vUV, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (void*)(3 * sizeof(GLfloat)));
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(vVertex);
glDisableVertexAttribArray(vUV);
I don't know if the mistake is in the process, or maybe is not correct the use of attributes in fragment shader ( I suppose that 'layout(binding=1)', if you use shader with FBO bound, tooks GL_COLOR_ATTACHMENT_1 texture); or the use of 'vTexCoords' as the .xy values of vertex.
Upvotes: 2
Views: 4017
Reputation: 43319
I think you are confusing sampler bindings with fragment data output locations. While the two things can both be assigned using a layout (...)
qualifier, they are very different.
layout (location = X) out vec3 color
assigns the output color
to GL_COLOR_ATTACHMENT0 + X
layout (binding = Y) sampler2D texHDR
tells GLSL to use texture image unit GL_TEXTURE0 + Y
Your fragment shader only writes to a single output, so there is no actual reason to have multiple color attachments in this situation. You attach images to FBOs in order to write to them from a fragment shader, not to read from them as a texture. In fact, it is undefined behavior to read from a texture at the same time as it is attached to an FBO for writing without using special extensions (e.g. GL_NV_texture_barrier
).
#version 420
smooth in vec2 vTexCoord;
//out vec4 vFragColor;
layout(location=0) out vec3 color; // Fragment Data Output Location
layout(binding=0) uniform sampler2D texHDR; // Texture Image Unit Binding
void main(void)
{
//vFragColor = texture(textureMap, vTexCoord);
//color = vec4(1.0,0.5,0.5,0.5);
color = texture(texHDR,vTexCoord);
}
Now, the texture you want to read should be bound to GL_TEXTURE0
(this is the default unless you manually call glActiveTexture (...)
somehwere) and the texture you want to output to should be attached to your Framebuffer Object at GL_COLOR_ATTACHMENT0
.
The most important thing to keep in mind here is that the binding
and location
qualifiers are completely separate: Color Attachment 0 does not correspond to Texture Image Unit 0.
Upvotes: 1