0
votes

I was following LazyFoo's tutorial on GLSL 2D texturing (http://lazyfoo.net/tutorials/OpenGL/34_glsl_texturing/index.php), and I was able to get most parts working.

However, the program renders the texture zoomed up real close. Is this an issue with the vertex, or the texture lookup? Below is the vertex shader I was using in my implementation:

texCoord = LTexCoord;  
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vec4( LVertexPos2D.x, LVertexPos2D.y, 0.0, 1.0 );

And below is the fragment shader I was using:

gl_FragColor = texture( textureID, texCoord );

As for the render function, I deviate from the tutorial by using opengl's fixed pipeline matrices (don't need to update matrices ):

//If the texture exists
    if( mTextureID != 0 )
    {
        //Texture coordinates
        GLfloat texTop = 0.f;
        GLfloat texBottom = (GLfloat)mImageHeight / (GLfloat)mTextureHeight;
        GLfloat texLeft = 0.f;
        GLfloat texRight = (GLfloat)mImageWidth / (GLfloat)mTextureWidth;

        //Vertex coordinates
        GLfloat quadWidth = mImageWidth;
        GLfloat quadHeight = mImageHeight;

        //Set vertex data
        LVertexData2D vData[ 4 ];

        //Texture coordinates
        vData[ 0 ].texCoord.s =  texLeft; vData[ 0 ].texCoord.t =    texTop;
        vData[ 1 ].texCoord.s = texRight; vData[ 1 ].texCoord.t =    texTop;
        vData[ 2 ].texCoord.s = texRight; vData[ 2 ].texCoord.t = texBottom;
        vData[ 3 ].texCoord.s =  texLeft; vData[ 3 ].texCoord.t = texBottom;

        //Vertex positions
        vData[ 0 ].position.x =       0.f; vData[ 0 ].position.y =        0.f;
        vData[ 1 ].position.x = quadWidth; vData[ 1 ].position.y =        0.f;
        vData[ 2 ].position.x = quadWidth; vData[ 2 ].position.y = quadHeight;
        vData[ 3 ].position.x =       0.f; vData[ 3 ].position.y = quadHeight;

        glEnable(GL_TEXTURE_2D);
        glBindTexture( GL_TEXTURE_2D, mTextureID );
        glContext.textureShader->bind();
        glContext.textureShader->setTextureID( mTextureID );
        glContext.textureShader->enableVertexPointer();
        glContext.textureShader->enableTexCoordPointer();
            glBindBuffer( GL_ARRAY_BUFFER, mVBOID );
            glBufferSubData( GL_ARRAY_BUFFER, 0, 4 * sizeof(LVertexData2D), vData );
            glContext.textureShader->setTexCoordPointer( sizeof(LVertexData2D), (GLvoid*)offsetof( LVertexData2D, texCoord ) );
            glContext.textureShader->setVertexPointer( sizeof(LVertexData2D), (GLvoid*)offsetof( LVertexData2D, position ) );
            glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mIBOID );
            glDrawElements( GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, NULL );
        glContext.textureShader->disableVertexPointer();
        glContext.textureShader->disableTexCoordPointer();
        glContext.textureShader->unbind();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindTexture( GL_TEXTURE_2D, NULL );
        glDisable(GL_TEXTURE_2D);         // disable texture 2d


    }
}

In response to Koradi, the vertex and texture coordinates are instantiated as such below:

void TextureShader::setVertexPointer( GLsizei stride, const GLvoid* data )
{
    glVertexAttribPointer( mVertexPosLocation, 2, GL_FLOAT, GL_FALSE, stride, data );
}
void TextureShader::setTexCoordPointer( GLsizei stride, const GLvoid* data )
{
    glVertexAttribPointer( mTexCoordLocation, 2, GL_FLOAT, GL_FALSE, stride, data );
}

It is rendered in the main loop with the following code:

glPushMatrix();
    glTranslatef( glContext.gFBOTexture->imageWidth() / -2.f, glContext.gFBOTexture->imageHeight() / -2.f, 0.f );
    glContext.gFBOTexture->render();
glPopMatrix();

Is there something obvious that I am overlooking? I am new to GLSL.

Edit: Added more code

1
Nothing can be said having your vertex shader only. Please provide all your OpenGL-related code. - lisyarus
Why do you use mImageWidth and mImageHeight as you use it? You seem to want some pixel-exact mapping here, but that assumes that your GL matrices are set up properly. Without seeing those, it is impossible to say what part of the texture actually ends up on screen. - derhass

1 Answers

0
votes

After mulling over it for a few days, the issue was with how to send sampler2D uniforms into GLSL:

glBindTexture( GL_TEXTURE_2D, mTextureID );
glContext.textureShader->bind();
glContext.textureShader->setTextureID( mTextureID );

was corrected to:

glBindTexture( GL_TEXTURE_2D, mTextureID );
glContext.textureShader->bind();
glContext.textureShader->setTextureID( 0 );

setTextureID() sets the sampler2D uniform variable. Once the texture is binded, the sampler2D uniform should be set to 0, not the texture address.