Java GLSL中未出现纹理的可能原因是什么?
我正在学习如何将纹理与GLSL(在LWJGL中)结合使用,以创建一个简单的片段着色器来模糊纹理。第一次尝试(出于测试目的)是一个非常简单的着色器,它只获取原始颜色值:Java GLSL中未出现纹理的可能原因是什么?,java,opengl,shader,glsl,lwjgl,Java,Opengl,Shader,Glsl,Lwjgl,我正在学习如何将纹理与GLSL(在LWJGL中)结合使用,以创建一个简单的片段着色器来模糊纹理。第一次尝试(出于测试目的)是一个非常简单的着色器,它只获取原始颜色值: uniform sampler2D rectTexture; void main(){ vec4 color = texture2D(rectTexture, gl_FragCoord.st); gl_FragColor = color; } 着色器编译得很好。编译后,我链接并开始使用它,直到现在一切正常,没有错误报告
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)绘制一个四边形,但是纹理没有显示出来。纹理本身不是问题;我在没有片段着色器的第一个四边形旁边绘制了第二个四边形,它会如您所期望的那样显示。基本方法是从uniformTextureAddr
不是-1,如果我使用一个更简单的着色器,它只是将每个像素变为红色,我会得到一个红色的四元体。正如所料。因此,缺陷必须存在于整个业务中。这也排除了一些细微的错误,例如四边形超出了框架
是的,在不使用着色器绘制之后,我再次使用着色器调用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,即使它应该在那里。日志信息仍然只显示:
信息日志:
已成功编译片段着色器以在硬件上运行
更新2:
实际纹理是从backbuffer复制的。在较小的视口中绘制简单的白线,然后复制到纹理:
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();
您是否也在使用顶点着色器?有些卡片要求您同时提供顶点和片段着色器。您提供的是纹理坐标,但在着色器中不使用它们。相反,您使用的是gl_FragCoord,它为您提供窗口坐标:
texture2D(rectTexture, gl_FragCoord.st)
您应该使用gl\u MultiTexCoord0.xy。因为您使用gl\u TEXTURE\u 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_纹理_最小_过滤器、GL_纹理_贴图过滤器、GL_纹理_包裹和GL_纹理_包裹
如果没有,大多数opengl驱动程序将为着色器提供rgba=[0,0,0,0]颜色
请参阅
以下配置适用于大多数GL_纹理_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 );
希望这有帮助。不,我没有使用顶点着色器。但我不认为这是问题所在,因为我也没有将顶点着色器与另一个只将像素变为红色的着色器一起使用,这很有效。我相信你至少应该尝试使用一个简单的顶点着色器,问题可能是纹理坐标没有从固定函数正确传递(驱动程序错误),检查这一点的唯一方法是使用顶点着色器。此外,顶点着色器应沿顶点位置传递纹理坐标。关于更新,这不是问题,GLSL编译器通常会优化未使用的变量,情况就是这样。您可以发布纹理加载代码和绘制代码吗?我已添加了您要求的信息。注释字段太长,所以我只是编辑了我的问题。关于您的第一次更新,这是正常的,大多数GLSL编译器会优化掉未使用的变量,您没有使用secondTexture,因此它被删除。