Slide set

advertisement
OpenSceneGraph
based on materials from http://www.openscenegraph.org/
Katia Oleinik: koleinik@bu.edu
Agenda:
•
•
•
•
•
•
•
•
•
Introduction to OpenSceneGraph
Hardware requirements
Overview of OSG structure
First example – displaying a model
Building primitives
Transformations
Using OpenGL primitives
Texture
Special nodes
 Introduction to OpenSceneGraph
OpenSceneGraph
• an open source 3D graphics API (application programming interface)
• used for
- visual simulation,
- computer games,
- scientific visualization,
- modeling,
- training, etc.
 Introduction to OpenSceneGraph
OpenSceneGraph
• written in C++ (encourages object oriented programming);
• runs on a number of operating systems, including:
- MS Windows
- Max OS X
- Linux
- IRIX
- Solaris
- Sony Playstation
uses OpenGL for rendering (allows for high performance graphics);
supports the standard template library (STL);
 Introduction to OpenSceneGraph
OpenSceneGraph 3.0 Features:
• Support for performance increasing features
o View frustum, small feature and occlusion culling
o Level of detail (LOD)
o State sorting and lazy state updating
o OpenGL latest extensions
o Multi-threading and database optimization
• Support for OpenGL, from 1.1 through 2.0 including the latest extensions
• Support for OpenGL Shading Language
• Support for a wide range of 2D image and 3D database formats
• Loaders available for OpenFlight, TerraPage, OBJ, 3DS, JPEG, PNG and GeoTIFF
• Particle effects
• Support for anti-aliased TrueType text
• Multi-threaded and configurable support for multiple CPU/multiple GPU machines
 Introduction to OpenSceneGraph
OpenSceneGraph 3.0 latest updates:
•
•
•
•
Support for Windows MS Visual Studio
Support for Android on tablets and phones
Support for IOS (iPhone OS) on tablets and phones
Improvements to osgVolume class enabling high quality volume rendering
FightGear Flight Simulator
FightGear Flight Simulator
FightGear Flight Simulator
 Hardware requirements
Processor
• OSG runs on most contemporary CPUs.
• OSG is thread-safe and can take advantage of multi-processor and
dual core architectures.
• OSG runs on both 32- and 64-bit processors.
Graphics
• OSG requires graphics hardware with robust OpenGL support
• 256 MB of graphics RAM – good starting point
RAM
• 1GB – good enough for many application, but you might need more,
depending on your dataset
Disc
• Depends on your data requirements
 Overview of OSG structure
 Overview of OSG structure
Root
Matrix
Geode
Drawable
Transformation
Geode
Transformation
Geode
Drawable
Matrix
Drawable
 First example – displaying a model
• ex_simple_viewer.cpp
// load the nodes from the command line arguments.
osg::Node* model = osgDB::readNodeFile(argv[1]);
// initialize the viewer and set the scene to render
osgViewer::Viewer viewer;
viewer.setSceneData(model);
// run viewer
return viewer.run();
Root
Node
 First example – displaying a model
• ex_simple_viewer.cpp: compiling, linking and running
To compile and link
% make ex_simple_viewer
To run the viewer
% ex_simple_viewer cow.obj
First button – rotate the model
Second button – translate
Third button – scale
Press “q” (“Esc” for Windows) button to exit
 First example – displaying a model
• ex_viewer_args.cpp
// call argument parser
osg::ArgumentParser arguments (&argc, argv);
std::string filename;
// define the argument line option
arguments.read("--model", filename);
// load the nodes from the command line arguments
osg::Node* model = osgDB::readNodeFile(filename);
 First example – displaying a model
• ex_viewer_args.cpp: running
To compile and link
% make ex_viewer_args
To run the viewer
% ex_viewer_args –-model cow.obj
Try a few different models:
dumptruck.osg
teapot.osg
 First example – displaying a model
