Object Ownership
-
new osg::Class without a matching delete is an OSG programming idiom.
-
Internally, OSG is based on smart pointers with intrusive reference-counts (OSG::Referenced).
-
Passing an OSG object to an OSG API function transfers ownership to OSG.
The graph will own what was attached by addChild().
-
osg::ref_ptr
If an app needs to hold onto an OSG object after passing it to an OSG API function,
the app must store it inside a osg::ref_ptr in order to increment its reference-count
(to avoid unexpected deletion).
Matrix, Transform
Rotating a matrix can be done by making a rotation matrix, then doing matrix multiplication.
Eg, to animate rotating an aircraft by 1 degree every frame,
pre-compute a 1 degree rotation matrix from an identity matrix,
then multiply it by a transform's matrix every frame.
The rotation matrix can remain unchanged until the angle (rotation rate) has to change.
class
{
osg::ref_ptr<osg::MatrixTransform> mTransform; // rotated every frame
osg::ref_ptr<osg::Matrix> mRotationMatrix; // coefficient of matrix multiplication
};
// Make a rotation matrix:
mRotationMatrix.makeRotate( degree, osg::Vec3f( 1.0f, 0.0f, 0.0f ) ); // X axis
// Rotate matrix every frame (matrix of OSG::MatrixTransform):
...
osg::Matrix m = mTransform->getMatrix();
m = mRotationMatrix * m;
mTransform->setMatrix( m );
Matrix Multiplication, Rotating Around Which Axis
Rotation of a matrix can be either in object space or fixed space.
Long way: Read a linear algebra textbook and study premultiply or postmultiply.
Short way: Run your program: if rotation is wrong, swap the coefficients.
m = mRotationMatrix * m; // rotate around local axis
m = m * mRotationMatrix; // rotate around fixed axis
Blending
Blending in OSG is similar to OpenGL,
with the addition of using OSG's transparent bin
(essentially another rendering pass) for transparent primitives.
// Enable blending, select transparent bin.
stateSet->setMode( GL_BLEND, osg::StateAttribute::ON );
stateSet->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
// Enable depth test so that an opaque polygon will occlude a transparent one behind it.
stateSet->setMode( GL_DEPTH_TEST, osg::StateAttribute::ON );
// Conversely, disable writing to depth buffer so that
// a transparent polygon will allow polygons behind it to shine thru.
// OSG renders transparent polygons after opaque ones.
osg::Depth* depth = new osg::Depth;
depth->setWriteMask( false );
stateSet->setAttributeAndModes( depth, osg::StateAttribute::ON );
// Disable conflicting modes.
stateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF );