0
votes

I have a frame buffer with two textures attached, and the read calls:

Occlusion = texture2D(OcclusionTexture, TexCoord);
FragColor = texture2D(ColourTexture, TexCoord);

Return the same thing. They return the data that resides in the texture OcclusionTexture. Any help please, sorry for the wall of code.

Shader Code: Attachments

 subroutine void RenderPassType();
    subroutine uniform RenderPassType RenderPass;

    uniform sampler2D ColourTexture;
    uniform sampler2D OcclusionTexture;
    layout(location = 0) out vec4 FragColor; // Actual fragment colour;
    layout(location = 1) out vec3 OutColour;
    layout(location = 2) out vec3 OcclusionColour;

Writing and reading

    subroutine (RenderPassType) void Write()
    {
        // Writing
        OcclusionColour = vec3(m_Light[0].Intensity);
        OutColour = vec3(ApplyFog(ViewPos, Colour, fogColour,                   fogDistance)); 
    } 

    subroutine (RenderPassType) void Read()
    {
        // Reading
        vec4 Occlusion = texture2D(OcclusionTexture, TexCoord);
        FragColor = texture2D(ColourTexture, TexCoord);
    }

Code for generating the frame buffer and texture:

// Create and bind the FBO
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);

// The depth buffer
glGenRenderbuffers(1, &DepthBuff);
glBindRenderbuffer(GL_RENDERBUFFER, DepthBuff);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 
    settings::GameSettings::GetSingleton()->Screen.x, settings::GameSettings::GetSingleton()->Screen.y);

// The color buffer
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &ScreenTex);
glBindTexture(GL_TEXTURE_2D, ScreenTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, settings::GameSettings::GetSingleton()->Screen.x
    , settings::GameSettings::GetSingleton()->Screen.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

// The occlusion buffer
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &OcclusionTex);
glBindTexture(GL_TEXTURE_2D, OcclusionTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, settings::GameSettings::GetSingleton()->Screen.x
    , settings::GameSettings::GetSingleton()->Screen.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

// Attach the images to the framebuffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, DepthBuff);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ScreenTex, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, OcclusionTex, 0);

GLenum drawBuffers[] = { GL_NONE, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};

glDrawBuffers(3, drawBuffers);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

SetUniform("ColourTexture", ScreenTex);
SetUniform("OcclusionTexture", OcclusionTex);

////////////////////////////////////////////////////// EDIT //////////////////////////////////////////////////////

First pass I render the scene to the textures. In the second pass I only read from the textures and do volumetric lighting calculations and then push the final frag colour out to attachment 0.

2
You cannot read and write a texture at the same time. If this is not what you are doing here, then please mark clearly which code lines belong to which shader invocation. - BDL
No render pass one I right to the texture, render pass 2 I read from the texture. - Student123
How is SetUniform implemented? - BDL
void Shader::SetUniform(char* string, int type) { GLuint varLocation = glGetUniformLocation(m_shaderProgramHandle, string); glUniform1iv(varLocation, 1, &type); } - Student123
Then the problem is exactly what @dari wrote in hist answer - BDL

2 Answers

3
votes

Your texture binding is wrong. It should look something like this:

SetUniform("ColourTexture", 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, ScreenTex);

SetUniform("OcclusionTexture", 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, OcclusionTex);
//draw stuff

Note: The important part is here, that the number of the active texture unit is passed to the uniform and not the texture id.

-1
votes

The problem with the textures is that I was binding and unbinding the shader program.

glUseProgram(m_shaderProgramHandle); //bind program
glUseProgram(0); //unbind a program

The textures were only bound to their texture units when the shader was initiated, because the shader was being unbound it was also unbinding the texture units. The fix was:

void StandardLightingShader::Begin() 
{
    glUseProgram(m_shaderProgramHandle);

    // Set up Pass
    glBindFramebuffer(GL_FRAMEBUFFER, FBO);
    glEnable(GL_DEPTH_TEST);
    glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &pass1Index);
    SetUniform("ScreenSize", settings::GameSettings::GetSingleton()->Screen);
    SetUniform("ScreenOffSet", settings::GameSettings::GetSingleton()->ScreenPosition);

    // Bind the textures to texture units.
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, ScreenTex);

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

}

So basically if you unbind your program you need to rebind your textures to texture units, BUT the actual uniform variables will persist through shader change.

SetUniform("ColourTexture", 0);