Thursday, August 20, 2009

Deferred Lighting

hi, quick update
last crytek presentation they show their deferred lighting system, and i thought.. hmmm, i implemented those things few months ago, doing test and stuff to see if its good, but i didn't finsih all the tiny things that make it unstable (i wanted to focus on things other the graphics & effect), so last week i finished handling those tiny things and here is the result:

87 dynamic lights (yes, they all cast dynamic shadows)

Sunday, August 2, 2009

Undo/Redo System

hi, last week i implemented undo/redo system.
as you all know, editing software without undo/redo system is pretty useless.
i think undo/redo system is a must in any editing software, i think the system is very simple and easy to implement (depending on the app, but still) so i can't see any reason why not supporting it.
ok, so explained why, so now i explain (in general) how i added it to my level editor, i will explain the idea so for implementation detail just ask...
the more generic your system is (in term of managing editable objects) the more easy it become, here i describe a system with user define max size for undo/redo (because of memory issues, you don't want to consume more than needed).
you need to support few things before implementing it:
1. you have to be able to take a snapshot of current scene state, meaning, every editable object must be stored in a way that could be restored later.
2. deque container, i use deque so i could keep X oldest elements (used to limit memory used by the system), basically every container with option to add and remove from both direction will be fine.
after you support those its just a matter of identify the places you want to support undo/redo, and wrap them with Undo_Start & Undo_End or whatever name you want.
so what those functions do?
1. Undo_Start - take a snapshot of the scene and save it in undo deque, i make sure to store a flag (lets call it done) which says if i called Undo_End or not, and i checked this flag right after i entered this function. this to assure i wont try to call Undo_Start inside Undo_Start/Undo_End block (prevent nesting), the function also gets a string so i could name the operation i wrap, useful if you want your console to output text like: Undo create new box, or undo delete...
2. Undo_End - checks if i started undo op, and set the 'done' flag to true
simple enough, so now we'll see how to perform undo/redo actions:
1. Perform_Undo - pop the head from the undo deque, push it to the redo queue, and restore the snapshot you saved, i also check size limits right after pushig new element and i its greater then a max size i defined i just pop from the tail.
2. Perform_Redo - pop the head from the redo deque, push it the the undo deque, and restore the snapshot you saved, also do same limit test as in Perform_Undo

note this system could be optimized in few ways, one place to start is the snapshot function.
how exactly you do the snapshot is depends on the app, but a simple method is to duplicate all editable objects in the scene.
also note that the snapshot needs to run ONLY once, just before you modifying the scene.
practical example:
if you have 'CreateNewBox' function that you call when you click on a create new box button on main toolbar, you need to wrap this function like this:
OnButtonCreateNewBox
{
Undo_Start("Create New Box")
CreateNewBox()
Undo_End()
}
if your system supporting those kind of scene changes, speed isn't an issue, but if you support dragging and manipulating object properties with the mouse (like scale/rotate/move vertices/faces) you need to do some optimizations.
that's it, pretty simple right?