Need hint with Indicator

I was under the impression–false it would seem–that by using an AlphaMap, a Color and a BaseImage, I could colorize the base image by the defined color while the alpha map would effectively serve as a mask. That was my understanding. Which is wrong.

Is it possible to do it this way?

Right now using the default alpha map, color and overlay image isn’t very successful. It sort of work without an alpha map, but the color “overwrites” the base image and if I use an alpha map, the color isn’t visible at all. Looks like the alpha map is opaque I guess.

I’m not totally sure I understand what you’re trying to achieve, but here are some of the options you have available:

Colorizing an image (no mater what layer it is), is totally possible:

  1. Use a greyscale image.
  2. Call: element.getElementMaterial().setColor(“Color”, new ColorRGBA(1,0,0,0.4f));

Element being whatever portion of the indicator you are trying to colorize. The above would blend red into the greyscale image… play around with the alpha setting until it looks like you want it to.

Actually… after reading your post again… I think I get what you are trying to do. There are two answers… 1. No 2. Yes

The no answer is this: I actually know exactly how to do this (I’m currently colorizing portions of my characters which are a single mesh… eyes, skin tone, hair color, etc). I could add this functionality to the base shader, as I think it would be extremely useful for colorizing themes when I get around to putting together theme plugins.

The yes answer is this:

  1. Create a new Indicator class by, copying the existing source code and refactoring the name.
  2. Add another element between the background layer and the indicator.
  3. Modify the appropriate methods to apply the same image as the background to your new layer, use an alpha mask to only display the portions you want colored and then apply the color as I explained above.

It should take about 3 minutes to put together.

I’m not sure I completely understand the logic behind suggestion #2 because when I used an Alpha Map, I couldn’t get any color at all to show through. So, even if I put an element, double the indicator itself, my earlier results tell me it’ll still be opaque.

But this bring the question of: How is this supposed to work in the first place?

What is the relation of AlphaMap, BaseImage and Color if any? Are they even related or do they replace the others?

1. Use a greyscale image. 2. Call: element.getElementMaterial().setColor(“Color”, new ColorRGBA(1,0,0,0.4f));
I can't use this as it would colorize the whole image. Not really the standard definition of a progress bar. ;)

FYI, that’s how I do things right now. Don’t mind the texture names too much as I tried different things.
[java]
int width = app.getContext().getSettings().getWidth() / 2;
bar = new Indicator(screen, “ProgressBar”, new Vector2f(width - width / 2, 50f), new Vector2f(width, 30f), Indicator.Orientation.HORIZONTAL) {

        @Override
        public void onChange(float currentValue, float currentPercentage) {
            if (currentPercentage <= 0) {
                this.setIndicatorColor(ColorRGBA.Red);
            } else {
                float value = 0.01f * currentPercentage;
                ColorRGBA newColor = new ColorRGBA();
                newColor.interpolateNoAlpha(ColorRGBA.Red, ColorRGBA.Green, value);
                this.setIndicatorColor(newColor);
            }
        }
    };
    bar.setDisplayPercentage();
    bar.setMaxValue(1f);

// bar.setBaseImage("Interface/GUI/progressbar.png");
bar.setBaseImage("Interface/GUI/Common/Extras/indicator_round_ol_x.png");
bar.setAlphaMap("Interface/GUI/Common/Extras/indicator_round_am_x.png");
[/java]

Um… if I remember correctly… the base Image is behind the indicator.
You can also either use a color-based indicator or image-based indicator (the squishy part of the indicator)
And then you have an overlay image you can use put a glass effect over the indicator.

The alpha map reshapes the color-based indicator (squishy part), since the are nothing more than a quad-grid with a color applied to it (i.e. the are rectangular like all quads… the alpha map discards pixels to make it appear the shape drawn in white in your alpha map)

You can, however, tint any image by applying a color to the material of any element. For the best results, use a greyscale image and a semi-transparent color.

Other things you can do with them…

  • You saw the examples I put out in that vid that showed the indicator change colors based on %…
  • You can also use the gradient fill methods of the mesh to keep the colors constant (i.e. green to the right, red to the left… gradient filled).
  • I believe you can also apply semi-transparent gradient fills to elements with a default image.
  • The base custom mesh also allows you to apply individual colors to each vert (a total of 16) for multi-color gradient fills.

To access these methods… use the following:

element.getModel(). --and this will give you a list of the public methods associated with vertex color manipulation. The standard horizontal and vertical gradient fill methods are backwards at the moment! But, both only require you to pass in to ColorRGBAs… the other method requires you build the float buffer and pass that in.

Hopefully some of this info is helpful.

@madjack said: [java] bar.setBaseImage("Interface/GUI/Common/Extras/indicator_round_ol_x.png"); [/java]

Ok… the method you are calling here would set the background image… the image you are using is an overlay image… so you probably wouldn’t see the image in this case.

Lemme check the Indicator class for what is what… one sec…

Ok… the defaultImg param of the constructor is the overlay image-- glass effect, etc. (indicator_round_ol_x.png used above)
setBaseImage sets a background image for the indicator… like a frame or recessed box, etc, etc

