• entries
743
1924
• views
583820

332 views

Just to report that I have added a slider control to Squishy's GUI system. It might not look like much, but the rounded ends took quite a bit of work.

What I've had to do, to support sliders of any size, is to render to an offscreen texture of a fixed size, first filling with white then drawing the end circles over the top with alphablending off, working out the width of the half circles based on the height of the bar so they stay in proportion.

At this point I have a texture that is the correct shape but all white.

I reenable alphablending, then render the bar using this texture, but with a special shader enabled that compares the u value of the texture coordinate with the current value of the slider, halving the colour values if required.

It all sounds a bit complicated but it is the only way I could get the colour fill of the bar to correctly fill into the rounded ends while having nicely antialiased edges to the circular bits.

It is the kind of detail that probably no-one else would ever notice, but it looks pretty nice.

The above menu doesn't actually affect the sound levels yet, but that will be pretty easy.

You can click within the bar to set its position, or click within the bar then drag the mouse to move the level. The bar "captures" mouse input at this point so, like a Win32 scrollbar, you can then drag anywhere on the screen and the bar will follow, obviously locked between its upper and lower limit, until you release the mouse button.

The bar will then communicate position changes (between 0 and 1) with the GUI listener, which can take appropriate action.

I see you're still working a rapid pace! :P

Knowing how lazy I am at times, I would of made an image with a cut out circle bar leaving it transparent, than just slide a rectangle box that is white under it when increasing or decreasing volume giving the same effect you have. It just wouldn't look too good because you have transparency on your GUI window.

Quote:
 Original post by MrCpaw It just wouldn't look too good because you have transparency on your GUI window.

That is exactly why a simple solution wouldn't work, so thanks for clearly understanding the problem so quickly from my ramblings. [smile]

Another solution would have been to use a premade texture of the bar with the above shader, but then I would have only been able to support bars of a certain size.

This way, I can have bars of any length and I don't use any more texture memory as there is a general white circle on transparent background texture that I use throughout the game.

Something that makes layered blending SUPER EASY is premultiplied alpha. Basically, you take your alpha image and just go ahead and multiply the color channels by the alpha (given the 0..1 range). So, for instance, white that is 50% transparent would be [0.5, 0.5, 0.5, 0.5] instead of [1, 1, 1, 0.5]. Then, you blend with SourceBlend = One, DestBlend = InvSrcAlpha (where the standard blend is SourceBlend = SrcAlph, DestBlend = InvSrcAlpha - the SourceBlend is different in premultiplied).

Because of the nature of it (and tomf's blog, linked above, is a bit better at explaining this), blending a ton of layers of alpha stuff together is cake - it just works the way you'd want it to (instead of having to screw around with render-to-texture stuff). It has some other advantages too that are listed on that page :)

EDIT - wow, I think I really misread the problem in your entry...but hey! It's still a handy technique! Maybe you're even already using it :D

Quote:
 Original post by Drilian Something that makes layered blending SUPER EASY is premultiplied alpha. Basically, you take your alpha image and just go ahead and multiply the color channels by the alpha (given the 0..1 range). So, for instance, white that is 50% transparent would be [0.5, 0.5, 0.5, 0.5] instead of [1, 1, 1, 0.5]. Then, you blend with SourceBlend = One, DestBlend = InvSrcAlpha (where the standard blend is SourceBlend = SrcAlph, DestBlend = InvSrcAlpha - the SourceBlend is different in premultiplied). Because of the nature of it (and tomf's blog, linked above, is a bit better at explaining this), blending a ton of layers of alpha stuff together is cake - it just works the way you'd want it to (instead of having to screw around with render-to-texture stuff). It has some other advantages too that are listed on that page :) EDIT - wow, I think I really misread the problem in your entry...but hey! It's still a handy technique! Maybe you're even already using it :D

Interesting stuff. I don't think it is a solution to the problem here, but it may well be of great use in other areas - getting shiny things to show up against a bright background is one that comes to mind.

Although from reading the article, it seems that I could use it for all alpha blending so when I've got changed and made a coffee, I'm going to experiment. Multiplying the colours by the alpha is easy since I use a custom image loader and I only set the alpha render states once so it will be easy to do.

Good grief! That looks like a real game!!!

You've really come a long way. The UI + water effects really look sharp.

And if you don't mind me asking, how are you calculating the blur?

To handle the rounded edges, you could also have "corner" graphics and "edge" graphics assigned to the control. The "edge" graphics would be repeated as needed. I haven't actually used this system yet, but it seems like it would work well.

Quote:
 Original post by Milkshake Good grief! That looks like a real game!!! You've really come a long way. The UI + water effects really look sharp. And if you don't mind me asking, how are you calculating the blur?

Just two pretty simple shaders. I render the game to a texture, then put the texture through a horizontal then vertical blur then render to the screen.

For example, the horizontal blur:

sampler tex : register(s0);

struct INPUT
{
float2 coord : TEXCOORD;
};

struct OUTPUT
{
vector color : COLOR;
};

float level=0;

OUTPUT main(INPUT input)
{
OUTPUT output;
float2 t=input.coord;

float p=0.003*level;

float4 total = tex2D(tex,t);
total+=0.895*tex2D(tex,t+float2(1*p,0));
total+=0.895*tex2D(tex,t+float2(-1*p,0));
total+=0.641*tex2D(tex,t+float2(2*p,0));
total+=0.641*tex2D(tex,t+float2(-2*p,0));
total+=0.368*tex2D(tex,t+float2(3*p,0));
total+=0.368*tex2D(tex,t+float2(-3*p,0));

output.color=total/4.808;
return output;
}



Can't remember where I blagged those constants from - somewhere on the internet.

Quote:
 Original post by Milkshake And if you don't mind me asking, how are you calculating the blur?

And if you don't mind me asking, when are you going to update your journal? [smile]

Quote:
 Original post by VBStrider To handle the rounded edges, you could also have "corner" graphics and "edge" graphics assigned to the control. The "edge" graphics would be repeated as needed. I haven't actually used this system yet, but it seems like it would work well.

Problem is that the white section can be part of the way through the rounded part - you can adjust it on a per pixel basis.

If it was in discrete sections, I would probably do as you say and draw it in sections in a loop, setting the diffuse of each block as I went, but I wanted to be able to have an analog input from the slider.

Quote:
Original post by Aardvajk
Quote:
 Original post by Milkshake And if you don't mind me asking, how are you calculating the blur?

And if you don't mind me asking, when are you going to update your journal? [smile]

Hahaha.

I'm working on an iPhone game which should be finished in a week or 4. I'll be writing it all up once I'm done. Interestingly, the first thing I did was ported the cow to the iPhone. He's a little naked without his shadows (as there's no stencil buffer on the iPhone), but it was cool to watch his little spaceship landing on that tiny screen.

Quote:
Original post by Aardvajk
Quote:
 Original post by Milkshake Good grief! That looks like a real game!!! You've really come a long way. The UI + water effects really look sharp. And if you don't mind me asking, how are you calculating the blur?

Just two pretty simple shaders. I render the game to a texture, then put the texture through a horizontal then vertical blur then render to the screen.

Can't remember where I blagged those constants from - somewhere on the internet.

Thanks for the shader code. It's odd because that's exactly how I calculate the blur for my depth of field (well, not those constants, but the split horizontal and vertical), and I'd swear your one looks better. Perhaps it's just that it's fullscreen vs depth-of-field filtered.

## Create an account

Register a new account