• Input OSG model file structure
Geode {
name "teapot.osg"
nodeMask 0xffffffff
cullingActive TRUE
num_drawables 1
Geometry {
DataVariance STATIC
useDisplayList FALSE
useVertexBufferObjects TRUE
PrimitiveSets 1
{
DrawArrays TRIANGLES 0 9744
}
VertexArray Vec3Array 9744
{
0.367875 -0 0.237053
0.375 -0 0.225
0.365248 0.086895 0.225
.....
}
ColorBinding OVERALL
ColorArray Vec4Array 1
{
1 1 1 1
}
}
}
 Building geometric primitives
• ex_simple_cone.cpp
// Create a vector to represent the "center of the cone"
Vec3 vcen(xcen, ycen, zcen);
osg::Cone* cone = new Cone(vcen, radius, height);
cone
// Create a drawable object based on the cone
osg::ShapeDrawable *drawable = new ShapeDrawable(cone);
// create a new geode (root node)
osg::Geode* geode = new Geode();
geode->addDrawable(drawable);
Root
Node
Drawable
Geode
 Building geometric primitives
• Improving ex_simple_cone.cpp
// Create a vector to represent the "center of the cone"
osg:: Vec3 vcen(xcen, ycen, zcen);
osg::Cone* cone = new Cone(vcen, radius, height);
cone
// Create a drawable object based on the cone
osg:: ShapeDrawable *drawable = new ShapeDrawable(cone);
drawable->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
Drawable
// create a new geode
osg:: Geode* geode = new Geode();
geode->addDrawable(drawable);
Geode
// create a root node
osg::Group *root = new osg::Group();
root->addChild(geode);
Root
Node
 Building geometric primitives
• ex_simple_cone.cpp
To compile and link
% make ex_simple_cone
To run the viewer
% ex_simple_cone
 Building geometric primitives
• ex_simple_cone.cpp
OSG comes with a number of primitives






Box
Sphere
Cone
Cylinder
Capsule
Special shapes (e.g. InfinitePlane)
• ex_arrow.cpp
// Create a cone and a cylinder
Geode *make_cone( float xcen, …){}
Geode *make_cylinder( float xcen, …){}
 Building geometric primitives
cone
cylinder
// create an arrow, as a transform node
MatrixTransform* arrow = new MatrixTransform;
arrow->setMatrix(Matrix::scale(1.0, 1.0, 1.0));
arrow->addChild(cone); arrow->addChild(cylinder);
Transform
Matrix
// add the arrow to the upper transform
MatrixTransform* mt = new MatrixTransform();
mt->setMatrix(
Matrix::rotate(inDegrees(30.0), 1.0, 0.0, 0.0)); Transform
Matrix
mt->addChild(arrow);
// create a root node
osg::Group *root = new osg::Group();
root->addChild(mt);
Root
Node
• Exercise Building 3 arrows
 Building geometric primitives
cone
cone
cone
cylinder
cylinder
cylinder
Transform
Matrix
Transform
Matrix
Transform
Matrix
Root Node
Transform
Matrix
• Exercise: Building 3 arrows
 Building geometric primitives
Group *make_vec_arrow(float shaft_radius, float total_length,
float r, float g, float b)
{
float cone_radius = 2*shaft_radius;
float cone_height = cone_radius;
float shaft_length = total_length - cone_height;
osg::Geode *cylinder = make_cylinder(0.0, 0.0, shaft_length/2.0,
shaft_radius, shaft_length, r,g,b,1.0);
osg::Geode *cone = make_cone(0.0, 0.0, shaft_length + cone_height/4.0,
cone_radius, cone_height, r, g, b, 1.0);
osg::Group* vec_arrow = new Group;
vec_arrow->addChild(cylinder);
vec_arrow->addChild(cone);
return vec_arrow;
}
osg::Group *red_arrow
= make_vec_arrow(…);
osg::MatrixTransform* xaxis = new MatrixTransform;
xaxis->addChild(red_arrow);
xaxis->setMatrix(…);
• Reusing the geometry
 Building geometric primitives