And apparently, I removed the use of images as the indicator itself due to the issue I was having with the alpha map not resizing properly. Which basically means, I need to fix the f’ing indicator lol. Currently, all indicators (the squishy part) are color-based. There may have been another reason I removed this… however it is not hitting me atm.

EDIT: For the life of me, I can’t figure out why there isn’t a method for setting the overlay image after the fact. One more thing I need to update here.

EDIT 2: Actually… I can’t figure out why the F I would have chosen to pass in the overlay image /boggle. I may have a bit of work ahead of me with this one. The general functionality will not alter… however, how the visuals are defined/set need an overhaul.

@t0neg0d said: Ok... the method you are calling here would set the background image... the image you are using is an overlay image... so you probably wouldn't see the image in this case.
Maybe you don't remember but that's how it's setup in your Indicator.xml file. Just saying. :)
setBaseImage sets a background image for the indicator... like a frame or recessed box, etc, etc
Oh, ok. So an outline where the "inside" should be more or less full transparency.
And apparently, I removed the use of images as the indicator itself due to the issue I was having with the alpha map not resizing properly. Which basically means, I need to fix the f'ing indicator lol. Currently, all indicators (the squishy part) are color-based. There may have been another reason I removed this... however it is not hitting me atm.
I don't really mind that. What I wanted to do was use a red-to-green-colored-depending-on-percentage bar underneath a stylized mask/overlay. In short, the overlay would act like a window where only the part with transparency would show the colored bar, because at the end of the day a colored bar can only be a rectangle.

Okay…

I got it to work by passing the overlay I wanted to use directly into the Indicator’s constructor. Works like a charm that way except for one thing, it’s not working as a mask. So what’s black is rendered as black and not used as a mask and stopping from rendering anything. Question is, was that even considered as a feature? :smiley:

@madjack said: Okay...

I got it to work by passing the overlay I wanted to use directly into the Indicator’s constructor. Works like a charm that way except for one thing, it’s not working as a mask. So what’s black is rendered as black and not used as a mask and stopping from rendering anything. Question is, was that even considered as a feature? :smiley:

Um… nope? =)

use setAlphaMap to do what your trying here.

Here be a diagram of the elements involved and what they do:

That’s exactly what the question was. :stuck_out_tongue: So yeah, it’s good.

As I said previously, when I set an AlphaMap (which is a mask), I don’t get ANYTHING at all to show through.

Let’s take this from the start.

First of all, Common/Extras/indicator_am_x.png isn’t an AlphaMap. Both the white and the black and fully opaque. It won’t work. I copied that file and removed the white. That should now work as a mask, uhh AlphaMap. That copy is now named indicator_am_x2.png. The image used in the constructor is the one it should use by default, indicator_ol_x.png

Now. When I use the Indicator without an alpha, it works great except for the part where the colorized indicator is a rectangle and since the background image is a capsule, it doesn’t work. But that’s why the mask exists; to hide everything not transparent.

Or: if (alphaColorValue >= 255) discardPixel else drawPixel(pixelIntensity - transparency);

At this point, if I put an AlphaMap image, the Colored Indicator doesn’t even show. I do see the percentage go up, but no color. This isn’t actually 100% true. If both images (background + alpha map) are similarly shaped (!?), I have a bit of color that shows at the start. If I use two different kind of images, I get nothing at all.

That last part makes no sense at all. The only difference between the similar images and the not similar ones is the image’s actual size. indicator_ol_x and indicator_am_x are both 109x18 and the other set has completely different values: 109x18 and 720x50. This might explain why one will show a tiny bit of color while the other can’t/won’t? Nope. To test I resized the 720x50 to 109x18 and it remained the same: nothings goes through it. I’m at a loss to explain the behavior.

No need to say that this is confusing to say the least.

Here’s visual clue of what’s going on:

Without a mask:

With a mask (indicator files):

Hopefully that’ll help you find the cause of this. :slight_smile:

@madjack
Heyas you! Ok… I tried the following, and it seems to be working correctly.

[java]
Indicator ind = new Indicator(screen, “indicator”, new Vector2f(50,50), new Vector2f(300,20), Indicator.Orientation.HORIZONTAL) {
@Override
public void onChange(float currentValue, float currentPercentage) { }
};
ind.setBaseImage(screen.getStyle(“Window”).getString(“defaultImg”));
ind.setIndicatorColor(ColorRGBA.randomColor());
ind.setAlphaMap(screen.getStyle(“Indicator”).getString(“alphaImg”));
ind.setMaxValue(1f);
[/java]

I see the panel img in the background, the colored indicator shaped like the defined alpha map and the overlay default overlay img over that.

Is there a difference between what you are doing and what is above here?

EDIT: An alphamap is a gradient image between visible color and none visible color… reason being is this:

The alpha value is between 0.0 and 1.0, you can store up to 3 separate alpha maps in one image by reading out a single channels color and multiplying the final alpha channel of a particular frag by the alphamap channel you want to read out of… Sooo…

gl_FragColor.a *= alphaMap.r; // r being a value between 0.0 and 1.0 (or transparent and opaque)

