Alpha Channel on GUI buttons with an opaque background

Started by Ryan Timothy B, Sat 20/06/2009 00:26:21

Previous topic - Next topic

Ryan Timothy B

Ok.  I've searched the forums a bit and came across a post that I believe answers all my questions.  And from what I believe it also tells me that I can't do what I want.

This thread: http://www.adventuregamestudio.co.uk/yabb/index.php?topic=34537.0

The story:
Anyway, I'm pretty much going to have to explain what I'm attempting to do here.
I'm trying to make the next Road Racer game with night time and day time (depending on the time of the day).  I had decided to use a dark blue color as the 'night' color.  Then I can set the GUI transparency according to the time of the day.  If it's midnight the GUI.transparency is 20, etc.
All worked fine.... until I decided to slap headlights into the scene.  The cars need to see somehow.

The problem:
As you can see in this image below, the alpha channels go all wonky unless they are on a blank portion of the gui background.
The headlights are buttons.


I slapped a few headlights in there to show you what my problem is.
EDIT: Oh and ignore the crazy blue squares.  The only color I'd have would be like perhaps 80% opacity of the blue covering the whole screen, so I could keep the alpha channel images in the buttons.

From the post linked above, the problem is that the Blue has a darker opaque than the white.  It's 100% opacity versus 20%ish.

Possible solution that I know of but I Can't use:
Now you could say that I can make another GUI (one for the darkness and one for the headlights).  But it won't work the way it should.  The darkness GUI will be darkening the image, and the headlight alpha channel will be trying to lighten an already darkened image, therefor visibility with a headlight will be even worse than without one.

Here's an image to show you what one would look like over the other. The left one is a mock up of how it SHOULD look, since I can't get it to show properly, and the right one is an actual GUI overlay on top of the Darkness GUI.

The left one is what it would look like if the headlight was on the same GUI as the Darkness.
The right one is what it would look like with an extra GUI on top of the Darkness GUI with a 20 transparency. -Much harder to see what is under it.


So here are my main questions:
Anyone got any Ideas?
Am I doing something wrong?
Or is it possible for CJ to easily make AGS allow this if it turns out I actually can't do it.

What I REALLY would love instead of a whitened headlight alpha channel over a blue GUI
If I could destroy the blue of the Darken GUI where the center of the light is.  Like this:

See how much easier it is to see? I would love this.

