Added proper implementations of OpenGL 1.0 calls to OSG object representation methods in SceneGraphBuilder.

This commit is contained in:
Robert Osfield 2008-03-12 20:15:28 +00:00
parent eb9f7428bc
commit db256b962c
2 changed files with 397 additions and 24 deletions

View File

@ -14,10 +14,10 @@
#ifndef OSGUTIL_SCENEGRAPHBUILDER
#define OSGUTIL_SCENEGRAPHBUILDER 1
#include <osg/NodeVisitor>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/MatrixTransform>
#include <osg/GLU>
#include <osgUtil/Export>
@ -31,6 +31,9 @@ class OSGUTIL_EXPORT SceneGraphBuilder
SceneGraphBuilder();
//
// OpenGL 1.0 style building methods
//
void glPushMatrix();
void glPopMatrix();
void glLoadIdentity();
@ -49,43 +52,129 @@ class OSGUTIL_EXPORT SceneGraphBuilder
void glPointSize(GLfloat pointSize);
void glPolygonMode(GLenum face, GLenum mode);
void glPolygonOffset(GLfloat factor, GLfloat units);
void glPolygonStipple(GLubyte* mask);
void glPolygonStipple(const GLubyte* mask);
void glShadeModel(GLenum mode);
void glEnable(GLenum mode);
void glDisable(GLenum mode);
void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
void glColor4fv(GLfloat* c) { glColor4f(c[0], c[1], c[2], c[3]); }
void glVertex3f(GLfloat x, GLfloat y, GLfloat z);
void glVertex3fv(GLfloat* v) { glVertex3f(v[0], v[1], v[2]); }
void glNormal3f(GLfloat x, GLfloat y, GLfloat z);
void glNormal3fv(GLfloat* n) { glNormal3f(n[0], n[1], n[2]); }
void glTexCoord1f(GLfloat x);
void glTexCoord1fv(GLfloat* tc) { glTexCoord1f(tc[0]); }
void glTexCoord2f(GLfloat x, GLfloat y);
void glTexCoord2fv(GLfloat* tc) { glTexCoord2f(tc[0],tc[1]); }
void glTexCoord3f(GLfloat x, GLfloat y, GLfloat z);
void glTexCoord3fv(GLfloat* tc) { glTexCoord3f(tc[0], tc[1], tc[2]); }
void glTexCoord4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void glTexCoord4fv(GLfloat* tc) { glTexCoord4f(tc[0], tc[1], tc[2], tc[3]); }
void glBegin(GLenum mode);
void glEnd();
//
// glu style building methods
//
void gluQuadricDrawStyle(GLenum aDrawStyle);
void gluQuadricNormals(GLenum aNormals);
void gluQuadricOrientation(GLenum aOrientation);
void gluQuadricTexture(GLboolean aTexture);
void gluCylinder(GLfloat aBase,
GLfloat aTop,
GLfloat aHeight,
GLint aSlices,
GLint aStacks);
void gluDisk(GLfloat aInner,
GLfloat aOuter,
GLint aSlices,
GLint aLoops);
void gluPartialDisk(GLfloat aInner,
GLfloat aOuter,
GLint aSlices,
GLint aLoops,
GLfloat aStart,
GLfloat aSweep);
void gluSphere(GLfloat aRadius,
GLint aSlices,
GLint aStacks);
//
// methods for obtaining the built scene graph
//
osg::Node* getScene();
osg::Node* takeScene();
protected:
typedef std::vector<osg::Matrixd> Matrices;
void matrixChanged();
void addAttribute(osg::StateAttribute* attribute);
void addMode(GLenum mode, bool enabled);
void addTextureAttribute(unsigned int unit, osg::StateAttribute* attribute);
void addTextureMode(unsigned int unit, GLenum mode, bool enabled);
void addShape(osg::Shape* shape);
void addDrawable(osg::Drawable* drawable);
void newGeometry();
Matrices _matrixStack;
osg::ref_ptr<osg::StateSet> _stateSet;
void allocateGeometry();
void completeGeometry();
void allocateStateSet();
Matrices _matrixStack;
osg::ref_ptr<osg::StateSet> _stateset;
bool _normalSet;
osg::Vec3f _normal;
bool _colorSet;
osg::Vec4f _color;
unsigned int _maxNumTexCoordComponents;
osg::Vec4f _texCoord;
GLenum _primitiveMode;
osg::ref_ptr<osg::Vec3Array> _vertices;
osg::ref_ptr<osg::Vec3Array> _normals;
osg::ref_ptr<osg::Vec4Array> _colors;
osg::ref_ptr<osg::Vec4Array> _texCoords;
osg::ref_ptr<osg::Geometry> _currentGeometry;
osg::ref_ptr<osg::Geode> _currentGeode;
osg::ref_ptr<osg::MatrixTransform> _currentTransform;
struct QuadricState
{
QuadricState():
_drawStyle(GLU_FILL),
_normals(GLU_SMOOTH),
_orientation(GLU_OUTSIDE),
_texture(GLU_FALSE) {}
GLenum _drawStyle;
GLenum _normals;
GLenum _orientation;
GLboolean _texture;
};
QuadricState _quadricState;
osg::ref_ptr<osg::Geometry> _geometry;
osg::ref_ptr<osg::Geode> _geode;
osg::ref_ptr<osg::MatrixTransform> _transform;
osg::ref_ptr<osg::Group> _group;
};

