0

我正在学习如何使用带有 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 IntroductionuniformTextureAddr不是-1,如果我使用更简单的着色器,它只会将每个像素变成红色,我会得到一个红色四边形。正如预期的那样。所以这个错误必须存在于整个 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();
4

3 回答 3

1

您正在提供纹理坐标,但未在着色器中使用它们。相反,您使用的是 gl_FragCoord,它为您提供窗口坐标:

texture2D(rectTexture, gl_FragCoord.st)

您应该改用gl_MultiTexCoord0.xy

于 2011-02-07T22:58:25.000 回答
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] 颜色。

请看glTexParameter的参考

以下配置适用于大多数 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 );

希望这可以帮助。

于 2013-07-03T08:55:27.853 回答
0

你也在使用顶点着色器吗?有些卡要求您同时提供顶点和片段着色器。

于 2010-06-25T10:43:33.273 回答