From db256b962cf2e4d1e525dc2376ff0d4a337436b9 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 12 Mar 2008 20:15:28 +0000 Subject: [PATCH] Added proper implementations of OpenGL 1.0 calls to OSG object representation methods in SceneGraphBuilder. --- include/osgUtil/SceneGraphBuilder | 105 +++++++++- src/osgUtil/SceneGraphBuilder.cpp | 316 ++++++++++++++++++++++++++++-- 2 files changed, 397 insertions(+), 24 deletions(-) diff --git a/include/osgUtil/SceneGraphBuilder b/include/osgUtil/SceneGraphBuilder index 36872fd99..08a844d27 100644 --- a/include/osgUtil/SceneGraphBuilder +++ b/include/osgUtil/SceneGraphBuilder @@ -14,10 +14,10 @@ #ifndef OSGUTIL_SCENEGRAPHBUILDER #define OSGUTIL_SCENEGRAPHBUILDER 1 -#include #include #include #include +#include #include @@ -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 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 _stateSet; + void allocateGeometry(); + void completeGeometry(); + void allocateStateSet(); + + Matrices _matrixStack; + osg::ref_ptr _stateset; + + bool _normalSet; osg::Vec3f _normal; + + bool _colorSet; osg::Vec4f _color; + + unsigned int _maxNumTexCoordComponents; osg::Vec4f _texCoord; + + GLenum _primitiveMode; + osg::ref_ptr _vertices; + osg::ref_ptr _normals; + osg::ref_ptr _colors; + osg::ref_ptr _texCoords; - osg::ref_ptr _currentGeometry; - osg::ref_ptr _currentGeode; - osg::ref_ptr _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 _geometry; + osg::ref_ptr _geode; + osg::ref_ptr _transform; osg::ref_ptr _group; }; diff --git a/src/osgUtil/SceneGraphBuilder.cpp b/src/osgUtil/SceneGraphBuilder.cpp index 6f24da828..3101080ef 100644 --- a/src/osgUtil/SceneGraphBuilder.cpp +++ b/src/osgUtil/SceneGraphBuilder.cpp @@ -12,18 +12,24 @@ */ #include -#include -#include -#include #include +#include + +#include #include #include -#include -#include -#include -#include - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include 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("<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 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("<className()<<")"<setMode(mode, enabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF); +} + + +void SceneGraphBuilder::addTextureAttribute(unsigned int unit, osg::StateAttribute* attribute) +{ + osg::notify(osg::NOTICE)<<"SceneGraphBuilder::addAttribute("<className()<<")"<setTextureAttribute(unit, attribute); +} + +void SceneGraphBuilder::addTextureMode(unsigned int unit, GLenum mode, bool enabled) +{ + osg::notify(osg::NOTICE)<<"SceneGraphBuilder::addTextureMode("<setTextureMode(unit, mode, enabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF); +} + +void SceneGraphBuilder::addShape(osg::Shape* shape) +{ + osg::notify(osg::NOTICE)<<"SceneGraphBuilder::addShape("<className()<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; }