Search code examples
javacolorslibgdxtextures

Libgdx change color of Texture at runtime


In a game made with libgdx I have a TextureAtlas in which I have stored all the TextureRegions for my Animations of the Player. The Player by default has a blue T-Shirt (for example). Now I would like to be able to have more then one Player and each should have another T-Shirt color. So basically, I want to replace the blue with red for the second Player and with green for the 3rd Player and so on. I am sure I can do this with PixMap but wouldn't. Because then I lose the advantage of the TextureAtlas(?). Is there another way to do this? Or do I need to have every "color version" as a TextureRegion in the TextureAtlas?

Another little question:
With Gimp (and maybe a few other programs) you can use color indexes for ".gif" files. This reduces the size of all your Textures by saving an index for every color in the file and then using this index to describe the pixels. So for every red pixel you would have a "1" instead of "#FF0000" and somewhere in the file you have a "1=#FF0000". If we then pack the ".gif" files with the color indexes inside a TextureAtlas, is the index then lost and it restores the default RGB colors or will that make problems?

Thanks a lot!


Solution

  • I faced the same Issue for generating weapon with random colors using the same texture.

    So I wrote this.
    Basically I make a pixmap of the texture you want to edit.

    Then you iterate over all of the pixels, while iterating I check for certain colors which are a part specific part of the texture. (I suggest using different shades of gray since the RGB is the same)

    Then when it is on a pixel where the color needs to be changed I grab a color for those pixel groups using a color picker method which is basically random which gets a color from a prefabbed color array,
    and then changes that specific pixel to the new color.

    /**
     * Requires a asset's textureName, and requires gray scale colors of the
     * parts
     * 
     * @param texturename
     * @param colorBlade
     * @param colorEdge
     * @param colorAffinity
     * @param colorGrip
     * @return
     */
    private static Texture genTexture(String texturename, int colorBlade,
            int colorEdge, int colorAffinity, int colorGrip, int colorExtra) {
        Texture tex = Game.res.getTexture(texturename);
    
        TextureData textureData = tex.getTextureData();
        textureData.prepare();
    
        Color tintBlade = chooseColor(mainColors);
        Color tintEdge = new Color(tintBlade.r + 0.1f, tintBlade.g + 0.1f,
                tintBlade.b + 0.1f, 1);
    
        Color tintAffinity = chooseColor(affinityColors);
        Color tintGrip;
        Color tintExtra = chooseColor(extraColors);
    
        boolean colorsAreSet = false;
    
        do {
            tintGrip = chooseColor(mainColors);
    
            if (tintAffinity != tintBlade && tintAffinity != tintGrip
                    && tintGrip != tintBlade) {
                colorsAreSet = true;
            }
        } while (!colorsAreSet);
    
        Pixmap pixmap = tex.getTextureData().consumePixmap();
    
        for (int y = 0; y < pixmap.getHeight(); y++) {
            for (int x = 0; x < pixmap.getWidth(); x++) {
    
                Color color = new Color();
                Color.rgba8888ToColor(color, pixmap.getPixel(x, y));
                int colorInt[] = getColorFromHex(color);
    
                if (colorInt[0] == colorBlade && colorInt[1] == colorBlade
                        && colorInt[2] == colorBlade) {
                    pixmap.setColor(tintBlade);
                    pixmap.fillRectangle(x, y, 1, 1);
                } else if (colorInt[0] == colorEdge && colorInt[1] == colorEdge
                        && colorInt[2] == colorEdge) {
                    pixmap.setColor(tintEdge);
                    pixmap.fillRectangle(x, y, 1, 1);
                } else if (colorInt[0] == colorAffinity
                        && colorInt[1] == colorAffinity
                        && colorInt[2] == colorAffinity) {
                    pixmap.setColor(tintAffinity);
                    pixmap.fillRectangle(x, y, 1, 1);
                } else if (colorInt[0] == colorGrip && colorInt[1] == colorGrip
                        && colorInt[2] == colorGrip) {
                    pixmap.setColor(tintGrip);
                    pixmap.fillRectangle(x, y, 1, 1);
                }
                else if (colorInt[0] == colorExtra && colorInt[1] == colorExtra
                    && colorInt[2] == colorExtra) {
                pixmap.setColor(tintExtra);
                pixmap.fillRectangle(x, y, 1, 1);
                }
            }
        }
    
        tex = new Texture(pixmap);
        textureData.disposePixmap();
        pixmap.dispose();
    
        return tex;
    }
    

    I hope this helps.
    Please don't just copy paste, try to rebuild this to suit your needs or you won't learn anything.