Faces
Vertices
Colors
Geometry
Geode 1
Transform
Matrix
Geode 2
Geode 3
Transform
Matrix
Transform
Matrix
Transform
Matrix
Root Node
• PrimitiveSet Class
1
3
4
3
2
Lines
2
1
2
0
1
LineStrip
1
2
3
4
3
4
0 3
Points
0
4
1
2
 Using OpenGL primitives
3
2
4
0
1
LineLoop
5
6
0
1
Triangles
Polygon
2
3
0
1
Quads
0
2
4
TriangleStrip
1
0
4
0
5
7
2
4
QuadStrip
6
3
5
3
1
2
TriangleFan
• PrimitiveSet Class
 Using OpenGL primitives
osg::Group *root = new osg::Group();
Group
…
osg::Geode* primGeode = new osg::Geode();
root->addChild(primGeode);
Geode
…
osg::Geometry* primGeom = new osg::Geometry();
primGeode->addDrawable(primGeom);
Geometry
…
viewer.setSceneData(root)
Vertices
Faces
Colors
Texture
• PrimitiveSet Class
osg::Vec3Array* pyramidVertices = new osg::Vec3Array;
pyramidVertices->push_back( osg::Vec3( 0, 0, 0) ); //
pyramidVertices->push_back( osg::Vec3(10, 0, 0) ); //
pyramidVertices->push_back( osg::Vec3(10,10, 0) ); //
pyramidVertices->push_back( osg::Vec3( 0,10, 0) ); //
pyramidVertices->push_back( osg::Vec3( 5, 5,10) ); //
 Using OpenGL primitives
front left
front right
back right
back left
peak
// create primitives: quad for the base
osg::DrawElementsUInt* pyramidBase =
new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
pyramidBase->push_back(3);
pyramidBase->push_back(2);
pyramidBase->push_back(1);
pyramidBase->push_back(0);
// create primitives: triangles for the sides
osg::DrawElementsUInt* pyramidFaceOne =
new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
pyramidFaceOne->push_back(0);
pyramidFaceOne->push_back(1);
pyramidFaceOne->push_back(4);
• PrimitiveSet Class
 Using OpenGL primitives
// assign all primitives to the Geometry node
osg::Geometry* pyramidGeometry = new osg::Geometry();
pyramidGeometry->setVertexArray( pyramidVertices );
pyramidGeometry->addPrimitiveSet(pyramidBase);
pyramidGeometry->addPrimitiveSet(pyramidFaceOne);
pyramidGeometry->addPrimitiveSet(pyramidFaceTwo);
pyramidGeometry->addPrimitiveSet(pyramidFaceThree);
pyramidGeometry->addPrimitiveSet(pyramidFaceFour);
geometry
// create a geode and add the geometry to the geode
osg::Geode* pyramidGeode = new osg::Geode();
pyramidGeode->addDrawable(pyramidGeometry);
Geode
// Create a root node and add the geode
osg::Group* root = new osg::Group();
root->addChild(pyramidGeode);
Root
Node
• PrimitiveSet Class
// create an array of colors
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f,
colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f,
colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f,
colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f,
 Using OpenGL primitives
1.0f)
1.0f)
1.0f)
1.0f)
);
);
);
);
//index
//index
//index
//index
0
1
2
3
red
green
blue
white
// create an index array
osg::TemplateIndexArray
<unsigned int, osg::Array::UIntArrayType,4,4> *colorIndexArray;
colorIndexArray =
new osg::TemplateIndexArray<unsigned int, osg::Array::UIntArrayType,4,4>;
colorIndexArray->push_back(0); // vertex 0 assigned color array element 0
colorIndexArray->push_back(1); // vertex 1 assigned color array element 1
colorIndexArray->push_back(2); // vertex 2 assigned color array element 2
colorIndexArray->push_back(3); // vertex 3 assigned color array element 3
colorIndexArray->push_back(0); // vertex 4 assigned color array element 0
// assign the arrays to the geometry
pyramidGeometry->setColorArray(colors);
pyramidGeometry->setColorIndices(colorIndexArray);
pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
 Transformations
