Time for action—quickly creating simple objects
It is easy to create simple objects by using an osg::Shape
subclass. We will take three typical shapes as examples: a box with different width, height, and depth values, a sphere with a radius value, and a cone with a radius and a height.
- Include necessary headers:
#include <osg/ShapeDrawable> #include <osg/Geode> #include <osgViewer/Viewer>
- Add three
osg::ShapeDrawable
objects successively, each with a type of basic shape. We set these shapes to different positions to make them visible to viewers at the same time, and for the reason of distinguishing them from each other, we color the latter two shapes green and respectively, blue by using thesetColor()
method ofosg::ShapeDrawable:
osg::ref_ptr<osg::ShapeDrawable> shape1 = new osg::ShapeDrawable; shape1->setShape( new osg::Box(osg::Vec3(-3.0f, 0.0f, 0.0f), 2.0f, 2.0f, 1.0f) ); osg::ref_ptr<osg::ShapeDrawable> shape2 = new osg::ShapeDrawable; shape2->setShape( new osg::Sphere(osg::Vec3(3.0f, 0.0f, 0.0f), 1.0f) ); shape2->setColor( osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f) ); osg::ref_ptr<osg::ShapeDrawable> shape3 = new osg::ShapeDrawable; shape3->setShape( new osg::Cone(osg::Vec3(0.0f, 0.0f, 0.0f), 1.0f, 1.0f) ); shape3->setColorS( osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f) );
- An
osg::Geode
object is created, and all the drawables are added to it. Note that the drawables and the geometry node are all managed by theosg::ref_ptr<>
smart pointer here. Theosg::Geode
object is finally used as the scene root of the viewer: - Now it's time to see if these shapes are rendered properly. We don't have to care about the actual drawing work of vertex positions, normals, and colors here, which brings convenience for debugging and quick shape viewing:
What just happened?
The osg::ShapeDrawable
class is useful for quick display, but it is not an efficient way of drawing geometry primitives. It should only be used for quick prototyping and debugging when you develop 3D applications. To create geometries with high performance computation and visualization requirements, the osg::Geometry
class, which is going to be introduced, is always a better choice.
OSG has an internal osg::GLBeginEndAdapter
class that is used to perform basic shape drawing operations. This class enables the use of vertex arrays in the style of a glBegin()
and glEnd()
pair, which makes the implementation of basic shapes easy to understand and extend.
To get and use an initialized osg::GLBeginEndAdapter
object, you should define a class derived from the osg::Drawable
base class and re-implement its drawImplementation()
method, and start programming as if you are writing the classic OpenGL 1.0 drawing calls:
void drawImplementation( osg::RenderInfo& renderInfo ) const { osg::GLBeginEndAdapter& gl = renderInfo.getState()->getGLBeginEndAdapter(); gl.Begin( … ); gl.Vertex3fv( … ); gl.End(); }
More information about re-implementing the osg::Drawable
class can be found in the Implementing your own drawables section of this chapter.