我正在学习如何使用GLSL(在LWJGL中)使用纹理来创建一个模糊纹理的简单片段着色器。第一次尝试(用于测试目的)是一个非常简单的着色器,它只采用原始颜色值:
uniform sampler2D rectTexture;
void main(){
vec4 color = texture2D(rectTexture, gl_FragCoord.st);
gl_FragColor = color;
}
着色器编译得很好。编译后我链接并开始使用它,直到这一切都正常工作,没有报告错误。然后我尝试为纹理设置统一变量:
uniformTextureAddr = ARBShaderObjects.glGetUniformLocationARB(programObject, "rectTexture");
ARBMultitexture.glActiveTextureARB(ARBMultitexture.GL_TEXTURE0_ARB);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
ARBShaderObjects.glUniform1iARB(uniformTextureAddr, 0);
然后我只用普通的texcoords绘制一个四边形(在两个维度上都是0.0f-1.0f),但纹理没有显示出来。纹理本身不是问题;我在第一个旁边绘制了第二个四边形而没有我的片段着色器,它会像你期望的那样显示出来。基本方法取自NeHe: GLSL - An Introduction。 uniformTextureAddr
不是-1,如果我使用更简单的着色器,它只是将每个像素变为红色,我得到一个红色的四边形。正如所料。所以bug必须在整个sampler2D业务中。琐碎的错误,例如四边形只是不在框架内,也被排除在外。
是的,在没有着色器绘图后,我再次使用着色器调用glUseProgramObject(programObj)。
顺便说一句,这是在带有ATI Radeon Catalyst 10.6驱动程序和LWJGL版本2.4.2的Windows XP SP3上运行。
更新:我认为程序本身可能有问题。当我向着色器添加另一个变量时:
uniform sampler2D secondTexture;
uniform sampler2D rectTexture;
void main(){
vec4 color = texture2D(rectTexture, gl_FragCoord.st);
gl_FragColor = color;
}
并调用glGetUniformLocationARB(programObject, "secondTexture");
它只返回-1,即使它应该在那里。日志信息仍然只说:
信息日志: 片段着色器已成功编译为在硬件上运行。
更新2:
从后备缓冲区复制实际纹理。在较小的视口中绘制一条简单的白线,然后将其复制到纹理:
GL11.glViewport(0, 0, 256, 256);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glColor3f(1.0f, 1.0f, 1.0f);
GL11.glBegin(GL11.GL_LINES);
GL11.glVertex3f(0.0f, 0.0f, 0.0f);
GL11.glVertex3f(256.0f, 256.0f, 0.0f);
GL11.glEnd();
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_LUMINANCE, 0, 0, 256, 256, 0);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
但就像我说的那样,我不认为纹理是实际问题,因为它在没有我的自定义着色器的情况下在第二个四边形上显示得很好。另外,不要担心绑定;这是程序中唯一的纹理,一开始只绑定一次。
这是我的绘图代码:
ARBShaderObjects.glUseProgramObjectARB(programObject);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0.0f, 1.0f);
GL11.glVertex3f(0.0f, 0.0f, 0.0f);
GL11.glTexCoord2f(1.0f, 1.0f);
GL11.glVertex3f(256.0f, 0.0f, 0.0f);
GL11.glTexCoord2f(1.0f, 0.0f);
GL11.glVertex3f(256.0f, 256.0f, 0.0f);
GL11.glTexCoord2f(0.0f, 0.0f);
GL11.glVertex3f(0.0f, 256.0f, 0.0f);
GL11.glEnd();
ARBShaderObjects.glUseProgramObjectARB(0);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0.0f, 1.0f);
GL11.glVertex3f(256.0f, 0.0f, 0.0f);
GL11.glTexCoord2f(1.0f, 1.0f);
GL11.glVertex3f(512.0f, 0.0f, 0.0f);
GL11.glTexCoord2f(1.0f, 0.0f);
GL11.glVertex3f(512.0f, 256.0f, 0.0f);
GL11.glTexCoord2f(0.0f, 0.0f);
GL11.glVertex3f(256.0f, 256.0f, 0.0f);
GL11.glEnd();
答案 0 :(得分:1)
您正在提供纹理坐标,但不在着色器中使用它们。相反,您使用的是gl_FragCoord,它为您提供了窗口坐标:
texture2D(rectTexture, gl_FragCoord.st)
您应该使用 gl_MultiTexCoord0.xy 。
答案 1 :(得分:1)
由于您使用GL_TEXTURE_2D存储rectTexture,因此采样器将期望标准化纹理坐标(即[0.0,1.0])。
因此,您的着色器应修改为:
uniform vec2 invTextureSize; // contains [1.0 / w, 1.0 / h];
uniform sampler2D rectTexture;
void main() {
vec4 color = texture2D( rectTexture, gl_FragCoord.st * invTextureSize.xy );
gl_FragColor = color;
}
此外,您需要为该纹理对象正确设置GL_TEXTURE_MIN_FILTER,GL_TEXTURE_MAG_FILTER,GL_TEXTURE_WRAP_S和GL_TEXTURE_WRAP_T。
如果没有,大多数opengl驱动程序将为着色器提供rgba = [0,0,0,0]颜色。
的参考资料以下配置适用于大多数GL_TEXTURE_2D对象
glTexParameter( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameter( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameter( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameter( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
希望这有帮助。
答案 2 :(得分:0)
您是否也在使用顶点着色器?有些卡要求您同时提供顶点和片段着色器。