Explicitly requesting default state for attribute

13 views
Skip to first unread message

Chris Djali / AnyOldName3

unread,
Dec 11, 2020, 2:38:26 PM12/11/20
to OpenSceneGraph Users
Hi,

I'm working on a node visitor that converts FFP state to shaders and am extending it so it can handle more than it used to. To avoid unnecessary state switches for things now handled by my shaders, I'm attempting to remove fixed-function-related state from the nodes which have had shaders set up.

With modes, this works well - I can just set them off and protected, and the glEnable/glDisable calls go away. However, it's proving difficult to achieve the same behaviour with StateAttributes. The obvious solution would be removing the attribute from the StateSet it's attached to, but it might be higher in the scenegraph so also affect nodes which aren't having shaders attached, so it's only really safe to modify the stateset the shader program gets attached to.

So far, the best thing I've got is default-constructing the particular StateAttribute I'm interested in and attaching that to the stateset. This means the default state is set when the draw call happens, but I can see a lot of apply calls (resulting in a lot of GL calls) toggling between this copy of the default attribute and the copy in the state's attribute stack (via applyGlobalDefaultAttribute). I don't think it's wildly different from the number of unnecessary GL calls I was getting before I tried this.

A solution that I think would work would be calling getGlobalDefaultAttribute on the State object as then the pointers would compare equal and the apply call would get skipped, but I don't have any clean way of getting the State instance to my visitor.

Ideally, there'd be some neat trick I've missed that lets me say "any subgraph of this node doesn't care about this attribute type, so set the default/leave whatever's there from the last draw call" that would work with the normal state composition mechanisms so I could override it from a parent stateset or make it protected so it couldn't be overridden by parent statesets. Maybe a custom StateAttribute could do that, but maybe someone on this mailing list knows something I don't already.

Cheers,

Chris

Chris Djali / AnyOldName3

unread,
Dec 18, 2020, 9:07:03 PM12/18/20
to OpenSceneGraph Users
I figured out a solution:
* Subclass the attribute in question. Make the subclass' apply do nothing.
* Apply the subclassed attribute to the root of the scene graph's stateset - this protects against the State instance encountering the unmodified attribute first, so cloneType-ing that, making the global default attribute not get applied repeatedly, and not have any OpenGL calls if it does.
* Apply the subclassed attribute anywhere that doesn't care.
* Apply the regular attribute anywhere that does care, including places that needed the regular default state.

Hopefully, this relatively simple solution shows up for anyone searching for this in the future.

Cheers,

Chris

Reply all
Reply to author
Forward
0 new messages