使用GLSL在纹理上覆盖透明色

时间:2015-06-16 00:07:42

标签: glsl lwjgl slick2d vertex-shader blending

我有一个使用Slick库加载的图像,图像呈现正常,而我的着色器不活动。当我使用着色器在图像上覆盖透明色时,整个图像将被透明色替换。

没有着色器的

使用着色器

顶点着色器

varying vec4 vertColor;

void main(){
    vec4 posMat = gl_Vertex;
    gl_Position = gl_ModelViewProjectionMatrix * posMat;
    vertColor = vec4(0.5, 1.0, 1.0, 0.2);
}

片段着色器

varying vec4 vertColor;

void main(){
    gl_FragColor = vertColor;
}

精灵渲染代码

Color.white.bind();
GL11.glBindTexture(GL11.GL_TEXTURE, image.getTextureID());
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(this.x, this.y);
GL11.glTexCoord2f(1, 0);
GL11.glVertex2f(x + w, y);
GL11.glTexCoord2f(1, 1);
GL11.glVertex2f(x + w, y + h);
GL11.glTexCoord2f(0, 1);
GL11.glVertex2f(x, y + h);
GL11.glEnd();
GL11.glBindTexture(GL11.GL_TEXTURE, 0);

}

OpenGL初始化

GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, Screen.getW(), Screen.getH(), 0, -1, 1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

1 个答案:

答案 0 :(得分:1)

a)vertColor = vec4(0.5, 1.0, 1.0, 0.2); b)gl_FragColor = vertColor;

着色器完全符合您的要求 - 它将所有片段的颜色设置为该颜色。如果要混合颜色,则应以某种方式在着色器中添加/乘以它们(例如,使用颜色属性和/或纹理采样器,然后在将属性从顶点着色器导出到片段着色器后,使用{{1}等等。)

还要注意:您将固定功能管道与即时模式(gl_FragColor = vertexColor * textureColor * blendColor; / glBegin)混合使用着色器......这不是一个好主意。另外,我不知道你的制服在哪里设置;使用没有制服的着色器==要求麻烦。

IMO最好的解决方案是使用常规的OpenGL> = 3.1使用适当的兼容着色器等,或者只使用固定功能管道而不使用传统OpenGL的着色器。

<小时/> 至于如何使用GLSL加载纹理:(如果需要,请参阅https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/texturing.php了解更多信息)

a)您通过创建纹理和数据将数据提供给GPU。通过调用

将其绑定到GPU纹理单元
glEnd

(我认为你已经完成了,因为你已经使用int id = glGenTexture(); glBindTexture( GL_TEXTURE_2D, id ); glTexImage2D( ... ); // see https://www.opengl.org/sdk/docs/man/html/glTexImage2D.xhtml for details 使用了图片参数)

b)为几何提供UV纹理坐标;您已经通过提供glBindTexture来完成此操作,这可能允许您使用https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/attributes.php中的旧版属性名称,但正确的方法是将其作为打包属性的一部分传递结构,

c)您通过在着色器中对纹理进行采样来使用绑定纹理,例如: (传统GLSL紧随其后)

glTexCoord2f
// vertex shader
varying vec2 vTexCoord;

void main() {
   vTexCoord = gl_MultiTexCoord0;
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

但是,如果您打算在运行时更改它,最好将colorMultiplier作为制服传递。