For your original question:

@madjack said: I was under the impression--false it would seem--that by using an AlphaMap, a Color and a BaseImage, I could colorize the base image by the defined color while the alpha map would effectively serve as a mask. That was my understanding. Which is wrong.

Did you want the base image clipped as well? i.e. to act as the indicator? If the answer is yes, then what you originally wanted to do will be possible both using a stretched image or clipped image once I add back in image based indicators.

@madjack
Ok… been playing around with some updates to the indicator and remembered why I got rid of image-based indicators. They are not visually accurate (i.e. There is no 0%… and depending on the resize borders… the smallest size possible without looking silly can be rather large).

One of the things I don’t like about the current indicator is using an alphamap to crop the rectangle in has the same issue in reverse… 0% and 100% are outside of the visual range of the indicator.

Sooooo… solution time:
I’m adding a couple of methods to the current indicator to allow you to set padding on the indicator portion of the indicator and the overlay portion of the indicator. This way between the base image, indicator and overlay, you should be able to easily configure the indicator to look however you want.

I’ll also allow you to set the indicator to an image, however, I’m going to using clipping in place of scaling the image to avoid the problem stated above.

Between all of these options, you should be able to accomplish what you originally asked.

@madjack
Here is the latest additions:

setOverlayImage(String imgPath);
setIndicatorImage(String imgPath);
setIndicatorPadding(Vector4f padding);

Element has a new method as well:

setColorMap(String imgPath);

@t0neg0d said: Did you want the base image clipped as well? i.e. to act as the indicator?

Nope. Not at all. The way it’s shown in your little picture above should be the way it is. Background, color, alpha map/mask and an overlay with transparency. That last one I’m not using. The background does the same thing for me as the overlay or maybe I should switch and use my background as an overlay. I shall try that.

@t0neg0d said: I remembered why I got rid of image-based indicators. They are not visually accurate (i.e. There is no 0%... and depending on the resize borders... the smallest size possible without looking silly can be rather large).

I have no idea if I’m getting this right, but what I’m understanding is that to use an image-based indicator you’re having problem with resizing? It can’t be too small because it looks crap? Might I suggest you don’t resize it down at all? Only up if needed? Then simply move the image to the right as the value increases, making sure anything “below 0” is clipped. That would work. It does in my head anyway. :wink:

One of the things I don't like about the current indicator is using an alphamap to crop the rectangle in has the same issue in reverse... 0% and 100% are outside of the visual range of the indicator.
Not sure I'm getting this right.
Sooooo... solution time: I'm adding a couple of methods to the current indicator to allow you to set padding on the indicator portion of the indicator and the overlay portion of the indicator. This way between the base image, indicator and overlay, you should be able to easily configure the indicator to look however you want.

Uhhhh ok. I had to reread that one to get it right. :wink: It should work although I shouldn’t need it.

I'll also allow you to set the indicator to an image, however, I'm going to using clipping in place of scaling the image to avoid the problem stated above.
Bah. Exactly what I proposed above. Too lazy to delete what I wrote. :P
@madjack said: I haven't had the time to check the source but was there any change to the behavior of the defaultImage passed to the constructor? Also I think it would be ideal if you could quickly throw a working example using a background image, a color indicator, a mask and an overlay so there is absolutely no way to eff it up (like I usually do). Pseudocode would also work.

I’ll report my findings a bit later.

Yes on all 3 image layers. I am setting them up differently. Hopefully this will take care of any issues you have seen.

This week, I am going to overhaul the entire wiki and add examples for each control as well.

I don’t know what you’ve done but you’ve completely fixed it. :smiley:

Using a basic Indicator constructor (no texture, only position, size and orientation), setting an alpha map and it works as advertized. O_O Yay!

@madjack said: I don't know what you've done but you've completely fixed it. :D

Using a basic Indicator constructor (no texture, only position, size and orientation), setting an alpha map and it works as advertized. O_O Yay!

Awesome… if you check the wiki, I posted the updates for the control and a single example with a commented line so you can cut & paste it, and play around with config params/method calls. Is has a slider hooked up to it to allow you to quickly see how it will react, etc. I’ll be adding these types of example for each control as I update with all of the past months changes.

I’ve tried several iterations and it’s still working so that’s great. Makes me happy.

As far as the wiki, that’s good. I’ll check it out.

Thanks a lot. If you feel like it you can lock the thread.

1 Like

I’ll leave it open in case others have questions about the indicator or something else comes up for you.

@t0neg0d said: or something else comes up for you.

Good call. I found something it seems.

If I use setBaseImage(“someImage.png”); the default image (taken from the style) isn’t removed. That can easily be fixed by passing the image directly into the constructor, but that would also mean setting “resizeBorders”… Not a huge issue but that’s not ideal.

Also, manually setting constructor’s base image to null works fine, but not if I use the method. I think having the ability to not set anything in the background would be a good option to have. I’m trying to find the best visual solution for what I have in mind and I think nothing in the background will be best. Not settled yet though.

Anyway, I thought I’d let you know these.