java - GLSL 中没有出现纹理的可能原因有哪些?

标签 java opengl shader glsl lwjgl

我正在学习如何将纹理与 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);

然后我只是用正常的纹理坐标(两个维度上都是 0.0f-1.0f)绘制一个四边形,但纹理没有显示。纹理本身不是问题,问题在于纹理本身。我在第一个四边形旁边绘制了第二个四边形,没有使用片段着色器,它按照您的预期显示。基本方法取自NeHe: GLSL - An IntroductionuniformTextureAddr 不是 -1,如果我使用更简单的着色器,它只会将每个像素变成红色,我会得到一个红色四边形。正如预期的那样。所以这个 bug 一定存在于整个 Sampler2D 业务中。诸如四边形超出框架之类的小错误也被排除在外。

是的,在不使用着色器进行绘制之后,我再次使用着色器调用 glUseProgramObject(programObj)。

顺便说一句,它在 Windows XP SP3 上运行,配有 ATI Radeon Catalyst 10.6 驱动程序和 LWJGL 版本 2.4.2。

更新:我认为程序本身可能有问题。当我向着色器添加另一个变量时:

uniform sampler2D secondTexture;
uniform sampler2D rectTexture;

void main(){
  vec4 color = texture2D(rectTexture, gl_FragCoord.st);
  gl_FragColor = color;
}

并调用glGetUniformLocationARB(programObject, "secondTexture");它只返回-1,即使它应该在那里。日志信息仍然只显示:

Info log: Fragment shader was successfully compiled to run on hardware.

更新2:

实际纹理是从后台缓冲区复制的。在较小的视口(viewport)中绘制一条简单的白线,然后复制到纹理:

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

但就像我说的,我不认为纹理是真正的问题,因为在没有我的自定义着色器的情况下,它在第二个四边形上显示得很好。另外,不用担心绑定(bind);这是程序中唯一的纹理,并且只在最开始绑定(bind)一次。

这是我的绘图代码:

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

最佳答案

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

texture2D(rectTexture, gl_FragCoord.st)

您应该使用gl_MultiTexCoord0.xy

关于java - GLSL 中没有出现纹理的可能原因有哪些?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3117185/

相关文章:

java - JTable 的问题,我可以添加到表中,但看不到所有行

java - Gradle 无法使用 useJUnitPlatform() 运行 JUnit 测试

java - InputStream 在 spring Controller 中关闭

c++ - 如何强制 QGLWidget 更新屏幕?

c# - 在离屏位图上应用像素着色器

opengl - GLSL -- 不推荐使用 texture1D,用什么代替?

unity3d - 如何在 Unity 3D 中编写自定义着色器来点亮特定像素或像素组?

java - SAXBuilder().build(InputStream) - 这会将整个文件读入内存吗?

opengl - OpenGL 的轻量级 UI 库

opengl - 这个纹理映射有什么问题?