Attribute variable not found in OpenGL, possible optimization

I am currently working in lazy shading and I have created a class that manages FBOs and draws buffers to the screen.

It looks like this:

FBORender::FBORender(float screenWidth, float screenHeight) :
    _screenWidth(screenWidth),
    _screenHeight(screenHeight),
    ProgramManager("defVertexShader.txt", "defFragShader.txt")
{
    CreateProgram();
    _vbo[0] = 0;
    _vbo[1] = 0;
    _vao = 0;
    BuildQuad();
    BuildVAO();


    glGenFramebuffers(1, &_fbo);
    glGenRenderbuffers(1, &_depthBuffer);

    // Bind the depth buffer
    glBindRenderbuffer(GL_RENDERBUFFER, _depthBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, (int)_screenWidth, (int)_screenHeight);

    // Generate and bind the texture for diffuse
    glGenTextures(1, &_diffuseBuffer);
    glBindTexture(GL_TEXTURE_2D, _diffuseBuffer);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)_screenWidth, (int)_screenWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, 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_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    // Generate and bind the texture for positions
    glGenTextures(1, &_positionBuffer);
    glBindTexture(GL_TEXTURE_2D, _positionBuffer);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, (int)_screenWidth, (int)_screenWidth, 0, GL_RGBA, 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_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    // Generate and bind the texture for normals
    glGenTextures(1, &_normalBuffer);
    glBindTexture(GL_TEXTURE_2D, _normalBuffer);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, (int)_screenWidth, (int)_screenWidth, 0, GL_RGBA, 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_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    // Bind the FBO so that the next operations will be bound to it.
    glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthBuffer);
    // Attach the textures to the FBO
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _diffuseBuffer, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, _positionBuffer, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, _normalBuffer, 0);

    GLenum fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
    {
        printf("DeferredLighting::Init: FrameBuffer incomplete: 0x%x\n", fboStatus);
        exit(1);
    }
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}


FBORender::~FBORender()
{
    glDeleteTextures(1, &_normalBuffer);
    glDeleteTextures(1, &_positionBuffer);
    glDeleteTextures(1, &_diffuseBuffer);
    glDeleteFramebuffers(1, &_fbo);

    glDeleteVertexArrays(1, &_vao);
    glDeleteBuffers(2, _vbo);
}


void FBORender::Start()
{
    // Bind the FBO and set the viewport to the proper size
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo);
    glViewport(0, 0, (int)_screenWidth, (int)_screenWidth);

    // Clear the render targets
    GLenum windowBuffClear[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
    glDrawBuffers(3, windowBuffClear);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    GLenum windowBuffOpaque[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
    glDrawBuffers(3, windowBuffOpaque);
}


void FBORender::Draw(const glm::mat4 &Projection, const glm::mat4 &ModelView)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    _ModelViewProjection = Projection * ModelView;
    _ModelView = ModelView;

    glDisable(GL_DEPTH_TEST);

    Bind();

    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, _normalBuffer);

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

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

    glBindVertexArray(_vao);
    LoadUniformVariables();
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

    UnBind();
}


void FBORender::Stop()
{
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}


void FBORender::BuildQuad()
{
    _coordinates[0] = 1.0f;
    _coordinates[1] = 1.0f;
    _coordinates[2] = 0.0f;
    _coordinates[3] = -1.0f;
    _coordinates[4] = 1.0f;
    _coordinates[5] = 0.0f;
    _coordinates[6] = 1.0;
    _coordinates[7] = -1.0f;
    _coordinates[8] = 0.0f;
    _coordinates[9] = -1.0f;
    _coordinates[10] = -1.0f;
    _coordinates[11] = 0.0f;

    _uv[0] = 1.0f;
    _uv[1] = 1.0f;
    _uv[2] = 0.0f;
    _uv[3] = 1.0f;
    _uv[4] = 1.0f;
    _uv[5] = 0.0f;
    _uv[6] = 0.0f;
    _uv[7] = 0.0f;
}


void FBORender::BuildVAO()
{
    // Generate and bind the vertex array object
    glGenVertexArrays(1, &_vao);
    glBindVertexArray(_vao);

    // Generate and bind the vertex buffer object
    glGenBuffers(2, _vbo);
    glBindBuffer(GL_ARRAY_BUFFER, _vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(float), _coordinates, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, _vbo[1]);
    glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(float), _uv, GL_STATIC_DRAW);

    LoadAttributeVariables();

    glBindVertexArray(0);
}


void FBORender::LoadUniformVariables()
{
    // OpenGL Matrices
    GLuint ModelViewProjection_location = glGetUniformLocation(GetProgramID(), "mvMatrix");
    glUniformMatrix4fv(ModelViewProjection_location, 1, GL_FALSE, glm::value_ptr(_ModelView));

    // Texture buffers
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, _diffuseBuffer);
    GLint Diffuse_location = glGetUniformLocation(GetProgramID(), "tDiffuse");
    glUniform1i(Diffuse_location, 0);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, _positionBuffer);
    GLint Position_location = glGetUniformLocation(GetProgramID(), "tPosition");
    glUniform1i(Position_location, 0);

    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, _normalBuffer);
    GLint Normal_location = glGetUniformLocation(GetProgramID(), "tNormals");
    glUniform1i(Normal_location, 0);
}


void FBORender::LoadAttributeVariables()
{
    // Vertex Attributes
    GLuint VertexPosition_location = glGetAttribLocation(GetProgramID(), "vPosition");
    glEnableVertexAttribArray(VertexPosition_location);
    glBindBuffer(GL_ARRAY_BUFFER, _vbo[0]);
    glVertexAttribPointer(VertexPosition_location, 3, GL_FLOAT, GL_FALSE, 0, 0);

    GLuint TextureCoord_Location = glGetAttribLocation(GetProgramID(), "uvCoord");
    printf("%d \n", TextureCoord_Location);
    glEnableVertexAttribArray(TextureCoord_Location);
    glBindBuffer(GL_ARRAY_BUFFER, _vbo[1]);
    glVertexAttribPointer(TextureCoord_Location, 2, GL_FLOAT, GL_FALSE, 0, 0);
}

      

And these are my shaders:

#version 410 core

uniform mat4 mvMatrix;

in vec4 vPosition;
in vec2 uvCoord;

smooth out vec2 texCoord;

void main(void) 
{
    texCoord = uvCoord;
    gl_Position = vPosition * mvMatrix;
}


#version 410 core

uniform sampler2D tDiffuse; 
uniform sampler2D tPosition;
uniform sampler2D tNormals;

in vec2 texCoord;

out vec4 fragColor;

void main( void )
{
    vec4 image = texture( tDiffuse, texCoord.st );
    vec4 position = texture( tPosition, texCoord.st );
    vec4 normal = texture( tNormals, texCoord.st );

    fragColor.xyz = vec3(0.5f, 0.5f, 0.5f);
}

      

The problem is that when trying to set attribute variables, one of them was uvCoord

not found. I think it might be optimization related, however, if so, what am I doing wrong or how should I go about doing it? uvCoord

used in the fragment shader.

+3


source to share


1 answer


The fragment shader uses uvCoord

.



No, it is not. Your exit is a constant color. As a result, texture fetching before that are all eliminated by a decent compiler, just like a variable texCoord

. This ultimately leads to the elimination of the input attribute, which does not affect the program output in any way. This is allowed by the GL specification. Your attribute is simply not considered active, but only active attributes have locations.

+5


source







All Articles