Hi!
I am trying to make a feedback loop using a FBO with three textures attached to it, and a couple of shaders. But all I get is a black screen…
The idea is to render the “final texture” to the first two textures, one of them rotated and scaled. Then actually create the “final texture” with a mixture of the previous two, this done thanks to a GLSL program.
Here I initialize the GLSL program, the textures and the FBO. I also get the locations to the two textures. There seems to be no problem in this piece of code, I think.
void Initialization()
{
program_texture = LoadShader ("texture.vert", "texture.frag");
printProgramInfoLog (program_texture);
loc_tex[0] = glGetUniformLocation (program_texture, "tex_0");
loc_tex[1] = glGetUniformLocation (program_texture, "tex_1");
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
glGenTextures(1, &texture[1]);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
glGenTextures(1, &texture[2]);
glBindTexture(GL_TEXTURE_2D, texture[2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
glBindTexture (GL_TEXTURE_2D, 0);
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[0], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, texture[1], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, texture[2], 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Then, I render as follows:
void Rendering()
{
glUseProgram(0);
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
glDrawBuffer (GL_COLOR_ATTACHMENT0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, texture[2]);
glPushMatrix();
glScalef(scale, scale, 1.0);
glRotatef(angle, 0.0, 0.0, 1.0);
glColor3f(brightness, brightness, brightness);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
glEnd();
glPopMatrix();
glBindTexture (GL_TEXTURE_2D, 0);
glDrawBuffer (GL_COLOR_ATTACHMENT1);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, texture[2]);
glPushMatrix();
glColor3f (1.0, 1.0, 1.0);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
glEnd();
glPopMatrix();
glBindTexture (GL_TEXTURE_2D, 0);
glDrawBuffer (GL_COLOR_ATTACHMENT2);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glUseProgram (program_texture);
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, texture[0]);
glUniform1i (loc_tex[0], 0);
glActiveTexture (GL_TEXTURE1);
glBindTexture (GL_TEXTURE_2D, texture[1]);
glUniform1i (loc_tex[1], 1);
glPushMatrix();
glBegin(GL_QUADS);
glVertex2f (-1.0, -1.0);
glVertex2f (1.0, -1.0);
glVertex2f (1.0, 1.0);
glVertex2f (-1.0, 1.0);
glEnd();
glPopMatrix();
glUseProgram(0);
if (drawGen){ DrawGenerator(); drawGen = false; }
glBindFramebuffer (GL_FRAMEBUFFER, 0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBindTexture (GL_TEXTURE_2D, texture[2]);
glPushMatrix();
glColor3f (1.0, 1.0, 1.0);
glBegin(GL_QUADS);
glTexCoord2f (0.0, 0.0); glVertex2f (-1.0, -1.0);
glTexCoord2f (1.0, 0.0); glVertex2f (1.0, -1.0);
glTexCoord2f (1.0, 1.0); glVertex2f (1.0, 1.0);
glTexCoord2f (0.0, 1.0); glVertex2f (-1.0, 1.0);
glEnd();
glPopMatrix();
glBindTexture (GL_TEXTURE_2D, 0);
glfwSwapBuffers();
}
And the shaders are:
// Vertex shader
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_MultiTexCoord1;
gl_Position = gl_ProjectionMatrix*gl_Vertex;
}
// Fragment shader
uniform sampler2D tex_0;
uniform sampler2D tex_1;
void main()
{
vec4 color_0 = texture2D (tex_0, gl_TexCoord[0].st);
vec4 color_1 = texture2D (tex_1, gl_TexCoord[1].st);
gl_FragColor = 0.5*(color_0+color_1);
}
There is a call in the rendering to a function named DrawGenerator(), which is supposed to give a first input to the loop. If I comment out the line that calls the GLSL program and the next six lines then the generator gets drawn, so I guess the problem is related to GLSL.
Perhaps I am wrongly assuming that by drawing a quad it will get the colors as described in the fragment shader?
Can you help me, or tell me another way of achieving this effect?