Which is simply just this with alpha channel in the middle (shown with an edited transparency mask behind it since you wouldn't be able to see it had alpha channel without):

But even if I could somehow do this, overlapping of the two wouldn't give desirable results with the blue and all.

Ok enough rambling.  Someone must know what I can do.  AGS is powerful and amazing, I'm just not using it right...  Yes.  That is the only reason. :P

EDIT: Without this, my game loses an eye catching feature I had hoped to have.  I really don't want to place another GUI over the darken GUI just to give the 'impression' there are headlights.  It would make visibility worse especially when the headlights are covering something.

Ryan Timothy B

Oh gosh. One thing I never did try (due to not thinking about it).  Was lowering the transparency of the Headlight GUI.  It's practically* the same as what I wanted from the headlights in the first place.
Now this confuses me.


*The only difference being, that having a Headlight GUI over the Darkness GUI is that it's bluer and less white.  Oh well.  I can handle this for now since it works.  Visibility under the light isn't exactly grand, but it'll do I guess.

Pumaman

For a night time effect, a common approach is to create an Animated Background with a night version of the background image, and then use DrawingSurface.DrawImage function with varying transparency values to draw it on top of the main background to change the time of day -- you might want to consider that approach, though if your background images are huge this may not be a performant approach.

Ryan Timothy B

Yes, if my backgrounds were much smaller I would definitely do that approach.  But I'll be looking at something crazy like 2000x2000 backgrounds.  Also with a minimum of 20 characters on screen plus other elements/objects. 
Tinting each object and character individually plus the background would definitely not do so well (I imagine).

That's why I went for the GUI transparency approach.  Although I'm not getting what I want from the headlights, I guess it can do since I don't believe there is a better approach for multiple headlights in one GUI.

Now if there were a way to do a reverse ALPHA channel (if that is what it would be called), I could get those headlights looking freakin amazing.  Just like the masks in Photoshop.  How applying black to the mask will turn that area transparent.  Or if the color was mid gray that area would be 50% transparent. etc.


I would love to make masks a suggestion, but I honestly can't see anyone else really needing this or how it would be approached.  Like in my scenario, I'd want to be able to apply a mask to the background image of the GUI and the buttons (having a toggle in the quick pane to have that particular button image be applied to the mask or not).  The image would have to go gray scale just for it to calculate the percentage of transparency applied to the mask.

Anyway, like I said. My headlights 'work' the way they are.  Obviously they don't increase visibility, but at least they give the impression of being a headlight. :P

Pumaman

What's the "GUI alpha rendering style" set to in your General Settings? Have you tried the AdditiveOpacity mode?

Ryan Timothy B

Yes.  It's running AdditiveOpacity (the default). :P

Ryan Timothy B

Considering this question is pretty much for this headlight GUI.  What is the Button ID # for?
When you create a button it'll say... ID = 0, ID = 1, ID = 2, etc.

Is it similar to the character ID number?  Where you can use quick references like: character[1]?

I've tried  button[0]  but that doesn't appear to work.

GuyAwesome

I think that doesn't work because a) the ID can refer to all Controls on a GUI - so ID = 0 might be a button, label, listbox, etc, and b) because every GUI starts its control IDs from 0, there's no way to tell if button[1] was on the headlight GUI, the darkness GUI, the Iconbar GUI, or what. I don't think there's a direct array of every button created in the game so far, as there is for characters, GUIs, etc (at least, not one we can access).
You might be able to use the GUI.Controls property, e.g. gHeadlight.Controls[0] - but honestly it's probably quicker to just name the buttons and use that... (hLight1, hLight2, etc vs. gHeadlight.Controls[0], gHeadlight.Controls[1], etc)

Ryan Timothy B

#8
Well considering I ONLY have buttons on this particular GUI and they all serve the same purpose, I could hug you right now. :P
You just saved me from 20 lines of:
Code: ags
if (rl_number==0) Light0.NormalGraphic = headlight[rl_number].Graphic;

and 20 other lines to find out the height of the button image.

Because this works:
Code: ags
gLight.Controls[1].Visible=false;


Thanks once again!

EDIT: Oh dang it.  Just tried to punch in the  .NormalGraphic  to the controls and it's not a public member of GUI control.  Looks like I'm back to 20 lines again.  But at least it works for the visibility of the buttons.  Either way, thanks.

GuyAwesome

#9
You need to add a couple extra lines, something like
Code: ags

Button *bLight = gLight.Controls[1].AsButton;
bLight.NormalGraphic = headlight[rl_number].Graphic;


I don't think you can compress that into gLight.Controls[1].AsButton.NormalGraphic = headlight[rl_number].Graphic;, sadly. (This is why I said naming the buttons was probably quicker - but I guess GUI.Controls means you can use a while loop to trim those 20 lines slightly?)

EDIT:
OK, just realised how quick that reply was. I'm not stalking you, honest...
EDIT2:
Huh, so you CAN compress it down... Sorry about that, I was sure I'd tried it at it didn't work. Must just be 2AM affecting my memory...

Ryan Timothy B

Ahh.  Never would have thought of that.
You're a regular hero today.  I'm going to have a daughter one of these days, she'll be really hot, and I'll force her to marry you.  haha jk

Anyway thanks a lot!  I love while statements, they save space, and they allow me to easily make my script Open Source for anyone who wants to make a driving game with it.

monkey0506

#11
Quote from: Ryan Timothy on Wed 24/06/2009 01:37:59Oh dang it.  Just tried to punch in the  .NormalGraphic  to the controls and it's not a public member of GUI control.  Looks like I'm back to 20 lines again.  But at least it works for the visibility of the buttons.  Either way, thanks.

The Controls property is comprised of the base GUIControl type from which all of the complex types, Button, Label, ListBox, TextBox, etc. are derived from. That means that GUIControl has basic properties like Visible, but type-specific properties like NormalGraphic only apply to Button objects. That's why every GUIControl object has properties such as AsButton, AsLabel, AsListBox, etc.

If the GUIControl is not actually associated with that type of control then the AsWhatever property will be null. So you could do:

Code: ags
if (gLight.Controls[1].AsButton != null) gLight.Controls[1].AsButton.NormalGraphic = headlight[rl_number].Graphic;


Edit: Beat out by Guy...:P...but you should make sure it's not null. Even if you're sure, if you change your GUI later it would cause issues...of course then your script would need to be changed too...sooo...

BTW Guy, GUI.Controls, GUIControl.AsButton, and Button.NormalGraphic are all standard properties, so AFAIK there shouldn't be any issue with just using it all off the GUI itself through the properties. The only issue arises when you're working with a property declared on a static property. So for example you cannot directly access Game.GlobalStrings[x].Length because Game.GlobalStrings is static.

Edit: Beat out by Ryan! FECK!

Quote from: RyanI'm going to have a daughter one of these days, she'll be really hot...

Gross. :D

Ryan Timothy B

Ooo.  I like your scripting better Monkey.  Saves me from using a variable, and it all compresses nicely into 1 line instead of 2.  Excellent. :P

Thanks!

GuyAwesome

Quote
The only issue arises when you're working with a property declared on a static property.

Right enough, that's what my sleep-deprived brain was summoning up (specifically GUIControl.GetAtScreenXY which was on my mind from here), coupled with some other, unrelated, difficulty I had using the AsType functions.

gixmi

The only difference being, that having a Headlight GUI over the Darkness GUI is that it's bluer and less white.

SMF spam blocked by CleanTalk