我正在关注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的新手。
编辑:添加了更多代码
答案 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,而不是纹理地址。