GLSL:渲染2D纹理

时间:2014-11-18 14:17:14

标签: c++ opengl 2d glsl game-engine

我正在关注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的新手。

编辑:添加了更多代码

1 个答案:

答案 0 :(得分:0)

在考虑了几天之后,问题在于如何将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统一变量。纹理绑定后,sampler2D uniform应设置为0,而不是纹理地址。