LibGDX:用于皮肤的ImageButton的色调图像

Dar*_*ski 6 java json libgdx

您好我想制作一个ImageButton,禁用的图像应该是灰色的.我使用Skin和.json文件来定义它.是否有更好的方法来获得灰色的图像而不是复制所有图像并将它们添加到纹理包装器中?

ash*_*bar 3

I think the best way (or even the only way) to accomplish this is by using shaders. Notice that shaders is a whole subject on its own, but once mastered, or even acquainted with, can give your game many cool capabilities, like graying out images.

As to your question: The first things that are needed, are shaders that will affect your images (or, in our case, ImageButton) in a way that will tint them gray. Luckily, these shaders have been implemented by somebody else, as an answer to a similar question. So, if we extract the required shaders from the above, we have the following:

grey.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;
}
Run Code Online (Sandbox Code Playgroud)

grey.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;
}
Run Code Online (Sandbox Code Playgroud)

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"));
Run Code Online (Sandbox Code Playgroud)

Now we can extend ImageButton so that it'll use shader when we want it to be grey out. In this example, ImageButton is greyed out (or colored in) when it's clicked:

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);
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

This give the following results. Before:

在此输入图像描述

After:

在此输入图像描述

After you've better understood shaders, you can build your own to be specific for your needs.