LibGDX:使用Skin为ImageButton着色图片

6

你好,我想制作一个ImageButton,禁用图像应该被染成灰色。我使用皮肤和.json文件来定义它。有没有更好的方法来获得一个灰色的着色图像,而不是复制所有图像并将它们添加到texturepacker中?


我猜我误解了问题。你是在寻找某种灰度着色器对吧?(不是叠加或类似的效果) - bemeyer
抱歉,我不知道什么是GrayShader。我的目标是将禁用的图标变成灰色(我的图标是白色)。我想知道最好的方法(处理速度最快)。例如:AndroidStudio。 - user4959397
2个回答

3
你可以使用ImageButtonStyle对象,在禁用的按钮上设置色调,使用Skin类中的newDrawable(Drawable drawable, Color tint)方法。在代码中,它可能看起来像这样。请注意,我们已经使用纹理集初始化了Skin对象,其中包含我们的UI纹理。有关更多信息,请参见wiki
// 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);

3
我认为实现这个目标的最佳方式(甚至唯一的方式)是使用着色器。请注意,着色器是一个独立的主题,但一旦掌握或熟悉,可以赋予你的游戏许多酷炫的功能,如将图像变灰。
至于你的问题:首先需要的是能够影响你的图像(或者在我们的情况下,ImageButton)以一种使它们变成灰色的方式的着色器。幸运的是,这些着色器已经被其他人实现,作为对类似问题的回答。因此,如果我们从上面提取所需的着色器,我们有以下内容:

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;
}

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;
}

假设这些文件在您的assets文件夹中,我们可以创建一个ShaderProgram,它将编译并使用这些着色器:
ShaderProgram shader = new ShaderProgram(Gdx.files.internal("grey.vsh"), Gdx.files.internal("grey.fsh"));

现在我们可以扩展 ImageButton,以便在需要灰掉时使用 shader。 在此示例中,当单击 ImageButton 时,它会变灰(或变色):
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);
        }
    }
} 

这将产生以下结果。之前:

enter image description here

之后:

enter image description here

当你更好地理解了“着色器”(shaders)之后,你就可以构建适合自己需求的着色器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接