On Thu, Feb 18, 2010 at 8:30 PM, Justin Gondron <[email protected]> wrote:

> Hi,
>
> I'm having a problem sharing statesets between drawables and nodes.  I have
> an example scene that consists of a sphere (pSphere1), a cube (pCube1), and
> two cones (pCone1, pCone2).  The artist applied a material (lambert2SG) to 3
> faces of the cube and the two cones, and a different material (blinn1SG) to
> the other three faces of the cube and the sphere.  They then exported this
> to collada, and we read it in using the osg dae plugin.  We then override
> the materials/textures that are defined in the collada file and apply our
> own materials/shader programs.
>
> So first off, let me explain how I'm applying the materials to shader
> groups, since I may be doing this incorrectly.  What I've found is that the
> drawables associated with a shader group are the same.  For instance, if I
> grab the sphere node pSphere1, then search for a drawable named blinn1SG
> within it's drawablelist, then create a stateset from this drawable and
> apply a shader program to it, it impacts not just the sphere's faces, but
> also impacts the three faces of the cube that the shader group was applied
> to in Maya.  It seems that the collada exporter/importer or some osg
> optimizer groups these all together as a single drawable, is that correct?
>  Is this the recommended way to connect the dots between what a shader group
> is in Maya to what the same group of faces are in OSG?
>
I'm not familiar with the Collada loader, but it's also not entirely clear
what you're doing when you say "create a StateSet from a drawable." OK, it's
clear, but I think it's causing you to misinterpret what's going on.

You don't need to create a state set from an existing object using
getOrCreateStateSet(); you can use new to create one and then assign it to
whatever objects you like. It doesn't sound reasonable that the Collada
loader has created one drawable for all the geometry that shares a shader
group across different high-level objects, unless it and you can be sure
that you never need to manipulate the objects position, etc. seperately. On
the other hand, it is entirely reasonable that the loader created one
StateSet for that shader group, sharing the StateSet between all the
drawables containing geometry that uses the shader group. If you're making
changes to a StateSet that's used by one of these drawables, you'll see it
in all the others that use it. If you're using getOrCreateStateSet to get a
state set from one of these drawables and then bang on it, you're changing
the shared state set.

>
> For now I'll assume that is the correct way and move on to the problem I'm
> seeing.  I've found that if you create a stateset from a drawable or a node,
> then share it to other nodes (not drawables), then everything is drawn
> correctly.  But if I first create a stateset from a drawable or a node, then
> apply the same stateset to another drawable, then some faces and even whole
> objects within the drawable that I'm sharing to don't get drawn correctly.
>  The behavior for these faces/objects is that it's still rendering the
> original texture that was imported from the collada file, even though I'm
> overriding it.  Here are the test cases I went through:
>
> 1. Create StateSet from node pCone1, then share it to drawable blinn1SG -
> The three sides of pCube1 and pCone1 are drawn correctly, pSphere1 not drawn
> correctly
> 2. Create StateSet from node pSphere1, then share it to drawable lambert2SG
> - pSphere1 and the three sides of pCube1 are drawn correctly, the two cones
> not drawn correctly
> 3. Create StateSet from drawable blinn1SG, then share it to node pCone1 -
> All appropriate faces drawn correctly
> 4. Create StateSet from drawable blinn1SG, then share it to drawable
> lambert2SG - Neither pCone1 or pCone2 drawn correctly, everything else drawn
> correctly
> 5. Create StateSet from drawable lambert2SG, then share it to node pSphere1
> - All appropriate faces drawn correctly
> 6. Create StateSet from drawable blinn12SG, then share it to node pCone1,
> then share it to node pCone2 - All appropriate faces drawn correctly
> 7. Create StateSet from node pCone1, then share it to node pCone2, then
> share it to drawable blinn2SG - Everything drawn correctly, except for
> pSphere1 not drawn correctly
> 8. Create StateSet from drawable lambert2SG, then share it to node
> pSphere1, then share it to node pCylinder1 - All appropriate faces drawn
> correctly
>
> Just a guess, but the names of the drawables aren't necessarily unique
across all the objects. As I said above, it would be a very agressive
optimization to actually share geometry across all these objects. However, a
drawable named "blinn12SG" might very well have the StateSet associated with
that shader group.

> So as best I can summarize, my problem seems to be the following:
> 1. If you create a stateset and apply it to a drawable, then share it to
> other nodes (not drawables), then everything is drawn correctly.
> 2. If you create a stateset and apply it to a node or a drawable, then
> share it to another drawable, then some objects/faces within the drawable
> that the stateset was shared to are not drawn correctly.
>
> The way that I am sharing statesets is the following:
> - Keep a map of the artist's material names to OSG's statesets:
>  std::map<std::string, osg::ref_ptr<osg::StateSet> >
> - When a material is being bound to a node, see if the stateset already
> exists for this material in the map
> - If not, create it with Node::getOrCreateStateSet()
> - If so, reuse the stateset with Node::setStateSet(stateSetInMap)
> - Similarly, when a material is being bound to a "shader group", see if the
> stateset already exists for this material in the map
> - If not, create it with Drawable::getOrCreateStateSet()
> - If so, reuse the stateset with Drawable::setStateSet(stateSetInMap)
>
Don't use getOrCreateStateSet here, unless you know exactly what you're
doing. You could use that to make a copy, and then manipulate the copy,
assign it to other drawables, etc.

>
> To find the objects and shader groups that they've specified, I'm using my
> own FindDrawableVisitor and FindNodeVisitor.  Let me know if you need to see
> these to see how I'm finding the nodes/drawables, in case I'm doing this
> part of it incorrectly.
>
> Thanks!
>
I think you're being confused by sharing of StateSets within the loaded
graph.

Tim
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to