Page 1 of 1

Shadows draw functions too costy?

Posted: 08 Dec 2006, 08:33
by Watermelon
This one should go to mailinglist,but unfortunately gna kept eating my mails and others',so I have to start a topic there:


I looked through the piedraw.c file today,it seems that the pieDrawShadows function uses 2 glLoadIdentity(),2 glMultiMaxtrix,2 inverse_matrix functions per a model/shape just to get the light source of a pie?

This is how it works if I understand correctly:
PieDrawShape2:
1.Retrieves modelview matrix from glGetFloatv(GL_MODELVIEW_MATRIX, glFloat *store) then stored it in property 'matrix' of a static array of 'shadowcasting_shape_t'.

PieDrawShadows:
2.Get lightsource via function 'glGetLightfv(GL_LIGHT0, GL_POSITION, pos_lgt0)'and loops through the 'shadowcasting_shape_t' array and loadIdentity then multiply/inverse every matrix value in that array just to get the 'offset x,y,z' to light source 'pos_lgt0',and finally pass the light source vector to PieDrawShadow.

PieDrawShadow:
3.appends the 'light source offsets' to x,y,z when drawing shapes.

In my opinion the light source 'offsets' should be fixed values,or at least all models/shapes should use the same offset values rather than doing such enormous amounts of matrix multiply/inverse,even if we want dynamic shadows based on game day time.

Please correct me if I am wrong,I am not even sure if I understand these openGL function properly,because my openGL is still in a 'non-exist' state.

Re: Shadows draw functions too costy?

Posted: 08 Dec 2006, 10:44
by DevUrandom
I know what you mean. I also looked at that part of the code a while ago.
Didn't look nice, to be honest... Actually I wonder why all that matrix loading and reloading and ... and ... is needed. I think other engines are able to do it without reloading the indenty on every model...
And: We draw everything twice. Once with front and another time with backculing enabled. Would be interesting if we could simplify that also...

Re: Shadows draw functions too costy?

Posted: 08 Dec 2006, 16:53
by Watermelon
DevUrandom wrote: I know what you mean. I also looked at that part of the code a while ago.
Didn't look nice, to be honest... Actually I wonder why all that matrix loading and reloading and ... and ... is needed. I think other engines are able to do it without reloading the indenty on every model...
And: We draw everything twice. Once with front and another time with backculing enabled. Would be interesting if we could simplify that also...
I think not just the matrix multi/inverse is a big overhead,but the Draw twice you mentioned is a performance killer too.It seems it draws all polygons twice in 'pieDrawShadows()' function,i think it's equal to triple the number of  'pieDrawShape2' calls when shadow is enabled...and realtime shadows for all imd shapes including buildings is a bit weird too...

Re: Shadows draw functions too costy?

Posted: 08 Dec 2006, 17:10
by kage
question on costliness: when running through the renderer every pass, do you spend an "if" on checking to see if shadows are enabled, or do you use something like a call a function via pointer when shadows are on, and have that pointer unlinked when not on -- rather, an array of pointers to functions that comprise the "render steps" (also keep in mind that inlined code enclosed within an if statement is almost always much much faster than calling a function). too bad there's no clean fast way to do anything: it's either function overhead or conditional checking of some kind.

Re: Shadows draw functions too costy?

Posted: 09 Dec 2006, 09:46
by Watermelon
kage wrote: question on costliness: when running through the renderer every pass, do you spend an "if" on checking to see if shadows are enabled, or do you use something like a call a function via pointer when shadows are on, and have that pointer unlinked when not on -- rather, an array of pointers to functions that comprise the "render steps" (also keep in mind that inlined code enclosed within an if statement is almost always much much faster than calling a function). too bad there's no clean fast way to do anything: it's either function overhead or conditional checking of some kind.
I think it's a function overhead,I did some experiment with the piedrawShadows function,first time I disabled matrix inverse/multiply lines,and there was no noticeable performance improvement,later I disabled the pieDrawShadow function in pieDrawShadows function,the performance impact of those matrix inverse/multiply function is not even noticeable with pieDrawShadow function disabled.The tests turned out that the pieDrawShadow is the culprit of instant fps drops,seems I overestimated the costs of matrix compution,but neglected the overhead of pieDrawShadow function.

