diff --git a/Make/makedirdefs b/Make/makedirdefs index 2be9cdc41..a154b565a 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -73,6 +73,7 @@ DEMOS_DIRS = \ osgconv\ osgcopy\ osgcube\ + osggeometry\ osghud\ osgimpostor\ osgoccluder\ diff --git a/VisualStudio/Demos/osggeometry/osggeometry.dsp b/VisualStudio/Demos/osggeometry/osggeometry.dsp new file mode 100644 index 000000000..9df03e1fd --- /dev/null +++ b/VisualStudio/Demos/osggeometry/osggeometry.dsp @@ -0,0 +1,190 @@ +# Microsoft Developer Studio Project File - Name="Demo osggeoemtry" - Package Owner=<4> + +# Microsoft Developer Studio Generated Build File, Format Version 6.00 + +# ** DO NOT EDIT ** + + + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + + + +CFG=Demo osggeoemtry - Win32 Release + +!MESSAGE This is not a valid makefile. To build this project using NMAKE, + +!MESSAGE use the Export Makefile command and run + +!MESSAGE + +!MESSAGE NMAKE /f "osggeoemtry.mak". + +!MESSAGE + +!MESSAGE You can specify a configuration when running NMAKE + +!MESSAGE by defining the macro CFG on the command line. For example: + +!MESSAGE + +!MESSAGE NMAKE /f "osggeoemtry.mak" CFG="Demo osggeoemtry - Win32 Release" + +!MESSAGE + +!MESSAGE Possible choices for configuration are: + +!MESSAGE + +!MESSAGE "Demo osggeoemtry - Win32 Release" (based on "Win32 (x86) Console Application") + +!MESSAGE "Demo osggeoemtry - Win32 Debug" (based on "Win32 (x86) Console Application") + +!MESSAGE + + + +# Begin Project + +# PROP AllowPerConfigDependencies 0 + +# PROP Scc_ProjName "" + +# PROP Scc_LocalPath "" + +CPP=cl.exe + +RSC=rc.exe + + + +!IF "$(CFG)" == "Demo osggeoemtry - Win32 Release" + + + +# PROP BASE Use_MFC 0 + +# PROP BASE Use_Debug_Libraries 0 + +# PROP BASE Output_Dir "Release" + +# PROP BASE Intermediate_Dir "Release" + +# PROP BASE Target_Dir "" + +# PROP Use_MFC 0 + +# PROP Use_Debug_Libraries 0 + +# PROP Output_Dir "Release" + +# PROP Intermediate_Dir "Release" + +# PROP Ignore_Export_Lib 0 + +# PROP Target_Dir "" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c + +# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c + +# ADD BASE RSC /l 0x809 /d "NDEBUG" + +# ADD RSC /l 0x809 /d "NDEBUG" + +BSC32=bscmake.exe + +# ADD BASE BSC32 /nologo + +# ADD BSC32 /nologo + +LINK32=link.exe + +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +# ADD LINK32 /nologo /subsystem:console /pdb:none /machine:I386 /out:"../../../bin/osggeoemtry.exe" /libpath:"../../../lib" + + + +!ELSEIF "$(CFG)" == "Demo osggeoemtry - Win32 Debug" + + + +# PROP BASE Use_MFC 0 + +# PROP BASE Use_Debug_Libraries 1 + +# PROP BASE Output_Dir "Debug" + +# PROP BASE Intermediate_Dir "Debug" + +# PROP BASE Target_Dir "" + +# PROP Use_MFC 0 + +# PROP Use_Debug_Libraries 1 + +# PROP Output_Dir "Debug" + +# PROP Intermediate_Dir "Debug" + +# PROP Ignore_Export_Lib 0 + +# PROP Target_Dir "" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c + +# ADD CPP /nologo /MDd /W3 /Gm /vd0 /GR /GX /Zi /Od /I "../../../include" /D "_CONSOLE" /D "_MBCS" /D "FL_DLL" /D "WIN32" /D "_DEBUG" /FR /YX /FD /c + +# ADD BASE RSC /l 0x809 /d "_DEBUG" + +# ADD RSC /l 0x809 /d "_DEBUG" + +BSC32=bscmake.exe + +# ADD BASE BSC32 /nologo + +# ADD BSC32 /nologo + +LINK32=link.exe + +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osggeoemtryd.exe" /pdbtype:sept /libpath:"../../../lib" + +# SUBTRACT LINK32 /incremental:no + + + +!ENDIF + + + +# Begin Target + + + +# Name "Demo osggeoemtry - Win32 Release" + +# Name "Demo osggeoemtry - Win32 Debug" + +# Begin Source File + + + +SOURCE=..\..\..\src\Demos\osggeoemtry\osggeoemtry.cpp + +# End Source File + +# End Target + +# Begin Group "Resource Files" + + + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + +# End Group + +# End Project + diff --git a/VisualStudio/VisualStudio.dsw b/VisualStudio/VisualStudio.dsw index 343a1ff97..0a07d2252 100644 --- a/VisualStudio/VisualStudio.dsw +++ b/VisualStudio/VisualStudio.dsw @@ -612,6 +612,60 @@ Package=<4> +Project: "Demo osggeometry"=.\Demos\osggeometry\osggeometry.dsp - Package Owner=<4> + + + +Package=<5> + +{{{ + +}}} + + + +Package=<4> + +{{{ + + Begin Project Dependency + + Project_Dep_Name Core osg + + End Project Dependency + + Begin Project Dependency + + Project_Dep_Name Core osgDB + + End Project Dependency + + Begin Project Dependency + + Project_Dep_Name Core osgGA + + End Project Dependency + + Begin Project Dependency + + Project_Dep_Name Core osgGLUT + + End Project Dependency + + Begin Project Dependency + + Project_Dep_Name Core osgUtil + + End Project Dependency + +}}} + + + +############################################################################### + + + Project: "Demo osghud"=.\Demos\osghud\osghud.dsp - Package Owner=<4> diff --git a/include/osg/Geometry b/include/osg/Geometry index 69385a18a..c60b2768a 100644 --- a/include/osg/Geometry +++ b/include/osg/Geometry @@ -12,16 +12,51 @@ namespace osg { +enum ArrayType +{ + AttributeArrayType = 0, + ByteArrayType = 1, + ShortArrayType = 2, + IntArrayType = 3, + UByteArrayType = 4, + UShortArrayType = 5, + UIntArrayType = 6, + UByte4ArrayType = 7, + FloatArrayType = 8, + Vec2ArrayType = 9, + Vec3ArrayType = 10, + Vec4ArrayType = 11 +}; + +static char* s_classNames[] = +{ + "AttributeArray" // 0 + "ByteArray", // 1 + "ShortArray", // 2 + "IntArray", // 3 + "UByteArray", // 4 + "UShortArray", // 5 + "UIntArray", // 6 + "UByte4Array", // 7 + "FloatArray", // 8 + "Vec2Array", // 9 + "Vec3Array", // 10 + "Vec4Array" // 11 +}; class AttributeArray : public Object { public: - AttributeArray(GLint dataSize=0,GLenum dataType=0):_dataSize(dataSize),_dataType(dataType) {} + AttributeArray(ArrayType arrayType=AttributeArrayType,GLint dataSize=0,GLenum dataType=0): + _arrayType(arrayType), + _dataSize(dataSize), + _dataType(dataType) {} AttributeArray(const AttributeArray& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): Object(array,copyop), + _arrayType(array._arrayType), _dataSize(array._dataSize), _dataType(array._dataType) {} @@ -30,6 +65,7 @@ class AttributeArray : public Object virtual const char* className() const { return "AttributeArray"; } + ArrayType arrayType() const { return _arrayType; } GLint dataSize() const { return _dataSize; } GLenum dataType() const { return _dataType; } virtual const GLvoid* dataPointer() const = 0; @@ -38,71 +74,67 @@ class AttributeArray : public Object virtual ~AttributeArray() {} - GLint _dataSize; - GLenum _dataType; + ArrayType _arrayType; + GLint _dataSize; + GLenum _dataType; }; -static char* s_classNames[] = { - "ByteArray", // 0 - "ShortArray", // 1 - "IntArray", // 2 - "UByteArray", // 3 - "UShortArray", // 4 - "UIntArray", // 5 - "FloatArray", // 6 - "Vec2Array", // 7 - "Vec3Array", // 8 - "Vec4Array" // 9 - }; -template + +template class TemplateArray : public AttributeArray, public std::vector { public: - TemplateArray() : TemplateArray(DataSize,DataType) {} + TemplateArray() : AttributeArray(ARRAYTYPE,DataSize,DataType) {} - TemplateArray(const TemplateArray& t,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : AttributeArray(t,copyop), std::vector(t) {} + TemplateArray(const TemplateArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : AttributeArray(ta,copyop), std::vector(ta) {} virtual Object* cloneType() const { return osgNew TemplateArray(); } virtual Object* clone(const CopyOp& copyop) const { return osgNew TemplateArray(*this,copyop); } virtual const char* libraryName() const { return "osg"; } - virtual const char* className() const { return s_classNames[ClassName]; } + virtual const char* className() const { return s_classNames[ARRAYTYPE]; } - virtual const GLvoid* dataPointer() const { if (!empty()) return &(*begin()); else return 0; } + virtual const GLvoid* dataPointer() const { if (!empty()) return &front(); else return 0; } }; -typedef TemplateArray ByteArray; -typedef TemplateArray ShortArray; -typedef TemplateArray IntArray; -typedef TemplateArray UByteArray; -typedef TemplateArray UShortArray; -typedef TemplateArray UIntArray; -typedef TemplateArray FloatArray; -typedef TemplateArray Vec2Array; -typedef TemplateArray Vec3Array; -typedef TemplateArray Vec4Array; +typedef TemplateArray ByteArray; +typedef TemplateArray ShortArray; +typedef TemplateArray IntArray; +typedef TemplateArray UByteArray; +typedef TemplateArray UShortArray; +typedef TemplateArray UIntArray; +typedef TemplateArray UByte4Array; +typedef TemplateArray FloatArray; +typedef TemplateArray Vec2Array; +typedef TemplateArray Vec3Array; +typedef TemplateArray Vec4Array; +/* ******************************************************************************************************************* */ -/** Experiemntal replacement for GeoSet. -*/ -class SG_EXPORT Geometry : public Drawable +enum PrimitiveType +{ + PrimitivePrimitiveType = 0, + DrawArrayPrimitiveType = 1, + UByteDrawElementsPrimitiveType = 2, + UShortDrawElementsPrimitiveType = 3, + UIntDrawElementsPrimitiveType = 4, +}; + +static char* s_PrimitiveNames[] = +{ + "Primitive", // 0 + "DrawArray", // 1 + "UByteDrawElements", // 2 + "UShortDrawElements", // 3 + "UIntDrawElements" // 4 +}; + +class Primitive : public Object { public: - - - Geometry(); - - /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ - Geometry(const Geometry& Geometry,const CopyOp& copyop=CopyOp::SHALLOW_COPY); - - virtual Object* cloneType() const { return osgNew Geometry(); } - virtual Object* clone(const CopyOp& copyop) const { return osgNew Geometry(*this,copyop); } - virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } - virtual const char* libraryName() const { return "osg"; } - virtual const char* className() const { return "Geometry"; } - - enum PrimitiveType + + enum PrimitiveMode { POINTS = GL_POINTS, LINES = GL_LINES, @@ -115,33 +147,153 @@ class SG_EXPORT Geometry : public Drawable QUAD_STRIP = GL_QUAD_STRIP, POLYGON = GL_POLYGON }; + + Primitive(PrimitiveType primType=PrimitivePrimitiveType):_primitiveType(primType) {} + + Primitive(const Primitive& prim,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + Object(prim,copyop) {} + + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return "Primitive"; } - enum AttributeType + PrimitiveType primitiveType; + + virtual void draw() const = 0; + + PrimitiveType _primitiveType; +}; + +class DrawArray : public Primitive +{ + public: + + DrawArray(): + Primitive(DrawArrayPrimitiveType) + {} + + DrawArray(GLenum mode, GLint first, GLsizei count): + Primitive(DrawArrayPrimitiveType), + _mode(mode), + _first(first), + _count(count) {} + + DrawArray(const DrawArray& da,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + Primitive(da,copyop), + _mode(da._mode), + _first(da._first), + _count(da._count) {} + + virtual Object* cloneType() const { return osgNew DrawArray(); } + virtual Object* clone(const CopyOp& copyop) const { return osgNew DrawArray(*this,copyop); } + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return "DrawArray"; } + + virtual void draw() const { - PRIMITIVES, - COORDS, - NORMALS, - COLORS, - TEX_COORDS, - TEX_COORDS_0 = TEX_COORDS, - TEX_COORDS_1, - TEX_COORDS_2, - TEX_COORDS_3, - TEX_COORDS_4, - TEX_COORDS_5, - TEX_COORDS_6, - TEX_COORDS_7 + glDrawArrays(_mode,_first,_count); + } + + GLenum _mode; + GLint _first; + GLsizei _count; +}; + +template +class DrawElements : public Primitive, public std::vector +{ + public: + + DrawElements():Primitive(PRIMTYPE),_dataType(_dataType) {} + + DrawElements(const DrawElements& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + Primitive(array,copyop) {} + + virtual Object* cloneType() const { return osgNew DrawElements(); } + virtual Object* clone(const CopyOp& copyop) const { return osgNew DrawElements(*this,copyop); } + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return s_PrimitiveNames[PRIMTYPE]; } + + virtual void draw() const + { + glDrawElements(_mode,size(),_dataType,&front()); + } + + GLenum _mode; + GLenum _dataType; +}; + +typedef DrawElements UByteDrawElements; +typedef DrawElements UShortDrawElements; +typedef DrawElements UIntDrawElements; + + +/* ******************************************************************************************************************* */ + + +/** Experiemntal replacement for GeoSet. +*/ +class SG_EXPORT Geometry : public Drawable +{ + public: + + Geometry(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + Geometry(const Geometry& Geometry,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + virtual Object* cloneType() const { return osgNew Geometry(); } + virtual Object* clone(const CopyOp& copyop) const { return osgNew Geometry(*this,copyop); } + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return "Geometry"; } + + enum AttributeBinding + { + OFF=0, + OVERALL, + PER_PRIMITIVE, + PER_VERTEX, }; - - void setAttribute(AttributeType type,AttributeArray* array); - - void setAttribute(AttributeType type,AttributeArray* array,AttributeArray* indices); + + void setVertexArray(Vec3Array* array) { _vertexArray = array; } + Vec3Array* getVertexArray() { return _vertexArray.get(); } + const Vec3Array* getVertexArray() const { return _vertexArray.get(); } - AttributeArray* getAttribute(AttributeType type); - - void setIndices(AttributeType type,AttributeArray* indices); - AttributeArray* getIndices(AttributeType type); + void setNormalBinding(AttributeBinding ab) { _normalBinding = ab; } + AttributeBinding getNormalBinding() const { return _normalBinding; } + + void setNormalArray(Vec3Array* array) { _normalArray = array; if (!_normalArray.valid()) _normalBinding=OFF; } + Vec3Array* getNormalArray() { return _normalArray.get(); } + const Vec3Array* getNormalArray() const { return _normalArray.get(); } + + + void setColorBinding(AttributeBinding ab) { _colorBinding = ab; } + AttributeBinding getColorBinding() const { return _colorBinding; } + + void setColorArray(AttributeArray* array) { _colorArray = array; if (!_colorArray.valid()) _colorBinding=OFF; } + AttributeArray* getColorArray() { return _colorArray.get(); } + const AttributeArray* getColorArray() const { return _colorArray.get(); } + + + typedef std::vector< ref_ptr > TexCoordList; + + void setTexCoordArray(unsigned int unit,AttributeArray*); + AttributeArray* getTexCoordArray(unsigned int unit); + const AttributeArray* getTexCoordArray(unsigned int unit) const; + + + typedef std::vector< ref_ptr > PrimitiveList; + + void setPrimitiveList(const PrimitiveList& primitives) { _primitives = primitives; } + PrimitiveList& getPrimitiveList() { return _primitives; } + const PrimitiveList& getPrimitiveList() const { return _primitives; } + + void addPrimtive(Primitive* primitive) { if (primitive) _primitives.push_back(primitive); } + /** draw Geometry directly ignoring an OpenGL display list which could be attached. @@ -170,27 +322,19 @@ class SG_EXPORT Geometry : public Drawable virtual const bool computeBound() const; - void setTexCoordArray(unsigned int pos,AttributeArray*); - AttributeArray* getTexCoordArray(unsigned int pos); - void setTexCoordIndicesArray(unsigned int pos,AttributeArray*); - AttributeArray* getTexCoordIndicesArray(unsigned int pos); - typedef std::vector< ref_ptr > TexCoordList; + PrimitiveList _primitives; - ref_ptr _primitives; - - ref_ptr _coords; - ref_ptr _coordIndices; - - ref_ptr _normals; - ref_ptr _normalIndices; - - ref_ptr _colors; - ref_ptr _colorIndices; + ref_ptr _vertexArray; + AttributeBinding _normalBinding; + ref_ptr _normalArray; + + AttributeBinding _colorBinding; + ref_ptr _colorArray; + TexCoordList _texCoordList; - TexCoordList _texCoordIndicesList; }; diff --git a/src/Demos/osggeometry/Makefile b/src/Demos/osggeometry/Makefile new file mode 100644 index 000000000..267b697ae --- /dev/null +++ b/src/Demos/osggeometry/Makefile @@ -0,0 +1,15 @@ +TOPDIR = ../../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osggeometry.cpp\ + +LIBS += $(OSG_LIBS) $(GLUT_LIB) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + Makefile.inst=Makefile + +EXEC = osggeometry + +include $(TOPDIR)/Make/makerules diff --git a/src/Demos/osggeometry/Makefile.inst b/src/Demos/osggeometry/Makefile.inst new file mode 100644 index 000000000..56c08058c --- /dev/null +++ b/src/Demos/osggeometry/Makefile.inst @@ -0,0 +1,11 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osggeometry.cpp\ + +LIBS += $(OSG_LIBS) $(GLUT_LIB) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osggeometry + +include $(TOPDIR)/Make/makerules diff --git a/src/Demos/osggeometry/osggeometry.cpp b/src/Demos/osggeometry/osggeometry.cpp new file mode 100644 index 000000000..67cbdec62 --- /dev/null +++ b/src/Demos/osggeometry/osggeometry.cpp @@ -0,0 +1,300 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +// ---------------------------------------------------------------------- +// Global variables - this is basically the stuff which will be animated +// ---------------------------------------------------------------------- + + +class MyTransformCallback : public osg::NodeCallback{ + + public: + + MyTransformCallback(osg::Transform* node,float angularVelocity) + { + _nodeToOperateOn = node; + _angular_velocity = angularVelocity; + _previousTraversalNumber = -1; + _orig_t = _timer.tick(); + } + + virtual void operator() (osg::Node* node, osg::NodeVisitor* nv) + { + if (nv) + { + if (_nodeToOperateOn && node==_nodeToOperateOn) + { + // ensure that we do not operate on this node more than + // once during this traversal. This is an issue since node + // can be shared between multiple parents. + if (nv->getTraversalNumber()!=_previousTraversalNumber) + { + osg::Timer_t new_t = _timer.tick(); + float delta_angle = _angular_velocity*_timer.delta_s(_orig_t,new_t); + + osg::Matrix matrix; + matrix.makeRotate(delta_angle,1.0f,1.0f,1.0f); + matrix *= osg::Matrix::translate(1.0f,0.0f,0.0f); + matrix *= osg::Matrix::rotate(delta_angle,0.0f,0.0f,1.0f); + + _nodeToOperateOn->setMatrix(matrix); + + _previousTraversalNumber = nv->getTraversalNumber(); + +// Some memory stress testing added by Steve to reveal crashes under Windows. +// // Start Added by SMW +// osg::Transform* Tnode = (osg::Transform *)node; +// int i; +// osg::Node *n; +// while (Tnode->getNumChildren() > 0) +// { +// n = Tnode->getChild(0); +// Tnode->removeChild(n); +// } +// for (i = 0;i < 500;i++) +// { +// Tnode->addChild( createCube() ); +// } +// // End Added by SMW + + } + } + } + + // must continue subgraph traversal. + traverse(node,nv); + + } + + protected: + + osg::Transform* _nodeToOperateOn; + float _angular_velocity; + + int _previousTraversalNumber; + osg::Timer _timer; + osg::Timer_t _orig_t; + +}; + +osg::Geode* createCube() +{ + osg::Geode* geode = new osg::Geode(); + + // ------------------------------------------- + // Set up a new GeoSet which will be our cube + // ------------------------------------------- + osg::GeoSet* cube = new osg::GeoSet(); + + // set up the primitives + cube->setPrimType( osg::GeoSet::POLYGON ); + cube->setNumPrims( 6 ); // the six square faces + + // set up the primitive indices + int* cubeLengthList = new int[6]; + cubeLengthList[0] = 4; // each side of the cube has 4 vertices + cubeLengthList[1] = 4; + cubeLengthList[2] = 4; + cubeLengthList[3] = 4; + cubeLengthList[4] = 4; + cubeLengthList[5] = 4; + + cube->setPrimLengths( cubeLengthList ); + + + // set up the coordinates. + osg::Vec3 *cubeCoords = new osg::Vec3[24]; + cubeCoords[0].set( -1.0000f, 1.0000f, -1.000f ); + cubeCoords[1].set( 1.0000f, 1.0000f, -1.0000f ); + cubeCoords[2].set( 1.0000f, -1.0000f, -1.0000f ); + cubeCoords[3].set( -1.0000f, -1.0000f, -1.000 ); + + cubeCoords[4].set( 1.0000f, 1.0000f, -1.0000f ); + cubeCoords[5].set( 1.0000f, 1.0000f, 1.0000f ); + cubeCoords[6].set( 1.0000f, -1.0000f, 1.0000f ); + cubeCoords[7].set( 1.0000f, -1.0000f, -1.0000f ); + + cubeCoords[8].set( 1.0000f, 1.0000f, 1.0000f ); + cubeCoords[9].set( -1.0000f, 1.0000f, 1.000f ); + cubeCoords[10].set( -1.0000f, -1.0000f, 1.000f ); + cubeCoords[11].set( 1.0000f, -1.0000f, 1.0000f ); + + cubeCoords[12].set( -1.0000f, 1.0000f, 1.000 ); + cubeCoords[13].set( -1.0000f, 1.0000f, -1.000 ); + cubeCoords[14].set( -1.0000f, -1.0000f, -1.000 ); + cubeCoords[15].set( -1.0000f, -1.0000f, 1.000 ); + + cubeCoords[16].set( -1.0000f, 1.0000f, 1.000 ); + cubeCoords[17].set( 1.0000f, 1.0000f, 1.0000f ); + cubeCoords[18].set( 1.0000f, 1.0000f, -1.0000f ); + cubeCoords[19].set( -1.0000f, 1.0000f, -1.000f ); + + cubeCoords[20].set( -1.0000f, -1.0000f, 1.000f ); + cubeCoords[21].set( -1.0000f, -1.0000f, -1.000f ); + cubeCoords[22].set( 1.0000f, -1.0000f, -1.0000f ); + cubeCoords[23].set( 1.0000f, -1.0000f, 1.0000f ); + + cube->setCoords( cubeCoords ); + + + // set up the normals. + osg::Vec3 *cubeNormals = new osg::Vec3[6]; + cubeNormals[0].set(0.0f,0.0f,-1.0f); + cubeNormals[1].set(1.0f,0.0f,0.0f); + cubeNormals[2].set(0.0f,0.0f,1.0f); + cubeNormals[3].set(-1.0f,0.0f,0.0f); + cubeNormals[4].set(0.0f,1.0f,0.0f); + cubeNormals[5].set(0.0f,-1.0f,0.0f); + cube->setNormals( cubeNormals ); + cube->setNormalBinding( osg::GeoSet::BIND_PERPRIM ); + + // --------------------------------------- + // Set up a StateSet to make the cube red + // --------------------------------------- + osg::StateSet* cubeState = new osg::StateSet(); + osg::Material* redMaterial = new osg::Material(); + osg::Vec4 red( 1.0f, 0.0f, 0.0f, 1.0f ); + redMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, red ); + cubeState->setAttribute( redMaterial ); + + cube->setStateSet( cubeState ); + + geode->addDrawable( cube ); + + return geode; +} + +osg::Geode* createGeometryCube() +{ + osg::Geode* geode = new osg::Geode(); + + // ------------------------------------------- + // Set up a new Geometry which will be our cube + // ------------------------------------------- + osg::Geometry* cube = new osg::Geometry(); + + // set up the primitives + + cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,0,4)); + cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,4,4)); + cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,8,4)); + cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,12,4)); + cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,16,4)); + cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,20,4)); + + + // set up coords. + osg::Vec3Array* coords = new osg::Vec3Array; + coords->resize(24); + + (*coords)[0].set( -1.0000f, 1.0000f, -1.000f ); + (*coords)[1].set( 1.0000f, 1.0000f, -1.0000f ); + (*coords)[2].set( 1.0000f, -1.0000f, -1.0000f ); + (*coords)[3].set( -1.0000f, -1.0000f, -1.000 ); + + (*coords)[4].set( 1.0000f, 1.0000f, -1.0000f ); + (*coords)[5].set( 1.0000f, 1.0000f, 1.0000f ); + (*coords)[6].set( 1.0000f, -1.0000f, 1.0000f ); + (*coords)[7].set( 1.0000f, -1.0000f, -1.0000f ); + + (*coords)[8].set( 1.0000f, 1.0000f, 1.0000f ); + (*coords)[9].set( -1.0000f, 1.0000f, 1.000f ); + (*coords)[10].set( -1.0000f, -1.0000f, 1.000f ); + (*coords)[11].set( 1.0000f, -1.0000f, 1.0000f ); + + (*coords)[12].set( -1.0000f, 1.0000f, 1.000 ); + (*coords)[13].set( -1.0000f, 1.0000f, -1.000 ); + (*coords)[14].set( -1.0000f, -1.0000f, -1.000 ); + (*coords)[15].set( -1.0000f, -1.0000f, 1.000 ); + + (*coords)[16].set( -1.0000f, 1.0000f, 1.000 ); + (*coords)[17].set( 1.0000f, 1.0000f, 1.0000f ); + (*coords)[18].set( 1.0000f, 1.0000f, -1.0000f ); + (*coords)[19].set( -1.0000f, 1.0000f, -1.000f ); + + (*coords)[20].set( -1.0000f, -1.0000f, 1.000f ); + (*coords)[21].set( -1.0000f, -1.0000f, -1.000f ); + (*coords)[22].set( 1.0000f, -1.0000f, -1.0000f ); + (*coords)[23].set( 1.0000f, -1.0000f, 1.0000f ); + + + cube->setVertexArray( coords ); + + + // set up the normals. + osg::Vec3Array* cubeNormals = new osg::Vec3Array; + cubeNormals->resize(6); + + (*cubeNormals)[0].set(0.0f,0.0f,-1.0f); + (*cubeNormals)[1].set(1.0f,0.0f,0.0f); + (*cubeNormals)[2].set(0.0f,0.0f,1.0f); + (*cubeNormals)[3].set(-1.0f,0.0f,0.0f); + (*cubeNormals)[4].set(0.0f,1.0f,0.0f); + (*cubeNormals)[5].set(0.0f,-1.0f,0.0f); + + cube->setNormalArray( cubeNormals ); + cube->setNormalBinding( osg::Geometry::PER_PRIMITIVE ); + + // --------------------------------------- + // Set up a StateSet to make the cube red + // --------------------------------------- + osg::StateSet* cubeState = new osg::StateSet(); + osg::Material* redMaterial = new osg::Material(); + osg::Vec4 red( 1.0f, 0.0f, 0.0f, 1.0f ); + redMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, red ); + cubeState->setAttribute( redMaterial ); + + cube->setStateSet( cubeState ); + + geode->addDrawable( cube ); + + return geode; +} + +int main( int argc, char **argv ) +{ + + glutInit( &argc, argv ); + + // create the commandline args. + std::vector commandLine; + for(int i=1;iaddChild( createCube() ); + myTransform->addChild( createGeometryCube() ); + + // move node in a circle at 90 degrees a sec. + myTransform->setAppCallback(new MyTransformCallback(myTransform,osg::inDegrees(90.0f))); + + // add model to viewer. + viewer.addViewport( myTransform ); + + // register trackball maniupulators. + viewer.registerCameraManipulator(new osgGA::TrackballManipulator); + + viewer.open(); + + viewer.run(); + + return 0; +} diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index ac6c80bf0..0db78a401 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -4,18 +4,18 @@ using namespace osg; Geometry::Geometry() { + _normalBinding = OFF; + _colorBinding = OFF; } Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop): Drawable(geometry,copyop), - _coords(geometry._coords), - _coordIndices(geometry._coordIndices), - _normals(geometry._normals), - _normalIndices(geometry._normalIndices), - _colors(geometry._colors), - _colorIndices(geometry._colorIndices), - _texCoordList(geometry._texCoordList), - _texCoordIndicesList(geometry._texCoordIndicesList) + _vertexArray(geometry._vertexArray), + _normalBinding(geometry._normalBinding), + _normalArray(geometry._normalArray), + _colorBinding(geometry._colorBinding), + _colorArray(geometry._colorArray), + _texCoordList(geometry._texCoordList) { } @@ -24,170 +24,163 @@ Geometry::~Geometry() // no need to delete, all automatically handled by ref_ptr :-) } -void Geometry::setTexCoordArray(unsigned int pos,AttributeArray* array) +void Geometry::setTexCoordArray(unsigned int unit,AttributeArray* array) { - if (_texCoordList.size()<=pos) - _texCoordList.resize(pos+1,0); + if (_texCoordList.size()<=unit) + _texCoordList.resize(unit+1,0); - _texCoordList[pos] = array; + _texCoordList[unit] = array; } -AttributeArray* Geometry::getTexCoordArray(unsigned int pos) +AttributeArray* Geometry::getTexCoordArray(unsigned int unit) { - if (pos<_texCoordList.size()) return _texCoordList[pos].get(); + if (unit<_texCoordList.size()) return _texCoordList[unit].get(); else return 0; } -void Geometry::setTexCoordIndicesArray(unsigned int pos,AttributeArray* array) -{ - if (_texCoordList.size()<=pos) - _texCoordList.resize(pos+1,0); - - _texCoordIndicesList[pos] = array; -} - -AttributeArray* Geometry::getTexCoordIndicesArray(unsigned int pos) -{ - if (pos<_texCoordIndicesList.size()) return _texCoordIndicesList[pos].get(); - else return 0; -} - -void Geometry::setAttribute(AttributeType type,AttributeArray* array) -{ - switch(type) - { - case(PRIMITIVES): - _primitives = array; - break; - case(COORDS): - _coords = array; - break; - case(NORMALS): - _normals = array; - break; - case(COLORS): - _colors = array; - break; - default: - if (type>=TEX_COORDS_0) - { - setTexCoordArray(type-TEX_COORDS_0,array); - } - break; - } -} - - -void Geometry::setAttribute(AttributeType type,AttributeArray* array,AttributeArray* indices) -{ - switch(type) - { - case(PRIMITIVES): - _primitives = array; - // indices not appropriate! - break; - case(COORDS): - _coords = array; - _coordIndices = indices; - break; - case(NORMALS): - _normals = array; - _normalIndices = indices; - break; - case(COLORS): - _colors = array; - _colorIndices = indices; - break; - default: - if (type>=TEX_COORDS_0) - { - setTexCoordArray(type-TEX_COORDS_0,array); - setTexCoordIndicesArray(type-TEX_COORDS_0,indices); - } - break; - } -} - - -AttributeArray* Geometry::getAttribute(AttributeType type) -{ - switch(type) - { - case(PRIMITIVES): - return _primitives.get(); - break; - case(COORDS): - return _coords.get(); - break; - case(NORMALS): - return _normals.get(); - break; - case(COLORS): - return _colors.get(); - break; - default: - if (type>=TEX_COORDS_0) - { - return getTexCoordArray(type-TEX_COORDS_0); - } - break; - } - return 0; -} - - -void Geometry::setIndices(AttributeType type,AttributeArray* indices) -{ - switch(type) - { - case(PRIMITIVES): - // indices not appropriate! - break; - case(COORDS): - _coordIndices = indices; - break; - case(NORMALS): - _normalIndices = indices; - break; - case(COLORS): - _colorIndices = indices; - break; - default: - if (type>=TEX_COORDS_0) - { - setTexCoordIndicesArray(type-TEX_COORDS_0,indices); - } - break; - } -} - - -AttributeArray* Geometry::getIndices(AttributeType type) -{ - switch(type) - { - case(COORDS): - return _coordIndices.get(); - break; - case(NORMALS): - return _normalIndices.get(); - break; - case(COLORS): - return _colorIndices.get(); - break; - default: - if (type>=TEX_COORDS_0) - { - return getTexCoordIndicesArray(type-TEX_COORDS_0); - } - break; - } - return 0; -} - - void Geometry::drawImmediateMode(State& /*state*/) { + if (!_vertexArray.valid()) return; + + // set up the vertex arrays. + glEnableClientState( GL_VERTEX_ARRAY ); + glVertexPointer(3,GL_FLOAT,0,_vertexArray->dataPointer()); + + + // set up texture coordinates. + for(unsigned int i=0;i<_texCoordList.size();++i) + { + AttributeArray* array = _texCoordList[i].get(); + glClientActiveTextureARB(GL_TEXTURE0_ARB+i); + if (array) + { + glEnableClientState( GL_TEXTURE_COORD_ARRAY ); + glTexCoordPointer(array->dataSize(),array->dataType(),0,array->dataPointer()); + } + else + { + glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + } + } + + + // set up normals. + Vec3* normalPointer = 0; + if (_normalArray.valid() && !_normalArray->empty()) normalPointer = &(_normalArray->front()); + + switch (_normalBinding) + { + case(OFF): + glDisableClientState( GL_NORMAL_ARRAY ); + break; + case(OVERALL): + if (normalPointer) glNormal3fv(reinterpret_cast(normalPointer)); + glDisableClientState( GL_NORMAL_ARRAY ); + break; + case(PER_PRIMITIVE): + glDisableClientState( GL_NORMAL_ARRAY ); + break; + case(PER_VERTEX): + glEnableClientState( GL_NORMAL_ARRAY ); + if (normalPointer) glNormalPointer(GL_FLOAT,0,normalPointer); + break; + } + + + // set up colors, complicated by the fact that the color array + // might be bound in 4 different ways, and be represented as 3 different data types - + // Vec3, Vec4 or UByte4 Arrays. + const unsigned char* colorPointer = 0; + unsigned int colorStride = 0; + ArrayType colorType = AttributeArrayType; + if (_colorArray.valid()) + { + colorType = _colorArray->arrayType(); + switch(colorType) + { + case(UByte4ArrayType): + { + colorPointer = reinterpret_cast(_colorArray->dataPointer()); + colorStride = 4; + break; + } + case(Vec3ArrayType): + { + colorPointer = reinterpret_cast(_colorArray->dataPointer()); + colorStride = 12; + break; + } + case(Vec4ArrayType): + { + colorPointer = reinterpret_cast(_colorArray->dataPointer()); + colorStride = 16; + break; + } + } + } + + switch (_colorBinding) + { + case(OFF): + glDisableClientState( GL_COLOR_ARRAY ); + break; + case(OVERALL): + glDisableClientState( GL_COLOR_ARRAY ); + if (colorPointer) + { + switch(colorType) + { + case(UByte4ArrayType): + glColor4ubv(reinterpret_cast(colorPointer)); + break; + case(Vec3ArrayType): + glColor3fv(reinterpret_cast(colorPointer)); + break; + case(Vec4ArrayType): + glColor4fv(reinterpret_cast(colorPointer)); + break; + } + } + break; + case(PER_PRIMITIVE): + glDisableClientState( GL_COLOR_ARRAY ); + break; + case(PER_VERTEX): + glEnableClientState( GL_COLOR_ARRAY ); + if (colorPointer) glColorPointer(_colorArray->dataSize(),_colorArray->dataType(),0,colorPointer); + } + + + // draw the primitives themselves. + for(PrimitiveList::iterator itr=_primitives.begin(); + itr!=_primitives.end(); + ++itr) + { + if (_normalBinding==PER_PRIMITIVE) + { + glNormal3fv((const GLfloat *)normalPointer++); + } + + if (_colorBinding==PER_PRIMITIVE) + { + switch(colorType) + { + case(UByte4ArrayType): + glColor4ubv(reinterpret_cast(colorPointer)); + break; + case(Vec3ArrayType): + glColor3fv(reinterpret_cast(colorPointer)); + break; + case(Vec4ArrayType): + glColor4fv(reinterpret_cast(colorPointer)); + break; + } + colorPointer += colorStride; + } + + (*itr)->draw(); + } + } /** Statistics collection for each drawable- 26.09.01 @@ -213,7 +206,7 @@ const bool Geometry::computeBound() const { _bbox.init(); - const Vec3Array* coords = dynamic_cast(_coords.get()); + const Vec3Array* coords = dynamic_cast(_vertexArray.get()); if (coords) { for(Vec3Array::const_iterator itr=coords->begin();