1
votes

I'm trying to develop a GLSL shader that uses two sampler2Ds, but I'm having some issues.

Fragment shader:

varying vec4 v_color;
varying vec2 v_texCoord0;
uniform sampler2D u_texture;
uniform sampler2D my_second_texture;
void main() {
   vec4 original_color = texture2D(u_texture, v_texCoord0);
   gl_FragColor = original_color;
}

This shader should output an unaltered u_texture.

Drawing code:

spritebatch.begin();

spritebatch.setShader(my_shader);
my_shader.setUniformi("my_second_texture", 1);
Gdx.gl20.glActiveTexture(1);
my_second_texture.bind(1); //Around here is where things go wrong, I think...
Gdx.gl20.glActiveTexture(0);

Gdx.gl.glClearColor(bg_color.r, bg_color.g, bg_color.b, bg_color.a);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
spritebatch.setTransformMatrix(new Matrix4());
spritebatch.setColor(1, 1, 1, 1);
spritebatch.draw(my_first_texture, -960, -540, 1920, 1080, 0, 0, 1920, 1080, false, true);

spritebatch.end();

The result on the screen is my_second_texture stretched across the whole screen. The expected result is an unaltered my_first_texture on the screen. (For the curious: The ultimate goal is a palette swap shader.)

How can I make a shader that properly uses two sampler2Ds, using GLSL and LibGDX?

1
Where's your #version directive?genpfault
I didn't think it was necessary, I'm pretty new with shaders. Either way, putting a "#version 150" or a "#version 410" at the start doesn't change the end result for me.Will Tice
Rename the my_first_texture uniform to u_texture. github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/… Consider to base your shader on this shader github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/…Xoppa
@Xoppa: I made the change to u_texture, but I get the same result. My shader is largely the same as the shader you linked, I'm just discarding vertex color.Will Tice

1 Answers

4
votes

See https://www.opengl.org/sdk/docs/man/xhtml/glActiveTexture.xml

texture must be one of GL_TEXTUREi

In practice you can offset your unit with GL10.GL_TEXTURE0, e.g: Gdx.gl.glActiveTexture(GL10.GL_TEXTURE0 + unit); Note that Texture#bind(int unit); (where unit is zero based, so doesn't requires to offset using GL10.GL_TEXTURE0) will make the specified unit active. You don't have to call glActiveTexture prior to calling texture.bind(1);.

tl;dr:

...
spritebatch.setShader(my_shader);
my_second_texture.bind(1);
Gdx.gl.glActiveTexture(GL10.GL_TEXTURE0);
my_shader.setUniformi("my_second_texture", 1);
...