from chapter 4:
How OpenGL draws objects
OpenGL uses geometry primitives to draw different objects in the 3D world. A geometry primitive, which may be a set of points, lines, triangles, or polygonal faces, determines how OpenGL sorts and renders its associated vertex data. The easiest way to render a primitive is to specify a list of vertices between the glBegin() and glEnd() pair, which is called immediate mode, but it is inefficient in most cases.
The vertex data, including vertex coordinates, normals, colors, and texture coordinates, can also be stored in various arrays. Primitives will be formed by dereferencing and indexing the array elements. This method, named vertex array, reduces redundant shared vertices and thus performs better than immediate mode.
Display lists also significantly improve application performance, because all vertex and pixel data are compiled and copied into the graphics memory. The prepared primitives can be reused repeatedly, without transmitting data over and over again. It helps a lot in drawing static geometries.
The vertex buffer object (VBO) mechanism allows vertex array data to be stored in high-performance memory. This provides a more efficient solution for transferring dynamic data. By default, OSG uses vertex arrays and display lists to manage and render geometries. However, this may change depending on different data types and rendering strategies.
----- We would like to also call attention to the removal of immediate mode and display lists in OpenGL ES and OpenGL 3.x, for the purpose of producing a more lightweight interface. Of course OpenGL 3.x and further versions will keep these deprecated APIs for backward compatibility. ---- However, they are not recommended to be used in new code.
Geode and Drawable classes
The osg::Geode class corresponds to the leaf node of a scene graph. It has no child nodes, but always contains geometry information for rendering. Its name Geode is short for geometry node. The geometry data to be drawn are stored in a set of osg::Drawable objects managed by osg::Geode. The non-instantiatable osg::Drawable class is defined as a pure virtual class. It has several subclasses for rendering models, images, and texts to the OpenGL pipeline. These renderable elements are collectively called drawables.
The osg::Geode class provides a few methods to attach and detach drawables, as well as collect information about them:
1. The public method addDrawable() takes an osg::Drawable pointer as its parameter and attaches a drawable to the osg::Geode instance. All drawables added are internally managed by the osg::ref_ptr<> smart pointer.
2. The public methods removeDrawable() and removeDrawables() will detach one or more drawables from the current osg::Geode object, and decrease their referenced counting number as well. The removeDrawable() method uses an osg::Drawable pointer as the only parameter, and removeDrawables() accepts two parameters: the zero-based index of the start element, and number of elements to be removed.
3. The getDrawable() method returns the osg::Drawable object stored at the specified zero-based index.
4. The getNumDrawables() method returns the total number of attached drawables. Developers are then able to traverse each drawable in a cycle with the getDrawable() method, or remove all drawables at once by using the following code: geode->removeDrawables( 0, geode->getNumDrawables() );
-------------------------------
Storing array data
As already mentioned in earlier chapters, OSG supports vertex arrays and VBO to speed up the rendering process. To manage the vertex data used in these two mechanisms, OSG defines a basic osg::Array class and a few derived classes for commonly used array and index array types.
The osg::Array class can't be instantiated, but it declares interfaces to exchange with OpenGL calls and buffer data modifiers. Its subclasses (osg::Vec2Array, osg::Vec3Array, osg::UIntArray, etc.) inherit the characteristics of the Standard Template Library vector class, and can thus make use of all of the std::vector members, including push_back(), pop_back(), size(), and STL algorithms and iterators.
The following code will add a three-element vector to an existing osg::Vec3Array object named vertices: vertices->push_back( osg::Vec3(1.0f, 0.0f, 0.0f) );
The OSG built-in array classes should be allocated from heap and managed by smart pointers. However, it is not necessary for the array elements such as osg::Vec2 and osg::Vec3 to follow this rule, as they are very basic data types.
The osg::Geometry class acts as the high-level wrapper of the OpenGL vertex array functionality. It records different types of arrays and manages a geometry primitive set to render these vertex data in an orderly manner. It is derived from osg::Drawable class and can be added to an osg::Geode object at any time. This class accepts arrays as basic data carriers and uses them to produce simple or complex geometry models.
Vertices and vertex attributes
The Vertex is the atomic element of geometry primitives. It uses several numeric attributes to describe a point in 2D or 3D spaces, including vertex position, color, normal and texture coordinates, fog coordinate, and so on. The position value is always required, and other attributes will help to define the nature of the point. OpenGL accepts up to 16 generic attributes to be specified per vertex, and can create different arrays in which to store each of them. All attribute arrays are supported by the osg::Geometry class with the corresponding set*Array() methods.
-------------------------
From chapter 5 start:
The Group interface The osg::Group type represents the group nodes of an OSG scene graph. It can have any number of child nodes, including the osg::Geode leaf nodes and other osg::Group nodes. It is the most commonly-used base class of the various NodeKits—that is, nodes with various functionalities. The osg::Group class derives from osg::Node, and thus indirectly derives from osg::Referenced. The osg::Group class contains a children list with each child node managed by the smart pointer osg::ref_ptr<>. This ensures that there will be no memory leaks whenever deleting a set of cascading nodes in the scene graph.
The osg::Group class provides a set of public methods for defining interfaces for handling children. These are very similar to the drawable managing methods of osg::Geode, but most of the input parameters are osg::Node pointers.
1. The public method addChild() attaches a node to the end of the children list. Meanwhile, there is an insertChild() method for inserting nodes to osg::Group at a specific location, which accepts an integer index and a node pointer as parameters.
2. The public methods removeChild() and removeChildren() will remove one or more child nodes from the current osg::Group object. The latter uses two parameters: the zero-based index of the start element, and the number of elements to be removed.
3. The getChild() returns the osg::Node pointer stored at a specified zero-based index.
4. The getNumChildren() returns the total number of children.
You will be able to handle the child interface of osg::Group with ease because of your previous experience of handling osg::Geode and drawables.
Managing parent nodes:
We have already learnt that osg::Group is used as the group node, and osg::Geode as the leaf node of a scene graph. Their methods were introduced in the last chapter, and are also used in this chapter. Additionally, both classes should have an interface for managing parent nodes. OSG allows a node to have multiple parents, as will be explained later. In this section, we will f irst have a glimpse of parent management methods, which are declared in the osg::Node class directly:
1. The method getParent() returns an osg::Group pointer as the parent node. It requires an integer parameter that indicates the index in the parent's list.
2, 3,etc