OSG allows for hierarchies of transformation node. Such structure makes it
much easier to control the motions of each limb, part or the whole body.
transform
transform
geode
geode
transform
transform
geode
geode
transform
geode
 Transformations
OSG MatrixTransform Class:
// direct transformation specification
transform->getMatrix();
transform->setMatrix();
// set identity
Identity();
// navigation
osg::Matrix mt1 = osg::Matrix::Translate(x, y, z);
osg::Matrix mt2 = osg::Matrix::Rotate(angle, x, y, z);
osg::Matrix mt3 = osg::Matrix:: Scale(x, y, z);
// for multiplying matrices
osg::Matrix resultMat = mt1 * t2 * mt3;
// invert matrix
osg::Matrix::Invert();
 AddingTexture
// initialize texture class
osg::Texture2D* texture = new osg::Texture2D;
texture->setDataVariance(osg::Object::DYNAMIC);
Any file format supported
by the plugins
// load the texture image from the file:
osg::Image* texImage = osgDB::readImageFile(texture_file);
if (! texImage){
std::cout << " couldn't find texture, quiting." << std::endl;
return -1;
}
// Assign the texture to the image we read from file:
texture->setImage(texImage);
// Create a new StateSet with default settings:
osg::StateSet* stateTex = new osg::StateSet();
// Assign texture unit 0 of our new StateSet to the texture
// enable the texture.
stateTex->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
// Associate this state set with the Geode that contains
// the primitive:
geode->setStateSet(stateTex);
• Exercise: Reading texture
from the command line
// Add parsing texture option from a command line
// call argument parser
osg::ArgumentParser arguments (&argc, argv);
std::string filename;
// define the argument line option
arguments.read("--texture", texfilename);
osg::Texture2D* texture = new osg::Texture2D;
texture->setDataVariance(osg::Object::DYNAMIC);
// load the texture image from the file:
osg::Image* texImage = osgDB::readImageFile(texture_file);
if (! texImage){
std::cout << " couldn't find texture, quiting." << std::endl;
return -1;
}
…
 AddingTexture
 Special Nodes
Switch node
- Node for switching between different states of an object
LOD node - Rendering Optimization node
Billboard node – rendering optimization node
Text node – node for presenting text on the screen
 Special Nodes
LOD (“level of detail” node - Rendering Optimization node
This node “switches” based on the distance from the viewer to the object.
It works like a regular group node: load.addChild(detailedNode);
Set the visible range from the viewer to the object:
load.setRange(childNumber, near, far);

 Special Nodes
LOD lod = new LOD();
Lod.addChild(detailedNode);
Lod.setRange(0, 0, 10);
Lod.addChild(NotSodetailedNode);
Lod.setRange(1, 10, 100);
Lod.addChild(CorseNode);
Lod.setRange(2, 100, 1000);
Lod.addChild(NoDetailNode);
Lod.setRange(2,1000,10000);
For up-to-date information on the project, in-depth details on how
to compile and run libraries and examples, see the documentation
on the OpenSceneGraph website:
http://www.openscenegraph.org
For support subscribe to OSG public mailing list:
http://www.openscenegraph.org/projects/osg/wiki/MailingLists
or forum:
http://forum.openscenegraph.org
Contact me: Katia Oleinik: koleinik@bu.edu
Tutorial presentations and examples online:
www.bu.edu/tech/research/training/presentations/list/
Online evaluation:
http://scv.bu.edu/survey/tutorial_evaluation.html
Resources
• BU Scientific Computing and Visualization:
http://www.bu.edu/tech/research/scv/
• OpenSceneGraph: http://www.openscenegraph.org/
Autodesk Maya
Download