GLSL:渲染 2D 纹理

GLSL: Rendering a 2D texture

本文关键字:纹理 2D 渲染 GLSL      更新时间:2023-10-16

我正在学习LazyFoo关于GLSL 2D纹理(http://lazyfoo.net/tutorials/OpenGL/34_glsl_texturing/index.php)的教程,我能够让大多数部件工作。

但是,该程序会渲染放大的纹理。这是顶点或纹理查找的问题吗?下面是我在实现中使用的顶点着色器:

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

下面是我正在使用的片段着色器:

gl_FragColor = texture( textureID, texCoord );

至于渲染函数,我偏离了教程,使用了opengl的固定流水线矩阵(不需要更新矩阵):

//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

    }
}

为了响应 Koradi,顶点和纹理坐标实例化如下:

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 );
}

它使用以下代码在主循环中呈现:

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

我是否忽略了什么明显的东西?我是GLSL的新手。

编辑:添加了更多代码

经过几天的思考,问题在于如何将sampler2D制服发送到GLSL中:

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

已更正为:

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

setTextureID() 设置 sampler2D 统一变量。绑定纹理后,采样器2D 制服应设置为 0,而不是纹理地址。