View File

@ -12,18 +12,24 @@
*/
#include <osgUtil/SceneGraphBuilder>
#include <osg/Timer>
#include <osg/GLExtensions>
#include <osg/GLObjects>
#include <osg/Notify>
#include <osg/io_utils>
#include <osg/PrimitiveSet>
#include <osg/Texture>
#include <osg/AlphaFunc>
#include <osg/TexEnv>
#include <osg/ColorMatrix>
#include <osg/LightModel>
#include <osg/CollectOccludersVisitor>
#include <osg/GLU>
#include <osg/BlendFunc>
#include <osg/LineStipple>
#include <osg/Depth>
#include <osg/CullFace>
#include <osg/FrontFace>
#include <osg/LineWidth>
#include <osg/Point>
#include <osg/PolygonMode>
#include <osg/PolygonOffset>
#include <osg/PolygonStipple>
#include <osg/ShadeModel>
#include <osg/ShapeDrawable>
using namespace osgUtil;
@ -34,6 +40,11 @@ SceneGraphBuilder::SceneGraphBuilder():
{
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// OpenGL 1.0 building methods
//
void SceneGraphBuilder::glPushMatrix()
{
if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
@ -43,123 +54,396 @@ void SceneGraphBuilder::glPushMatrix()
void SceneGraphBuilder::glPopMatrix()
{
if (!_matrixStack.empty()) _matrixStack.pop_back();
matrixChanged();
}
void SceneGraphBuilder::glLoadIdentity()
{
if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
_matrixStack.back().makeIdentity();
matrixChanged();
}
void SceneGraphBuilder::glLoadMatrixd(const GLdouble* m)
{
if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
_matrixStack.back().set(m);
matrixChanged();
}
void SceneGraphBuilder::glMultMatrixd(const GLdouble* m)
{
if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
_matrixStack.back().preMult(osg::Matrixd(m));
matrixChanged();
}
void SceneGraphBuilder::glTranslated(GLdouble x, GLdouble y, GLdouble z)
{
if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
_matrixStack.back().preMult(osg::Matrixd::translate(x,y,z));
matrixChanged();
}
void SceneGraphBuilder::glScaled(GLdouble x, GLdouble y, GLdouble z)
{
if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
_matrixStack.back().preMult(osg::Matrixd::scale(x,y,z));
matrixChanged();
}
void SceneGraphBuilder::glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
{
if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
_matrixStack.back().preMult(osg::Matrixd::rotate(osg::inDegrees(angle),x,y,z));
matrixChanged();
}
void SceneGraphBuilder::glBlendFunc(GLenum srcFactor, GLenum dstFactor)
{
addAttribute(new osg::BlendFunc(srcFactor, dstFactor));
}
void SceneGraphBuilder::glCullFace(GLenum mode)
{
addAttribute(new osg::CullFace(osg::CullFace::Mode(mode)));
}
void SceneGraphBuilder::glDepthFunc(GLenum mode)
{
addAttribute(new osg::Depth(osg::Depth::Function(mode)));
}
void SceneGraphBuilder::glFrontFace(GLenum mode)
{
addAttribute(new osg::FrontFace(osg::FrontFace::Mode(mode)));
}
void SceneGraphBuilder::glLineStipple(GLint factor, GLushort pattern)
{
addAttribute(new osg::LineStipple(factor, pattern));
}
void SceneGraphBuilder::glLineWidth(GLfloat lineWidth)
{
addAttribute(new osg::LineWidth(lineWidth));
}
void SceneGraphBuilder::glPointSize(GLfloat pointSize)
{
addAttribute(new osg::Point(pointSize));
}
void SceneGraphBuilder::glPolygonMode(GLenum face, GLenum mode)
{
addAttribute(new osg::PolygonMode(osg::PolygonMode::Face(face),osg::PolygonMode::Mode(mode)));
}
void SceneGraphBuilder::glPolygonOffset(GLfloat factor, GLfloat units)
{
addAttribute(new osg::PolygonOffset(factor,units));
}
void SceneGraphBuilder::glPolygonStipple(GLubyte* mask)
void SceneGraphBuilder::glPolygonStipple(const GLubyte* mask)
{
addAttribute(new osg::PolygonStipple(mask));
}
void SceneGraphBuilder::glShadeModel(GLenum mode)
{
addAttribute(new osg::ShadeModel(osg::ShadeModel::Mode(mode)));
}
void SceneGraphBuilder::glEnable(GLenum mode)
{
addMode(mode, true);
}
void SceneGraphBuilder::glDisable(GLenum mode)
{
}
void SceneGraphBuilder::glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
addMode(mode, false);
}
void SceneGraphBuilder::glVertex3f(GLfloat x, GLfloat y, GLfloat z)
void SceneGraphBuilder::glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
_normalSet = true;
_color.set(red,green,blue,alpha);
}
void SceneGraphBuilder::glNormal3f(GLfloat x, GLfloat y, GLfloat z)
{
_normalSet = true;
_normal.set(x,y,z);
}
void SceneGraphBuilder::glTexCoord1f(GLfloat x)
{
_maxNumTexCoordComponents = 1;
_texCoord.set(x,0.0f,0.0f,1.0f);
}
void SceneGraphBuilder::glTexCoord2f(GLfloat x, GLfloat y)
{
_maxNumTexCoordComponents = 2;
_texCoord.set(x,y,0.0f,1.0f);
}
void SceneGraphBuilder::glTexCoord3f(GLfloat x, GLfloat y, GLfloat z)
{
_maxNumTexCoordComponents = 3;
_texCoord.set(x,y,z,1.0);
}
void SceneGraphBuilder::glTexCoord4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
_maxNumTexCoordComponents = 4;
_texCoord.set(x,y,z,w);
}
void SceneGraphBuilder::glVertex3f(GLfloat x, GLfloat y, GLfloat z)
{
osg::Vec3 vertex(x,y,z);
vertex = vertex * _matrixStack.back();
if (_vertices.valid()) _vertices->push_back(vertex);
if (_normal.valid()) _normals->push_back(_normal);
if (_colors.valid()) _colors->push_back(_color);
if (_texCoords.valid()) _texCoords->push_back(_texCoord);
}
void SceneGraphBuilder::glBegin(GLenum mode)
{
// reset geometry
_primitiveMode = mode;
_vertices = new osg::Vec3Array;
_normalSet = false;
_normals = new osg::Vec3Array;
_colorSet = false;
_colors = new osg::Vec4Array;
_maxNumTexCoordComponents = 0;
_texCoords = new osg::Vec4Array;
}
void SceneGraphBuilder::glEnd()
{
allocateGeometry();
_geometry->setVertexArray(_vertices.get());
if (_colorSet)
{
_geometry->setColorArray(_colors.get());
_geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
}
else
{
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(_color);
_geometry->setColorArray(colors);
_geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
}
if (_normalSet)
{
_geometry->setNormalArray(_normals.get());
_geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
}
else
{
_geometry->setNormalBinding(osg::Geometry::BIND_OFF);
}
if (_maxNumTexCoordComponents>0)
{
_geometry->setTexCoordArray(0, _texCoords.get());
}
_geometry->addPrimitiveSet(new osg::DrawArrays(_primitiveMode, 0, _vertices->size()));
completeGeometry();
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// GLU style building methods
//
void SceneGraphBuilder::gluQuadricDrawStyle(GLenum aDrawStyle)
{
_quadricState._drawStyle = aDrawStyle;
}
void SceneGraphBuilder::gluQuadricNormals(GLenum aNormals)
{
_quadricState._normals = aNormals;
}
void SceneGraphBuilder::gluQuadricOrientation(GLenum aOrientation)
{
_quadricState._orientation = aOrientation;
}
void SceneGraphBuilder::gluQuadricTexture(GLboolean aTexture)
{
_quadricState._texture = aTexture;
}
void SceneGraphBuilder::gluCylinder(GLfloat aBase,
GLfloat aTop,
GLfloat aHeight,
GLint aSlices,
GLint aStacks)
{
osg::notify(osg::NOTICE)<<"SceneGraphBuilder::gluCylinder("<<aBase<<", "<<aTop<<", "<<aHeight<<", "<<aSlices<<", "<<aStacks<<")"<<std::endl;
osg::notify(osg::NOTICE)<<" quadric("<<_quadricState._drawStyle<<", "<<_quadricState._normals<<", "<<_quadricState._orientation<<", "<<_quadricState._texture<<std::endl;
}
void SceneGraphBuilder::gluDisk(GLfloat aInner,
GLfloat aOuter,
GLint aSlices,
GLint aLoops)
{
osg::notify(osg::NOTICE)<<"SceneGraphBuilder::gluDisk("<<aInner<<", "<<aOuter<<", "<<aSlices<<", "<<aLoops<<")"<<std::endl;
osg::notify(osg::NOTICE)<<" quadric("<<_quadricState._drawStyle<<", "<<_quadricState._normals<<", "<<_quadricState._orientation<<", "<<_quadricState._texture<<std::endl;
}
void SceneGraphBuilder::gluPartialDisk(GLfloat aInner,
GLfloat aOuter,
GLint aSlices,
GLint aLoops,
GLfloat aStart,
GLfloat aSweep)
{
osg::notify(osg::NOTICE)<<"SceneGraphBuilder::gluPartialDisk("<<aInner<<", "<<aOuter<<", "<<aSlices<<", "<<aLoops<<", "<<aStart<<", "<<aSweep<<")"<<std::endl;
osg::notify(osg::NOTICE)<<" quadric("<<_quadricState._drawStyle<<", "<<_quadricState._normals<<", "<<_quadricState._orientation<<", "<<_quadricState._texture<<std::endl;
}
void SceneGraphBuilder::gluSphere(GLfloat aRadius,
GLint aSlices,
GLint aStacks)
{
addShape(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f), aRadius));
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// General scene graph building methods
//
osg::Node* SceneGraphBuilder::getScene()
{
if (_group.valid() && _group->getNumChildren()>0) return _group.get();
else if (_transform.valid() && _transform->getNumChildren()>0) return _transform.get();
else if (_geode.valid() && _geode->getNumDrawables()>0) return _geode.get();
return 0;
}
osg::Node* SceneGraphBuilder::takeScene()
{
osg::ref_ptr<osg::Node> node;
if (_group.valid() && _group->getNumChildren()>0) node = _group.get();
else if (_transform.valid() && _transform->getNumChildren()>0) node = _transform.get();
else if (_geode.valid() && _geode->getNumDrawables()>0) node = _geode.get();
// reset all the pointers to properly release the scene graph
_geometry = 0;
_geode = 0;
_transform = 0;
_group = 0;
return node.release();
}
void SceneGraphBuilder::matrixChanged()
{
}
void SceneGraphBuilder::addAttribute(osg::StateAttribute* attribute)
{
allocateStateSet();
_stateset->setAttribute(attribute);
osg::notify(osg::NOTICE)<<"SceneGraphBuilder::addAttribute("<<attribute->className()<<")"<<std::endl;
}
void SceneGraphBuilder::addMode(GLenum mode, bool enabled)
{
osg::notify(osg::NOTICE)<<"SceneGraphBuilder::addMode("<<mode<<","<<enabled<<")"<<std::endl;
allocateStateSet();
_stateset->setMode(mode, enabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
}
void SceneGraphBuilder::addTextureAttribute(unsigned int unit, osg::StateAttribute* attribute)
{
osg::notify(osg::NOTICE)<<"SceneGraphBuilder::addAttribute("<<attribute->className()<<")"<<std::endl;
allocateStateSet();
_stateset->setTextureAttribute(unit, attribute);
}
void SceneGraphBuilder::addTextureMode(unsigned int unit, GLenum mode, bool enabled)
{
osg::notify(osg::NOTICE)<<"SceneGraphBuilder::addTextureMode("<<mode<<","<<enabled<<")"<<std::endl;
allocateStateSet();
_stateset->setTextureMode(unit, mode, enabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
}
void SceneGraphBuilder::addShape(osg::Shape* shape)
{
osg::notify(osg::NOTICE)<<"SceneGraphBuilder::addShape("<<shape->className()<<std::endl;
osg::ShapeDrawable* sd = new osg::ShapeDrawable(shape);
sd->setColor(_color);
addDrawable(sd);
}
void SceneGraphBuilder::addDrawable(osg::Drawable* drawable)
{
if (!_geode) _geode = new osg::Geode;
_geode->addDrawable(drawable);
}
void SceneGraphBuilder::allocateStateSet()
{
if (_geometry.valid())
{
completeGeometry();
_stateset = 0;
}
if (!_stateset) _stateset = new osg::StateSet;
}
void SceneGraphBuilder::allocateGeometry()
{
if (!_geometry)
{
_geometry = new osg::Geometry;
}
}
void SceneGraphBuilder::completeGeometry()
{
if (_geometry.valid()) addDrawable(_geometry.get());
_geometry = 0;
}