LibGDX: Shade Images for ImageButton usin a Skin

Hello, I want to make ImageButton, and the disabled image should be grayed out. I use Skin and a .json file to define it. Is there a better way to get a gray tinted image than to duplicate all the images and add them to the texturepacker?

+6
source share
2 answers

I think the best way (or even the only way) to achieve this is to use shaders . Please note that shaders is a separate topic, but once it is mastered or even familiar with you, it can give your game many interesting features, for example, to color images.

As for your question: the first things that are needed are shaders that will affect your images (or, in our case, ImageButton ) so that their shade is gray. Fortunately, these shaders were implemented by someone else as an answer to a similar question . So, if we extract the required shaders from the above, we have the following:

gray.vsh:

 attribute vec4 a_position; attribute vec4 a_color; attribute vec2 a_texCoord0; uniform mat4 u_projTrans; varying vec4 vColor; varying vec2 vTexCoord; void main() { vColor = a_color; vTexCoord = a_texCoord0; gl_Position = u_projTrans * a_position; } 

gray.fsh:

 #ifdef GL_ES #define LOWP lowp precision mediump float; #else #define LOWP #endif varying LOWP vec4 vColor; varying vec2 vTexCoord; uniform sampler2D u_texture; uniform float grayscale; void main() { vec4 texColor = texture2D(u_texture, vTexCoord); float gray = dot(texColor.rgb, vec3(0.96, 0.96, 0.96)); texColor.rgb = mix(vec3(gray), texColor.rgb, grayscale); gl_FragColor = texColor * vColor; } 

Assuming these files are in your assets folder, we can create a ShaderProgram that will compile and use these shaders:

 ShaderProgram shader = new ShaderProgram(Gdx.files.internal("grey.vsh"), Gdx.files.internal("grey.fsh")); 

Now we can extend ImageButton to use shader when we want it to be gray. In this example, the ImageButton is highlighted (or colored) when pressed:

 public class GreyedOutImageBtn extends ImageButton { private boolean isGreyedOut; // A flag that determines whther or not this should be greyed out public GreyedOutImageBtn(ImageButtonStyle style) { super(style); addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { // When clicked, toggle the grey effect Gdx.app.log("ClickListener", "Click"); setIsGreyedOut(!getIsGreyedOut()); } }); isGreyedOut = false; } public boolean getIsGreyedOut() { return isGreyedOut; } public void setIsGreyedOut(boolean isGreyedOut) { this.isGreyedOut = isGreyedOut; } @Override public void draw(Batch batch, float parentAlpha) { if (getIsGreyedOut()) { batch.end(); batch.setShader(shader); // Set our grey-out shader to the batch batch.begin(); super.draw(batch, parentAlpha); // Draw the image with the greyed out affect batch.setShader(null); // Remove shader from batch so that other images using the same batch won't be affected } else { // If not required to be grey-out, do normal drawing super.draw(batch, parentAlpha); } } } 

This gives the following results. Before:

enter image description here

After:

enter image description here

Once you have a better understanding of shaders , you can create your own to be specific to your needs.

+2
source

You can set the hue color on disabled buttons using the ImageButtonStyle object and use newDrawable (Drawable drawable, Color tint) from the Skin class.

In code, this may look a bit like this. Note that we initialized the Skin object using Texture Atlas, which contains our UI textures. See the wiki for more details.

 // Create the tint color. Notice we use LibGDX Color class Color tintColor = new Color(0.5f, 0.5f, 0.5f, 1f); ImageButton.ImageButtonStyle btnStyle = new ImageButton.ImageButtonStyle(); btnStyle.up = skin.getDrawable("my_button"); btnStyle.disabled = skin.newDrawable("my_button", tintColor); ImageButton myButton = new ImageButton(btnStyle); 
+1
source

All Articles