Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attribute Variable not found in OpenGL, possible optimization

I'm currently working in a deferred shading and I created a class which manages the FBOs and draw the buffers on the screen.

This is how it looks so far:

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 those 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 problems is that when I try to set the attribute variables the one called uvCoord is not found. I think this may be due to an optimization, however, if that's so, what am I'm doing wrong or how should I do it? The uvCoord is used in the fragment shader.

like image 201
pceccon Avatar asked Jun 29 '26 07:06

pceccon


1 Answers

The uvCoord is used in the fragment shader.

No it is not. Your output is a constant color. As a result, the texture fetches before are all eliminated by a decent compiler, as is the texCoord varying. This ultimately results in the elimination of the input attribute, which simply does not affect the output of the program in any way. This is allowed by the GL spec. Your attribute is just not considered active, but only active attributes have locations.

like image 193
derhass Avatar answered Jul 01 '26 13:07

derhass



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!