Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending two textures to GLSL shader

Tags:

opengl

glsl

When sending two textures to my GLSL shader only one actually arrives. What is strange is the first texture I bind is used for both textures slots in my shader. This leads me to believe the way I am passing my textures in OpenGL is wrong. However, I am unable to track down the problem.

Here is the code where I configure the textures for use in my shader.

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


// Get uniforms
GLuint pass_3O  = glGetUniformLocation(blend_shader, "org");
GLuint pass_3B = glGetUniformLocation(blend_shader, "blur");

// Activate shaders
glUseProgram(blend_shader);


// Bind first texture 
glActiveTexture(GL_TEXTURE0 );
glBindTexture(GL_TEXTURE_2D, init_texture);

// Bind the second texture 
glActiveTexture(GL_TEXTURE1 );
glBindTexture(GL_TEXTURE_2D, third_texture);

// Assign index to 2d images
glUniform1i(pass_3O, 0);
glUniform1f(pass_3B, 1);

The code above is passing in two textures. The first is a 2D image of the first rendering pass of the 3D scene. The third is that same texture with x2 levels of blur added. This final stage is to blend them together for a poor mans bloom.

Here is the code where I am drawing both textures to the quad.

// Draw to quad
glBegin(GL_QUADS);
    glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f);
    glMultiTexCoord2f(GL_TEXTURE1, 0.0f, 0.0f);
    glVertex3f(-w_width/2.0,  -w_height/2.0, 0.5f);

    glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 1.0f);
    glMultiTexCoord2f(GL_TEXTURE1, 0.0f, 1.0f);
    glVertex3f(-w_width/2.0,   w_height/2.0, 0.5f);

    glMultiTexCoord2f(GL_TEXTURE0, 1.0f, 1.0f);
    glMultiTexCoord2f(GL_TEXTURE1, 1.0f, 1.0f);
    glVertex3f(w_width/2.0,    w_height/2.0, 0.5f);

    glMultiTexCoord2f(GL_TEXTURE0, 1.0f, 0.0f);
    glMultiTexCoord2f(GL_TEXTURE1, 1.0f, 0.0f);
    glVertex3f(w_width/2.0,   -w_height/2.0, 0.5f);
glEnd();
glFlush();
glPopAttrib();

// Unbind textures
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);

// Disable blend shader
glUseProgram(0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);

And here is the shader I am using to render the final image.

Vert

#version 120
void main()
{
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_TexCoord[1] = gl_MultiTexCoord1;
    gl_Position = ftransform();
}

Frag

#version 120
uniform sampler2D org;
uniform sampler2D blur;
void main()
{
    vec4 orig_clr = texture2D( org,  gl_TexCoord[0].st);
    vec4 blur_clr = texture2D( blur, gl_TexCoord[1].st );
    //gl_FragColor = orig_clr;
    gl_FragColor = blur_clr;
}

If I switch between the last two lines in the fragment shader I get the same exact results. The only way to change which texture gets render is to change the order in which I bind them.

For example, the following would finally pass me the blurred image. Once again, only getting one of the two images.

glActiveTexture(GL_TEXTURE0 );
glBindTexture(GL_TEXTURE_2D, third_texture);


glActiveTexture(GL_TEXTURE1 );
glBindTexture(GL_TEXTURE_2D, init_texture);

Any thoughts on what I am overlooking?

like image 938
Freddy Avatar asked May 11 '13 13:05

Freddy


1 Answers

Look at this code:

glUniform1i(pass_3O, 0);
glUniform1f(pass_3B, 1);

you have some small typo here, it should be glUniform1*i* instead of Uniform1*f* in the second call. The type must match that of the shader variable, so this call should just result in some error, leaving the uniform initialized at 0, which completely explains your results.

like image 144
derhass Avatar answered Sep 23 '22 01:09

derhass