Re: [osg-users] Draw Instanced Help

2011-12-03 Thread Paul Martz

On 12/2/2011 8:04 PM, michael.a.bo...@l-3com.com wrote:

My question is this, if I load a file using

osgDB::readNodeFile(somefile.osg);

How would I set it up for instanced drawing?

My guess is that I would need to write a node-visitor that collects all
of the geometry -  drawables and sets them up to use the instanced call
overload instead of the default. I have tried doing this, but my
implementation has gotten pretty complex, and I want to make sure there
isn't a more simple way I have overlooked.


Yes, you'd need to write a NodeVisitor. It would have an apply(Geode) that 
iterates over each Drawable. If the Drawable is a Geometry, the code would 
further iterate over each PrimitiveSet and call setNumInstances() on each one. 
It really just boils down to a pair of nested loops. This doesn't seem 
particularly complex, so I wonder if you might be doing something different that 
is complicating things. Your description of what you're doing is pretty vague, 
so it's hard to tell.

   -Paul





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


[osg-users] Draw Instanced Help

2011-12-02 Thread Michael . A . Bosse
Hi Everyone,
Sorry, the last copy of this went out without a subject. Please
disregard, it has been a long day.
I'm trying to implement a fairly dense forested area and simply adding
in a bunch of osg::MatrixTransform nodes predictably causes the cull to
crash. I could try reorganizing the scene around an oct-tree as was
suggested by a previous discussion on this topic, but for draw
performance reasons, since each tree is the same model, I would like to
use the new draw instanced arb. I see that osgdrawinstanced has been
referenced in many similar threads, but osgdrawinstanced creates its
geometry on the fly, and in doing so can quite easily use the command
syntax for instancing. I am trying to apply the technique to a loaded
model and there is no obvious easy method.

My question is this, if I load a file using 

osgDB::readNodeFile(somefile.osg); 

How would I set it up for instanced drawing? 

My guess is that I would need to write a node-visitor that collects all
of the geometry - drawables and sets them up to use the instanced call
overload instead of the default. I have tried doing this, but my
implementation has gotten pretty complex, and I want to make sure there
isn't a more simple way I have overlooked.

Thank you very much for your time.

Michael A Bosse'

___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Draw Instanced Help

2011-12-02 Thread Jean-Sébastien Guay

Hi Michael,


How would I set it up for instanced drawing?

My guess is that I would need to write a node-visitor that collects all
of the geometry -  drawables and sets them up to use the instanced call
overload instead of the default. I have tried doing this, but my
implementation has gotten pretty complex, and I want to make sure there
isn't a more simple way I have overlooked.


You've got the right idea for the general way to apply instanced 
rendering for complex objects. But you can simplify usage by making your 
model simpler.


Draw instanced will work really well if your model consists of a single 
primitiveset. So ideally you'll have your modeler create the tree in a 
single geometry with a single primitiveset. They can make a texture 
atlas so that the same texture file applies to the whole geometry, and 
then merge all the geometry into a single one.


If this is not possible, you can try using the osgUtil::Optimizer to do 
this for you as a pre-process. Using the artist's model as input, you 
would apply the SHARE_DUPLICATE_STATE, FLATTEN_STATIC_TRANSFORMS, 
MERGE_GEODES, MERGE_GEOMETRY, VERTEX_PRETRANSFORM, VERTEX_POSTTRANSFORM, 
INDEX_MESH and possibly TEXTURE_ATLAS_BUILDER optimizers on it. I use 
this combination on all models by the way, in combination with a few 
custom visitors it does wonders to cull and draw times. What these will do:


TEXTURE_ATLAS_BUILDER: Will merge many small textures into a single 
larger one, adjusting texture coordinates, which can then be shared by 
all those nodes. An artist-created texture atlas is better though, I've 
seen cases where the texture atlas builder in OSG will create a really 
large texture and use less than half the space in it, and other such 
inefficiencies. A human will also be better equipped to judge of the 
qualitative criteria in making some textures smaller thus fitting more 
textures into a single atlas.


SHARE_DUPLICATE_STATE: Make sure identical state is shared (uses the 
same pointer to the same object) instead of having multiple state 
attributes with the same value throughout your model. You might have to 
write a small visitor to help this optimizer a bit, essentially 
normalizing all state that your modeling tool might set differently from 
what you expect, but which has no effect on the final output. For 
example you could force all geometry to single sided, etc. The idea is 
to make sure the next steps will be able to merge as much as possible.


FLATTEN_STATIC_TRANSFORMS: Remove any transforms that are marked as 
static data variance. You might have to make a small visitor that will 
change the data variance to static on any transforms that you don't 
really need. Modeling programs have a tendency to put lots of transforms 
all over the place (in Maya for example, there are no groups, everything 
is a transform, even graph leaves are a transform plus a geometry...). 
Again this will make the next steps work more efficiently, because 
things that are separated by a transform can't be merged together. You 
might want to write another simple visitor that would remove unnecessary 
Group nodes. Once again things that are separated by a Group can't be 
merged together.


MERGE_GEODES, MERGE_GEOMETRY: Merge as many scene graph leaves together 
as possible. Again this will make the next steps work more efficiently. 
Note that the MERGE_GEODES optimizer in OSG has a pretty serious design 
flaw, it will only merge Geodes whose direct parent is a Group, and not 
any Group subclass. Sure, merging the children of an LOD node or Switch 
node is bad, but there are plenty of other subclass es of Group where it 
makes no difference. So I just subclassed the MergeGeodesVisitor so it 
checks the actual type of the parent, doesn't merge if it's certain 
types of Group subclasses (like LOD or Switch) but merges in all other 
cases.


VERTEX_PRETRANSFORM, VERTEX_POSTTRANSFORM, INDEX_MESH: This is a 
powerful trio of optimizers that will turn DrawArrays into DrawElements 
optimized for the GPU's cache, and merge all primitivesets under a 
Geometry together. After this, you might want to run the MERGE_GEODES 
and MERGE_GEOMETRY optimizers again, as they will be able to merge even 
more things together.


So anyways, I described why you would want to use the various optimizers 
for general models, but for your trees the goal is to end up with a 
single Geometry which has a single primitiveset. Then your job of doing 
instanced drawing of this tree becomes much easier. And again, if you 
can get your artist / modeler to make the model with this in mind, all 
the better. In general, if you can massage the data in order to make the 
code simpler, it's normally a win in the long run.


Hope this helps,

J-S
--
__
Jean-Sebastien Guayjean-sebastien.g...@cm-labs.com
   http://www.cm-labs.com/
http://whitestar02.dyndns-web.com/