RenderState.Push() + Pop() methods!

BlitzMax Forums/BlitzMax Programming/RenderState.Push() + Pop() methods!

sswift(Posted 2006) [#1]
I wrote this as part of my sprite system, and I think pretty much everyone will benefit from it, so I've posted this class in the code archives for all to use.

If you find it useful, buy my sprite system when it comes out in a few days. It'll be 10x as useful. :-)

http://www.blitzbasic.com/codearcs/codearcs.php?code=1641

What's it do? It saves and restores the current settings for drawing stuff.

When you make a function that changes these settings, you can save the current state at the start of the funciton with a push, and then pop that state off the stack when the function is finished.

This way you won't accidentally change the alpha and then forget to set it back to 1 when you're done and screw up text you print later.

I posted it before on the forum, but now it's in the code archives, and I changed a few minor things.


Michael Reitzenstein(Posted 2006) [#2]
In my system you can also change just the current level's alpha, blend, origin etc, so the properties can stack. So if you set the alpha to 0.5, push it, set the alpha to 0.5, it actually draws with an alpha of 0.25.

It's proved incredibly useful. Imagine a game object that's made up of two images, one 1.0 alpha and another 0.5 additive. You write the function to draw that, and then later on you want to fade it in, so you just push an alpha of x before you call the function, and the images will draw with alpha of x and x/2. Then if you wanted to make the whole thing additive for a creation animation, you push lightblend before you call it and both images are set to additive.

It's also useful when you want something to be drawn with alpha, but you don't want to restrict it to alpha blend. My font system pushes alpha blending. If you call the draw function when the blend is set to maskblend, it will draw them as additive. Alpha will (of course) draw them with alpha. Additive will draw them with additive, because additive is considered higher level than alpha.


sswift(Posted 2006) [#3]
That all sounds a bit crazy to me. :-)

But it does sound a bit like my sprite system. If you have a parent with an alpha of 0.5, and a child with an alpha of 0.5, then the child will be drawn with an alpha of 0.25.

Btw, you never answered my question about whether you ported the Lego game I wrote to the Mac via BlitzMax. :-)


Haramanai(Posted 2006) [#4]
If you find it useful, buy my sprite system when it comes out in a few days. It'll be 10x as useful. :-)

This explains your problems with Var.


sswift(Posted 2006) [#5]
If by that you mean in this case var works nicely, but in most cases it doesn't...

Otherwise I don't know what you're talking about. :-)


Michael Reitzenstein(Posted 2006) [#6]
That all sounds a bit crazy to me. :-)

But it does sound a bit like my sprite system. If you have a parent with an alpha of 0.5, and a child with an alpha of 0.5, then the child will be drawn with an alpha of 0.25.

What's the point? What advantages does it have over just drawing the images manually?

Btw, you never answered my question about whether you ported the Lego game I wrote to the Mac via BlitzMax. :-)


Really? I suppose I didn't...


sswift(Posted 2006) [#7]

What's the point? What advantages does it have over just drawing the images manually?




I can create a menu background.
Then create buttons.
Then make those buttons children of the menu background.

Then I can hide the menu, and the children hide.
Or I can fade the menu out, and the children fade.

Since all of this works with the animation system, I can tell the animation system that I want the menu to fade, and that I want it to take one second. Then I can poll the animation system to find out when the animation has completed, at which point I can start the game.

Alternatively, or simultaneously, I could tell the animation system to move the menu background from center screen to offscreen. And once again, find out when this action completes.

And these things happen simulataneously to the menu's buttons because they are children of the menu. And I don't have to do anything beyond attaching them to the menu for it to work.

Calling one function updates the animation. Calling another causes all the sprites to draw.

It's like the BOB and AniBOB systems in my Lego game, but more sophisticated.

Yeah, you could make a monster class, and give it an image pointer. But then you'd have to set up all the stuff for keeping track of their positions, their alpha, and animate everything manually. Also, if you have both monsters and bullets, now you have to keep track of the position, color, alpha, hidden state, rotation, scale etc for both. So you have to add all those fields again.

This saves you a lot of work. Now when you create a monster, you just give it a stprite field, and any miscellaenous fields it needs for managing health and stuff. All the position and appearance stuff is all handled by the sprite class. And the animation class handles all the animation for you. You'd have to write an animation system otherwise, and would it have single shot, ping pong, looped, one shot ping poing, and be able to play animations in forward and reverse, and handle moving things in sine waves and accelerating/decelerating them? It might. But that's a ton of work to get right. It's taken me two weeks just to port it and get all the interfaces designed right for Max, and that doesn't count all the time it took to write in the first place. Probably take you like a month to do it. And there's all that annoying rotation/scaling math to handle the parent child stuff. You wanna do that? I don't. :-) But I had to.


Michael Reitzenstein(Posted 2006) [#8]
I think it'll probably make the simple stuff easier, but the more complex stuff much more difficult. I use eight different types of interpolation in my game. What happens when it's not something your system supports? Then you have to take the object and update it all manually. Most objects will have stuff that won't work easily within your parameters in a complex project - and that means manually updating everything, and that means no benefits, just a dud wrapper object that makes everything less flexible.

You can get all the child/parent stuff by defining it at render time. Animation stuff needs to be setup and handled one way or another so no harm making an animation object there. And really, how many lines of code are you looking at saving with your screen fades? Not very many, if any, if you wrote it right the other way.

But that's all I'm really going to say... you're a competitor and it's a big advantage if you spend all your time fighting the system you built for yourself :)


sswift(Posted 2006) [#9]
"What happens when it's not something your system supports?"

Like what?

"and that means manually updating everything, and that means no benefits, just a dud wrapper object that makes everything less flexible."

The animation stuff is completely seperate from the sprite class. If you want to move the sprites, you can position them or translate them. And you can do everything to them that you would want to do to a sprite. Set scale, color, alpha, blending mode, rotation, etc.

"You can get all the child/parent stuff by defining it at render time."

But it's a huge pain to do so. How are you going to do it? Are you going to create a menu class with your own parent and child system?

If not, what are you going to do?

Have DrawImage DrawImage DrawImage DrawImage 20 times in each section of code where the menu might move? One set for the "menu scrolling onto screen" state, one for the "menu waiting for input" state, and one for the "menu scrolling off screen" state?

Or are you going to have a bunch of boolean values which tell you whether a menu should be drawn, and a function to draw it at a speficied location, with one function for every menu in the game?

And if you have that, how are you going to check for collisions between the mouse and the various menu objects? have a huge case statement with one case for each menu which might be visible and then a bunch of commands to check to see if the mouse collides with the rects around the buttons?



But that's all I'm really going to say... you're a competitor and it's a big advantage if you spend all your time fighting the system you built for yourself :)



You're crazy. You saw my Lego game. The code was a mess, and it wasn't because of the sprite system. The sprite system was the cleanest part of the whole thing. The menu system is what was a mess, and the way I handled loading images. And why were they a mess? Because I used techniques like you are describing rather than using more object oriented techniques like I did in the sprite system.

Anyway, don't take my word for it. Take Mike Boeh's word for it. His sprite system for his games (wiritten in C) works exactly the same as mine does, (according to him) and he's programmed way more games than either of us.

Also, Blitz 3D uses this sort of system. A sprite is exactly the same sort of thing as an Entity in Blitz3D. And my system supports the same parent child stuff.

The only thing my system does different is is goes a step above and beyond this and provides an animation system on top, which is like using my AniBrush system on top of Blitz 3D. All the low level stuff is still right there for you to use, but it sure is nice to be able to animate a sprite in a loop with one command.


Robert Cummings(Posted 2006) [#10]
I don't think I'll ever be able to work with sswift. He would drive me insane within minutes.


Michael Reitzenstein(Posted 2006) [#11]
Really, I don't see where you're coming from. Good luck with your game.


sswift(Posted 2006) [#12]
OEJ:
I WORK ALONE!


Michael:
Hey, my absolute defense here is lots of people have bought my stuff, and they like how it works, so I must be doing something right! :-)