PDA

View Full Version : Sorting transparent objects, qsort()



tcs
02-23-2000, 10:06 AM
Hi !

I want to draw billboarding bitmap trees. Their background is
transparent, so I need to sort them to erase the visual artifacts
that would appear otherwise. To draw them from front to back, I
need to know their distance from the viewer. If I have 100 trees,
I need 100 square roots each frame. Not good. This is my first
problem.

After I calculated the distances from the viewer, I want to sort them
so that they are drawn in correct order. I want to use the qsort()
function for this. This is my second problem. I can't get qsort() to
accept my callback function:

int CTreeCollection::Compare(const void *arg1, const void *arg2)
(My compiler is VC++ 6.0)

I always get the error "int (const void *,const void *)" can't be
converted in int "(__cdecl *)(const void *,const void *)". I have no
idea how to solve this. How should my callback function look ? How shold I
pass the callback function to qsort() ?

Can anyone help me to speed up / avoid those square roots every frame ?
Does anyone know how to use qsort() ?
Someone out there with a better idea to do all this stuf ?

Tim

dmy
02-23-2000, 01:11 PM
hi tcs!
the qsort()!
i had the same problem when i first tried qsort() for object depth sorting.
i also tried to make the compare function a member of a class...

well, you can't make it a member, but that's not a problem.

the compare function must be a global function, like printf(), to say.

this is my compare function layout:




#define SLOT(s) ((Tdmyentityslot *)s)
//-----------------------------------------------------------------------------
int __cdecl depthsortfunc( const void *a, const void *b ) {
if( SLOT(b)->compare == SLOT(a)->compare ) return 0;
if( SLOT(b)->compare > SLOT(a)->compare ) return 1;
return -1;
}
#undef SLOT



about depth sorting, yes you need a depth value, but there's no need to sort real distances from the camera.
all you really need is a value related to distance, so simply avoid the sqrt.
just use the squared distance and everything will work just fine.

Dolo/\/\ightY




[This message has been edited by dmy (edited 02-23-2000).]

cass
02-23-2000, 01:19 PM
tcs,

First thing is, you can sort on distance^2 rather than distance and avoid the square root operation.

Second, I'd consider using the C++ standard library sort over qsort() since it could probably inline the comparator and avoid a lot of function call overhead.

For more information on the C++ standard library sort, see:
http://www.sgi.com/Technology/STL/sort.html

Hope this helps -
Cass

tcs
02-24-2000, 03:33 AM
Thanks, it works...
I made it a global function, I already thought this was the reason. The idea with not calculating the distance, but calculating just some kind of sorting value works also great.

Thanks !

Marc
02-29-2000, 07:09 AM
hi tcs

Please could you tell me, how I can get the distance of an object/vertex from the viewer after all that rotations and translations you normally do in a 3D-world with OGL?

Thanx in advance

tcs
02-29-2000, 08:24 AM
hi !

simply calculate it ;-))
There's no other way since opengl is a one way pipeline. I use the described method without square roots, just for depth comparison. If you want't to get the distance, use pythagoras. If you do some rotation stuff, you have to calc that, too.