Maybe pieDrawShadow could use some optimization/use vertex buffer rather than doing glBegin/glEnd for each polygon for every shape.

Re: Shadows draw functions too costy?

Posted: 09 Dec 2006, 10:04
by kage
as it turns out, doing this stuff using a matrix is often a lot faster than the alternative -- matrixes are used often enough, in, say, fps games for all types of movement and rotation of anything, because they're flexible (you can specify movement, rotation, and even warping all at once and math, being your friend, will handle all the legwork, all at once in a super-efficient way), accurate, and fast.

it's probably just the implementation -- in these types of things you might be able to trace it down to a single line of code that is brute-forcing something.
Watermelon wrote: Maybe pieDrawShadow could use some optimization/use vertex buffer rather than doing glBegin/glEnd for each polygon for every shape.
as it turns out, i know absolutely nothing about graphics apis at this point, so i leave that to the rest of you, but it sounds like it's starting some kind of "open/close" context with glBegin/glEnd, which are usually quite costly.

Re: Shadows draw functions too costy?

Posted: 09 Dec 2006, 11:46
by cybersphinx
The whole graphics engine is a mess, it was written with a software renderer, the PSX and a DirectX (or was it 3Dfx? Anyway, some hardware) renderer (which possibly was bolted on later) in mind. The hardware renderer was adapted to OpenGL, by replacing commands, not rewriting it for efficiency. Ideally it should just be ripped out and replaced by something modern and maintained like OpenSceneGraph, CrystalSpace, Irrlicht or Ogre 3D. That'd need quite some work, since all other code is quite a mess, as well...

Re: Shadows draw functions too costy?

