Re: [Plib-users] Plib as a Model Loader
Brought to you by:
sjbaker
From: Steve B. <sjb...@ai...> - 2004-07-16 08:34:34
|
Tyler Ohlsen wrote: > Loading from a 3D file into a scene graph is one implementation, you > don't have to do it that way. I agree that it makes a lot of sense and > that most 3D applications are greatly improved by using scene graphs. > That being said, it would be nice to have the option to use someone > else's scene graph library. Not that yours is lacking in anything, but > the option is nice. What other kind of data structure could you load a 3D model into? A big pile of unstructured polygons and vertices I suppose - but that isn't going to make rendering very easy - and it throws away a lot of valuable information from the source model. >>SSG lets you set both the modelview and projection matrix directly. >> >>It's hard to imagine what "your own camera" could be that SSG couldn't >> already handle. > > Again, this was a matter of preference. I would like to use my own > camera if I could (without doing a hack to convert my camera's > orientation representation to ssg's camera orientation every frame). What hack? Just call the SSG function to pass your camera's data (heading, pitch, roll, x, y, z) into SSG. That's *ONE* line of code! It couldn't be much simpler! >>No - because SSG needs to know that those matrices are in order to >>do field-of-view culling, Range-switched nodes and such. OK - we >>*could* read those matrices back from OpenGL in order to find out >>what your camera code set them to - but reading things back from >>OpenGL is something to be avoided at all costs. > > But if you're not using ssg as your scene graph (just as a model loader) > then you don't want it to do view culling. Then ssg doesn't need to > know the current state of these matrices at all. OK - so if you aren't using SSG to render the scene and you don't want the loaders to load into SSG's scene graph - then why the heck are you using SSG? > glNewList(iListID, GL_COMPILE); > glPushMatrix(); > glRotatef(-90, 1,0,0); //ssgRawDraw allows for regular > opengl transforms > glScalef(0.25f, 0.25f, 0.25f); > ssgRawDraw(oModel); > glPopMatrix(); > glEndList(); But this mythical 'ssgRawDraw' function has to traverse the scene graph because the scene graph may contain transforms, selectors, animations and level-of-detail nodes that the loader created for us. Let's look at just one of those things by way of example: Level of detail nodes (ssgRangeSelector). This is something that has been created by the loader from information in the model file. It is a model that has one polygonal representation when it's close to the eye - and a simpler one when it's further away. If you ignore the presence of that node in the file and just render all the polygons mindlessly then you'll see TWO copies of the model being drawn at once - one of which looks really bad when it's close to the eyepoint because it's made of so few polygons - and the other of which will overload your system because it's drawn with so many polygons - even when it's 10 miles away from the camera. So in that case, you **MUST** traverse the scene graph that the loader built for you or the scene won't look right. Now - in order to decide which of those two models to draw, your rendering code (marked here in your example as 'ssgRawDraw') **MUST** be able to figure out the range from the object to the camera. However, it has no way to do that because you only gave the camera matrix to OpenGL - you didn't tell the renderer. The *ONLY* way that ssgRawDraw could possibly figure out that range would be to do a glGetMatrix. The trouble with glGetMatrix is that it (potentially) stalls the graphics pipe...this could make it UNBELIEVABLY slow. So - the rational way to do it is to have your application pass the camera matrix into SSG so that it knows where the camera is without having to read it out of OpenGL....and that's what we have. There simply isn't any other way to make this work. There are other nodes that need this information - ssgCutout for example. Then there is the issue of field-of-view culling. In a typical application, the camera's field of view is something like 60x40 degrees. That means that we are only rendering about a tenth of the objects in the scene on a 'typical' setup. If your 'ssgRawDraw' isn't doing field-of-view culling then it's going to run something like ten times slower than ssgCullAndDraw for the same scene. However, the only way you can possibly do field of view culling is if you know where the camera is...same problem. It is UTTERLY trivial to modify any program that computes a camera position and passes it to OpenGL to pass that position into SSG instead. Truly - it can't take you more than 5 lines of code. Heck - you could even to a glGetMatrix yourself if you couldn't figure any other way. When you take that little baby step, everything else runs at least 10x faster than what you propose - and it also gets things like level-of-detail and billboards right. ---------------------------- Steve Baker ------------------------- HomeEmail: <sjb...@ai...> WorkEmail: <sj...@li...> HomePage : http://www.sjbaker.org Projects : http://plib.sf.net http://tuxaqfh.sf.net http://tuxkart.sf.net http://prettypoly.sf.net -----BEGIN GEEK CODE BLOCK----- GCS d-- s:+ a+ C++++$ UL+++$ P--- L++++$ E--- W+++ N o+ K? w--- !O M- V-- PS++ PE- Y-- PGP-- t+ 5 X R+++ tv b++ DI++ D G+ e++ h--(-) r+++ y++++ -----END GEEK CODE BLOCK----- |