A Geometry is derived from Drawable (isn't a Node).
A Geode is a Node that has a Drawable attached to it.
Hence the name "geode" (a Node with a Geometry).
Drawable --> Geometry
Node --> Geode
geode->addDrawable( geometry );
modes vs. attributes:
OSG modes directly correlate to OpenGL modes such as shading and blending.
Attributes are the parameters of a mode such as the shade model and blend function.
OSG defines attributes as set of classes derived from StateAttribute (BlendFunc, etc).
A mode is part of a StateSet, so:
osg::StateSet::setMode()
For convenience, both an attribute and mode can be set by setAttributeAndModes():
osg::BlendFunc* bf = new osg::BlendFunc();
state->setAttributeAndModes( bf, osg::StateAttribute::ON );
state->setAttributeAndModes( bf ); // ON is implied
Inheriting state:
A child inherits state from its parent.
OVERRIDE forces applying a state to all children, regardless.
PROTECTED makes an exception to OVERRIDE, allowing a child to "override OVERRIDE".
BY DEFAULT, STATE-SET IN A CHILD NODE OVERRIDES
THE *SAME* TYPE OF STATE-SET IN A PARENT NODE [Martz].
A
/ \
B C
A sets a blue color.
B sets a red color.
C doesn't change color.
What color will C be?
C will be the same color as B (suprise) because OSG will let
the last glColor() remain in effect (applied when B was visited).
The "return traversal" from B --> A doesn't restore nor pop OpenGL state.
This isn't peculiar to OSG (this is fundamental behavior of any scene graph).
Disabling nodes:
node->setNodeMask(0)
This can effectively disable not-so-obvious nodes such as Cameras etc.
Visitor pattern, NodeVisitor, apply():
OSG names the Visitor design pattern's visit() method as apply().
A derivative of NodeVisitor should override apply().
class Visitor : public osg::NodeVisitor
{
virtual void apply( osg::Node& node ) // visit() method
{
...
// Keep searching.
traverse( node );
}
};
Screenshot, recording an image:
osg::Image* shot = new osg::Image();
shot->allocateImage(width, height, 24, GL_RGB, GL_UNSIGNED_BYTE);
camera->attach(osg::Camera::COLOR_BUFFER, shot);
osgDB::writeImageFile(*shot,"image_file.png");
Then Viewer has to render a frame in order to get a screenshot.
Direct rendering:
OSG provides different ways to directly issue OpenGL calls:
1. osg::Operation callback of an osg::Window (Palomino uses this for motion-blur).
2. osg::Camera::DrawCallback
3. derivative of osg::Drawable
The first two ways renders per-frame.
The third way (osg::Drawable) renders per-node.
An excellent example of rendering per-node (osg::Drawable) is osgteapot.
class Teapot : public osg::Drawable
{
virtual void drawImplementation( osg::RenderInfo& ) const;
// We need to set up the bounding box of the data too, so that the
// scene graph knows where this object is, for both positioning
// the camera at start up, and most importantly for culling.
virtual osg::BoundingBox computeBound() const;
};
render bins:
[Martz]
"Subject: Re: [osg-users] Render Queue
The osgUtil::CullVisitor creates RenderBins (render bins) from the visible Drawables,
then each RenderBin is processed. So, take a look at CullVisitor and RenderBin.
Then also look at, for example, osg::Geometry::apply to see how Geometry is
sent to OpenGL. You can capture the OpenGL commands with a tool like GLIntercept.
This will show you what OSG is doing to render the scene."
[Osfield]
"The state sorting in the OSG is done as part of the cull traversals
when the various Drawables and Stateset's are placing in the rendering
backend, composed of RenderBin/RenderStages and a StateGraph. When a
RenderBin is state sorted sorting is done via an STL map container,
sorting purely on the ptr to the StateSet. In the default state
sorting no fine grained start sorting is done - so contents of
StateSet aren't compared. Its possible to enable fine grained state
sorting but I've found that the cost of such sorting generally
outweighs the benefits, what is done by default appears to be a good
compromise between low CPU overhead and efficient use of the GPU."
To disable lighting:
PROTECTED doesn't work but OVERRIDE does.
mSwitchNode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF );
multiple lights:
osg::Light is a state attribute;
osg::LightSource is a Group.
Only one osg::Light can be attached to a osg::LightSource.
So to enable multiple lights, build a linear chain of LightSources (light groups).
Then add geometry at the end of the chain.
root
|
V
lightSource 0
|
V
lightSource 1
|
V
geodes
To handle the ESC key:
viewer->setKeyEventSetsDone( 0 );
Cameras:
Cameras define the 3D modelview matrix, 2D viewpoint, and render target.
Cameras are attached to the GraphicsContext of a GraphicsWindows.
Cameras can either be attached as a node to the scene graph (old way),
or added to an osg::Viewer (new way).
Manipulators control a camera.
Thus a manipulator will effectively define the modelview matrix.
Use Manipulator::getInverseMatrix() to extract a modelview matrix.
A camera defines the rendering target.
Rendering to different 2D viewports of a window, each with its own viewpoint,
is done in OSG by adding more cameras.
Rendering to a texture (RTT) is done thru an osg::Camera also.
Set the "render target" of the camera to a texture.
Callbacks to invoke before/after a view is drawn can be registered by osg::Camera.
To enable windowed-mode in Viewer:
viewer.setUpViewInWindow( 0, 0, 1024, 768 );