Posted: 09 Dec 2006, 12:45
by DevUrandom
Agreed... :)
Yesterday I tried to remove the 128x128 pixel tiles limitation...
I went to all kinds of funny stuff like distorted (similar to scanlines) textures, tiles being that the wrong place but at least being displayed correctly.
Even increasing the hardcoded TILE_WIDTH and TILE_HEIGHT didn't help anything, because in other parts of the code the number of tiles which fits into a 512x512 texture page (all texpages seem to be hardcoded to that size) is hardcoded to 16 in several places. Fixing those 16s to something (hardcoded) variable didn't help either, I bet there are other hardcoded numbers which are related.
Then followed several crashing attempts and I ended up with a version which didn't crash anymore, but neither showed any textures. ;)
When I tried to fix that by multiplying the uv coordinates with (UWORD)(-1) (after thinking about it, I recognized myself that it wouldn't have helped anything...), it suddenly started to crash when removing campaign units from the map during the load process... Very weird...
By that time I allready replaced most of the terrain/tiles related functions.

So I guess at least the terrain renderer needs to be replaced with something better, if we ever want (non-hardcoded) support for tiles bigger than 128x128.

Re: Shadows draw functions too costy?

Posted: 09 Dec 2006, 12:48
by Watermelon
cybersphinx wrote: The whole graphics engine is a mess, it was written with a software renderer, the PSX and a DirectX (or was it 3Dfx? Anyway, some hardware) renderer (which possibly was bolted on later) in mind. The hardware renderer was adapted to OpenGL, by replacing commands, not rewriting it for efficiency. Ideally it should just be ripped out and replaced by something modern and maintained like OpenSceneGraph, CrystalSpace, Irrlicht or Ogre 3D. That'd need quite some work, since all other code is quite a mess, as well...
I think fixing the exist render functions is better than using an external render engine,since you can write something from scratch with the time you wasted on understanding the endless lines of a render engine's API documentation...

Re: Shadows draw functions too costy?

Posted: 09 Dec 2006, 13:20
by kage
DevUrandom wrote: Agreed... :)
Yesterday I tried to remove the 128x128 pixel tiles limitation...
I went to all kinds of funny stuff like distorted (similar to scanlines) textures, tiles being that the wrong place but at least being displayed correctly.
Even increasing the hardcoded TILE_WIDTH and TILE_HEIGHT didn't help anything, because in other parts of the code the number of tiles which fits into a 512x512 texture page (all texpages seem to be hardcoded to that size) is hardcoded to 16 in several places. Fixing those 16s to something (hardcoded) variable didn't help either, I bet there are other hardcoded numbers which are related.
Then followed several crashing attempts and I ended up with a version which didn't crash anymore, but neither showed any textures. ;)
When I tried to fix that by multiplying the uv coordinates with (UWORD)(-1) (after thinking about it, I recognized myself that it wouldn't have helped anything...), it suddenly started to crash when removing campaign units from the map during the load process... Very weird...
By that time I allready replaced most of the terrain/tiles related functions.

So I guess at least the terrain renderer needs to be replaced with something better, if we ever want (non-hardcoded) support for tiles bigger than 128x128.
when this kind of stuff happens, it's often better to stop improving stuff and start rewriting it: rewrite a small chunk, find everything that breaks and change that to use your new system. do this chunk by chunk, and keep each chunk isolated (obviously), and soon enough you stop getting nearly as many bug reports.

also, using defines for code you're playing around with can be tedious because it requires recompile (even with object code caching this is still tedious) -- is there any sort of cvs/debug-build infrastructure for handling the loading of constants from a file? production builds probably shouldn't do this, as it's much during runtime, but little overhead for each tweak
Watermelon wrote: I think fixing the exist render functions is better than using an external render engine,since you can write something from scratch with the time you wasted on understanding the endless lines of a render engine's API documentation...
i agree to some extent here: each api has a lot of pros and a lot of cons, and always gives you more fluff than you want to use. if any api was perfect (or anywhere near it), nothing else would exist. if we do adapt an api, it's best to only go with one that handles rendering and model loading -- anything beyond that and we'd might as well rewrite the game from scratch, since almost all those apis are geared towards getting a game up quickly from scratch (whereas we already have a working game), and provide skeleton code files for quick modification, whereas we'd actually have to learn the api so that we could integrate it. i think crystalspace is one of the "least questions asked" apis, where we could use what we wanted from it (such as graphics), but rip out the rest. i used to work with someone who was a dev for the ogre3d team -- based on what he was saying, it seemed to be pretty tightly meshed to where it was great if you were using it from the beginning, but really would require a bit of a rewrite of almost everything to adapt it (it'd be quicker to document every single game rule and then start from scratch using ogre, since what i see of our gameloop is about 90% incompatible with that). i don't know anything about the others you mentioned: openscenegraph or irrlicht...

also, lots of apis that offer audio support, but with an emphasis on graphics and scripting tend to have shoddy sound support - it'd be best to adapt a seperate api for that or use our own.

most of the apis don't really provide great graphics without you having to program them in: i've seen plenty of really good and really really bad games built on recent versions of crystalspace and ogre3d, so it's not purely a free ride, but at the same time it doesn't really hurt us, because if we can get our source code modularized enough to support the grafting-on of a graphics api, than it'd be clean enough that we can ditch it again if we didn't like it.
cybersphinx wrote: The whole graphics engine is a mess, it was written with a software renderer, the PSX and a DirectX (or was it 3Dfx? Anyway, some hardware) renderer (which possibly was bolted on later) in mind.
it was actually all three (3dfx had some nice graphics in some areas, and bad ones in others, as i remember).  there's nothing wrong with supporting different renderers, and usually it's done in a pretty clean way. on the other hand, opengl is so universal that there's little reason to go with anything else -- it looks just as good as directx on windows, is cleaner to program (i haven't worked with the api's, but i've seen their code...), and runs faster too... only reason you see so many directx games instead of opengl ones is because microsoft had an early start on directx usage in gaming (at that time, opengl was mostly limited to very high end unix workstations), and everyone trained in the use of directx, and never tried anything else.

Re: Shadows draw functions too costy?

Posted: 09 Dec 2006, 13:42
by DevUrandom
AFAIK that mainloop-takeover is gone in OGRE Eihort...