Added OpenDX writer from Randall Hopper.

This commit is contained in:
Robert Osfield 2002-02-18 20:46:47 +00:00
parent 685d0b08cb
commit 4abfdb1ebd
17 changed files with 3918 additions and 8 deletions

View File

@ -52,6 +52,7 @@ Byan Woods <byran@tapestrysolutions.com>
Randall Hopper <aa8vb@yahoo.com> Randall Hopper <aa8vb@yahoo.com>
- port to FreeBSD. - port to FreeBSD.
- warning fixes to IRIX compilation. - warning fixes to IRIX compilation.
- Open DX writer.
Ulrich Hertlein <u.hertlein@bit-side.com> Ulrich Hertlein <u.hertlein@bit-side.com>
- support for IBM Mirror Repeat extension in osg::Texture - support for IBM Mirror Repeat extension in osg::Texture

4
NEWS
View File

@ -1,7 +1,7 @@
OSG News (most significant items from ChangeLog) OSG News (most significant items from ChangeLog)
================================================ ================================================
10th February 2002 - osg-0.8.44.tar.gz 18th February 2002 - osg-0.8.44.tar.gz
>>> Support added for Mac OSX, Cygwin and MinGW, and new TerraPage loader. >>> Support added for Mac OSX, Cygwin and MinGW, and new TerraPage loader.
@ -28,6 +28,8 @@ OSG News (most significant items from ChangeLog)
The Open Flight .flt loader has undergone a number of improvements The Open Flight .flt loader has undergone a number of improvements
including support for instancing and billboards. including support for instancing and billboards.
New TerraPage (.txp) loader and OpenDX writer (.dx) plugins have been added.
Support for the clone operation on osg::Object's has been expanded Support for the clone operation on osg::Object's has been expanded
to allow cloneType() - a simple clone an blank object of the same type, to allow cloneType() - a simple clone an blank object of the same type,
and clone(CopyOp&) where CopyOp is a functor which allows users to and clone(CopyOp&) where CopyOp is a functor which allows users to

View File

@ -213,6 +213,24 @@ Package=<4>
############################################################################### ###############################################################################
Project: "dx"=".\osgPlugins\dx\dx.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name osg
End Project Dependency
Begin Project Dependency
Project_Dep_Name osgDB
End Project Dependency
}}}
###############################################################################
Project: "osg"=.\osg\osg.dsp - Package Owner=<4> Project: "osg"=.\osg\osg.dsp - Package Owner=<4>
Package=<5> Package=<5>

138
VisualStudio/osgPlugins/dx/dx.dsp Executable file
View File

@ -0,0 +1,138 @@
# Microsoft Developer Studio Project File - Name="dx" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=dx - Win32 Debug
!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 "dx.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 "dx.mak" CFG="dx - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "dx - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "dx - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "dx - 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 "../../../lib"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# 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 /dll /machine:I386
# ADD LINK32 /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_dx.dll" /libpath:"../../../lib"
# SUBTRACT LINK32 /nodefaultlib
!ELSEIF "$(CFG)" == "dx - 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 "../../../lib"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /vmg /vd0 /GR /GX /Zi /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# 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 /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 /nologo /dll /debug /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_dxd.dll" /pdbtype:sept /libpath:"../../../lib"
# SUBTRACT LINK32 /pdb:none /nodefaultlib
!ENDIF
# Begin Target
# Name "dx - Win32 Release"
# Name "dx - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\dx\AreaGeoSetTriangulator.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\dx\DXWriter.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\dx\ReaderWriterDX.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\dx\StateSetStr.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\dx\AreaGeoSetTriangulator.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\dx\DXWriter.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\dx\ReaderWriterDX.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\dx\StateSetStr.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project


View File

@ -97,6 +97,9 @@ class OSGGLUT_EXPORT GLUTEventAdapter : public osgUtil::GUIEventAdapter
// which required the mouse buttons state at the time of the event. // which required the mouse buttons state at the time of the event.
static unsigned int _s_accumulatedButtonMask; static unsigned int _s_accumulatedButtonMask;
// used to store current button value
static int _s_button;
// used to store window min and max values. // used to store window min and max values.
static int _s_Xmin; static int _s_Xmin;
static int _s_Xmax; static int _s_Xmax;

View File

@ -6,6 +6,7 @@ using namespace osgGLUT;
// default to no mouse buttons being pressed. // default to no mouse buttons being pressed.
unsigned int GLUTEventAdapter::_s_accumulatedButtonMask = 0; unsigned int GLUTEventAdapter::_s_accumulatedButtonMask = 0;
int GLUTEventAdapter::_s_button = 0;
int GLUTEventAdapter::_s_Xmin = 0; int GLUTEventAdapter::_s_Xmin = 0;
int GLUTEventAdapter::_s_Xmax = 1280; int GLUTEventAdapter::_s_Xmax = 1280;
int GLUTEventAdapter::_s_Ymin = 0; int GLUTEventAdapter::_s_Ymin = 0;
@ -31,6 +32,7 @@ GLUTEventAdapter::GLUTEventAdapter()
void GLUTEventAdapter::copyStaticVariables() void GLUTEventAdapter::copyStaticVariables()
{ {
_buttonMask = _s_accumulatedButtonMask; _buttonMask = _s_accumulatedButtonMask;
_button = _s_button;
_Xmin = _s_Xmin; _Xmin = _s_Xmin;
_Xmax = _s_Xmax; _Xmax = _s_Xmax;
_Ymin = _s_Ymin; _Ymin = _s_Ymin;
@ -99,9 +101,21 @@ void GLUTEventAdapter::adaptMouse(float time, int button, int state, int x, int
switch(button) switch(button)
{ {
case(GLUT_LEFT_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask | LEFT_MOUSE_BUTTON; break; case(GLUT_LEFT_BUTTON):
case(GLUT_MIDDLE_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask | MIDDLE_MOUSE_BUTTON; break; _s_accumulatedButtonMask =
case(GLUT_RIGHT_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask | RIGHT_MOUSE_BUTTON; break; _s_accumulatedButtonMask | LEFT_MOUSE_BUTTON;
_s_button = LEFT_MOUSE_BUTTON;
break;
case(GLUT_MIDDLE_BUTTON):
_s_accumulatedButtonMask =
_s_accumulatedButtonMask | MIDDLE_MOUSE_BUTTON;
_s_button = MIDDLE_MOUSE_BUTTON;
break;
case(GLUT_RIGHT_BUTTON):
_s_accumulatedButtonMask =
_s_accumulatedButtonMask | RIGHT_MOUSE_BUTTON;
_s_button = RIGHT_MOUSE_BUTTON;
break;
} }
} }
@ -113,9 +127,21 @@ void GLUTEventAdapter::adaptMouse(float time, int button, int state, int x, int
switch(button) switch(button)
{ {
case(GLUT_LEFT_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask & ~LEFT_MOUSE_BUTTON; break; case(GLUT_LEFT_BUTTON):
case(GLUT_MIDDLE_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask & ~MIDDLE_MOUSE_BUTTON; break; _s_accumulatedButtonMask =
case(GLUT_RIGHT_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask & ~RIGHT_MOUSE_BUTTON; break; _s_accumulatedButtonMask & ~LEFT_MOUSE_BUTTON;
_s_button = LEFT_MOUSE_BUTTON;
break;
case(GLUT_MIDDLE_BUTTON):
_s_accumulatedButtonMask =
_s_accumulatedButtonMask & ~MIDDLE_MOUSE_BUTTON;
_s_button = MIDDLE_MOUSE_BUTTON;
break;
case(GLUT_RIGHT_BUTTON):
_s_accumulatedButtonMask =
_s_accumulatedButtonMask & ~RIGHT_MOUSE_BUTTON;
_s_button = RIGHT_MOUSE_BUTTON;
break;
} }
} }

View File

@ -6,6 +6,10 @@ DIRS = osg rgb lib3ds flt obj lwo txp dw bmp pic tga osgtgz tgz zip
# comment in if you have Performer installed. # comment in if you have Performer installed.
# DIRS += pfb # DIRS += pfb
# comment in if you want Open DX support, currently not in by default
# since we havn't yet checked compilation on all platforms yet.
# DIRS += dx
# comment in if you have Quicktime installed, i.e under Mac OS. # comment in if you have Quicktime installed, i.e under Mac OS.
# if in this case then its likely you'll want to comment out the below # if in this case then its likely you'll want to comment out the below
# png, jpeg, gif and tiff plugins. # png, jpeg, gif and tiff plugins.

View File

@ -0,0 +1,640 @@
#include <stdio.h>
#include <string.h>
#include <osg/GeoSet>
#include "AreaGeoSetTriangulator.h"
namespace dx {
class AreaGeoSetTriangulator
// Used to convert area primitive GeoSets into TRIANGLE Geosets.
// Efficiently collects the various data arrays, which GeoSet can't do.
{
protected:
std::vector< osg::uint > _cindex;
std::vector< osg::uint > _nindex;
std::vector< osg::uint > _colindex;
std::vector< osg::uint > _tindex;
const osg::GeoSet &_area_geoset;
public:
AreaGeoSetTriangulator( const osg::GeoSet &area_geoset );
void operator() ( osg::uint v1, osg::uint v2, osg::uint v3,
osg::uint prim_index, osg::uint prim_tri_index,
osg::uint v1_geoset, osg::uint v2_geoset,
osg::uint v3_geoset );
// Passed triangles as primitives are triangulated
osg::GeoSet *BuildGeoSet();
};
//---------------------------------------------------------------------------
AreaGeoSetTriangulator::AreaGeoSetTriangulator( const osg::GeoSet &area_geoset)
: _area_geoset(area_geoset)
{
// Check type
switch ( area_geoset.getPrimType() ) {
case osg::GeoSet::TRIANGLE_STRIP:
case osg::GeoSet::FLAT_TRIANGLE_STRIP:
case osg::GeoSet::TRIANGLES:
case osg::GeoSet::QUAD_STRIP:
case osg::GeoSet::QUADS:
case osg::GeoSet::TRIANGLE_FAN:
case osg::GeoSet::FLAT_TRIANGLE_FAN:
case osg::GeoSet::POLYGON:
break;
default:
fprintf( stderr,
"Invalid primitive type passed to AreaGeoSetTriangulator\n" );
exit(1);
}
// NOTE: _coords, _normals, _colors, and _tcoords are maintained
// from the original geoset. The new geoset will always have
// indexed coords/normals/colors/tcoords (to save space).
}
//---------------------------------------------------------------------------
void AreaGeoSetTriangulator::operator() (
osg::uint v1, osg::uint v2, osg::uint v3,
osg::uint prim_index, osg::uint prim_tri_index,
osg::uint v1_geoset, osg::uint v2_geoset,
osg::uint v3_geoset )
// Passed triangles as primitives are triangulated from the original
// GeoSet. Note that the v? params are indicies into the Coord array,
// whereas the v?_geoset params are vertex numbers relative to the
// entire "area GeoSet" (which are different when the coords are
// indexed). The latter is needed to look up colors/normals/tcoords).
{
osg::GeoSet::BindingType binding;
osg::GeoSet::PrimitiveType primtype = _area_geoset.getPrimType();
int area_is_flatprim = ( primtype == osg::GeoSet::FLAT_TRIANGLE_STRIP ||
primtype == osg::GeoSet::FLAT_TRIANGLE_FAN );
// Store the triangle coord indicies
_cindex.push_back( v1 );
_cindex.push_back( v2 );
_cindex.push_back( v3 );
int index;
const osg::GeoSet::IndexPointer *ip;
// Store normals (as needed)
if ( _area_geoset.getNumNormals() ) {
ip = &_area_geoset.getNormalIndices();
// Grrr... FLAT_ primitives lie about binding type... like Performer
binding = _area_geoset.getNormalBinding();
if ( area_is_flatprim && binding == osg::GeoSet::BIND_PERVERTEX )
binding = osg::GeoSet::BIND_PERPRIM;
switch ( binding ) {
case osg::GeoSet::BIND_OVERALL : // Only once
if ( prim_index == 0 && prim_tri_index == 0 ) {
index = ip->valid() ? (*ip)[0] : 0;
_nindex.push_back( index );
break;
}
case osg::GeoSet::BIND_PERPRIM : // Once per tri
index = ip->valid() ? (*ip)[prim_index] : prim_index;
_nindex.push_back( index );
break;
case osg::GeoSet::BIND_PERVERTEX : // Each vertex
index = ip->valid() ? (*ip)[v1_geoset] : v1_geoset;
_nindex.push_back( index );
index = ip->valid() ? (*ip)[v2_geoset] : v2_geoset;
_nindex.push_back( index );
index = ip->valid() ? (*ip)[v3_geoset] : v3_geoset;
_nindex.push_back( index );
break;
case osg::GeoSet::BIND_OFF:
case osg::GeoSet::BIND_DEFAULT:
// Nonsensical cases
break;
}
}
// Store colors (as needed)
if ( _area_geoset.getNumColors() ) {
ip = &_area_geoset.getColorIndices();
// Grrr... FLAT_ primitives lie about binding type... like Performer
binding = _area_geoset.getColorBinding();
if ( area_is_flatprim && binding == osg::GeoSet::BIND_PERVERTEX )
binding = osg::GeoSet::BIND_PERPRIM;
switch ( binding ) {
case osg::GeoSet::BIND_OVERALL : // Only once
if ( prim_index == 0 && prim_tri_index == 0 ) {
index = ip->valid() ? (*ip)[0] : 0;
_colindex.push_back( index );
break;
}
case osg::GeoSet::BIND_PERPRIM : // Once per tri
index = ip->valid() ? (*ip)[prim_index] : prim_index;
_colindex.push_back( index );
break;
case osg::GeoSet::BIND_PERVERTEX : // Each vertex
index = ip->valid() ? (*ip)[v1_geoset] : v1_geoset;
_colindex.push_back( index );
index = ip->valid() ? (*ip)[v2_geoset] : v2_geoset;
_colindex.push_back( index );
index = ip->valid() ? (*ip)[v3_geoset] : v3_geoset;
_colindex.push_back( index );
break;
case osg::GeoSet::BIND_OFF:
case osg::GeoSet::BIND_DEFAULT:
// Nonsensical cases
break;
}
}
// Store tcoords (as needed)
if ( _area_geoset.getNumTextureCoords() ) {
ip = &_area_geoset.getTextureIndices();
switch ( _area_geoset.getTextureBinding() ) {
case osg::GeoSet::BIND_OVERALL : // Only once
if ( prim_index == 0 && prim_tri_index == 0 ) {
index = ip->valid() ? (*ip)[0] : 0;
_tindex.push_back( index );
break;
}
case osg::GeoSet::BIND_PERPRIM : // Once per tri
index = ip->valid() ? (*ip)[prim_index] : prim_index;
_tindex.push_back( index );
break;
case osg::GeoSet::BIND_PERVERTEX : // Each vertex
index = ip->valid() ? (*ip)[v1_geoset] : v1_geoset;
_tindex.push_back( index );
index = ip->valid() ? (*ip)[v2_geoset] : v2_geoset;
_tindex.push_back( index );
index = ip->valid() ? (*ip)[v3_geoset] : v3_geoset;
_tindex.push_back( index );
break;
case osg::GeoSet::BIND_OFF:
case osg::GeoSet::BIND_DEFAULT:
// Nonsensical cases
break;
}
}
}
//----------------------------------------------------------------------------
// Shamelessly lifted from the GeoSet header and adapted for our uses
// This is the same except that: 1) it passes the coordinate indices
// to the op function insted of the Vec3s, and 2) it passes an original
// primitive index and "triangle-in-primitive" index to the op function,
// 3) it also passes the absolute vertex numbers in the primitive so they
// can be used to look up normals/colors/tcoords, and 4) fixes some
// problems with vertex ordering which caused FRONT/BACK confusion with
// normals and lighting.
// With this, we can construct a new TRIANGLE GeoSet from any area GeoSet.
/** Template function for iterating through a GeoSet operating on triangles
with templated functor. Function automatically decomposes quads and polygons
into sub triangles which are passed onto functor.*/
template<class T>
void for_each_triangle2(const osg::GeoSet& gset,T& op)
{
switch(gset.getPrimType())
{
case(osg::GeoSet::TRIANGLE_STRIP):
case(osg::GeoSet::FLAT_TRIANGLE_STRIP):
{
if (gset.getCoordIndices().valid())
{
if (gset.getCoordIndices()._is_ushort)
{
osg::ushort* base = gset.getCoordIndices()._ptr._ushort;
osg::ushort* iptr = base;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
const int primLength = gset.getPrimLengths()[i];
osg::ushort* iend = iptr+primLength;
int tri=0;
for(int j = 2; j < primLength; j++ )
{
if( !(j%2) )
op(*(iptr),*(iptr+1),*(iptr+2),i,tri++,
iptr-base,(iptr+1)-base,(iptr+2)-base);
else
op(*(iptr),*(iptr+2),*(iptr+1),i,tri++,
iptr-base,(iptr+2)-base,(iptr+1)-base);
++iptr;
}
iptr=iend;
}
}
else
{
osg::uint* base = gset.getCoordIndices()._ptr._uint;
osg::uint* iptr = base;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
const int primLength = gset.getPrimLengths()[i];
osg::uint* iend = iptr+primLength;
int tri=0;
for(int j = 2; j < primLength; j++ )
{
if( !(j%2) )
op(*(iptr),*(iptr+1),*(iptr+2),i,tri++,
iptr-base,(iptr+1)-base,(iptr+2)-base);
else
op(*(iptr),*(iptr+2),*(iptr+1),i,tri++,
iptr-base,(iptr+2)-base,(iptr+1)-base);
++iptr;
}
iptr=iend;
}
}
}
else
{
osg::uint cindex = 0;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
const int primLength = gset.getPrimLengths()[i];
osg::uint cindex_end = cindex+primLength;
int tri=0;
for(int j = 2; j < primLength; j++ )
{
if( !(j%2) )
op(cindex,cindex+1,cindex+2,i,tri++,
cindex,cindex+1,cindex+2);
else
op(cindex,cindex+2,cindex+1,i,tri++,
cindex,cindex+2,cindex+1);
++cindex;
}
cindex = cindex_end;
}
}
}
break;
case(osg::GeoSet::TRIANGLES):
{
if (gset.getCoordIndices().valid())
{
if (gset.getCoordIndices()._is_ushort)
{
osg::ushort* base = gset.getCoordIndices()._ptr._ushort;
osg::ushort* iptr = base;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
op(*(iptr),*(iptr+1),*(iptr+2),i,0,
iptr-base,(iptr+1)-base,(iptr+2)-base);
iptr+=3;
}
}
else
{
osg::uint* base = gset.getCoordIndices()._ptr._uint;
osg::uint* iptr = base;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
op(*(iptr),*(iptr+1),*(iptr+2),i,0,
iptr-base,(iptr+1)-base,(iptr+2)-base);
iptr+=3;
}
}
}
else
{
osg::uint cindex = 0;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
op(cindex,cindex+1,cindex+2,i,0,
cindex,cindex+1,cindex+2);
cindex+=3;
}
}
}
break;
case(osg::GeoSet::QUAD_STRIP):
{
if (gset.getCoordIndices().valid())
{
if (gset.getCoordIndices()._is_ushort)
{
osg::ushort* base = gset.getCoordIndices()._ptr._ushort;
osg::ushort* iptr = base;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
const int primLength = gset.getPrimLengths()[i];
osg::ushort* iend = iptr+primLength;
int tri=0;
for(int j = 3; j < primLength; j+=2 )
{
op(*(iptr),*(iptr+1),*(iptr+2),i,tri++,
iptr-base,(iptr+1)-base,(iptr+2)-base);
// rhh FIXME: FIXED 1st vert offset
op(*(iptr+1),*(iptr+3),*(iptr+2),i,tri++,
(iptr+1)-base,(iptr+3)-base,(iptr+2)-base);
iptr+=2;
}
iptr=iend;
}
}
else
{
osg::uint* base = gset.getCoordIndices()._ptr._uint;
osg::uint* iptr = base;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
const int primLength = gset.getPrimLengths()[i];
osg::uint* iend = iptr+primLength;
int tri=0;
for(int j = 3; j < primLength; j+=2 )
{
op(*(iptr),*(iptr+1),*(iptr+2),i,tri++,
iptr-base,(iptr+1)-base,(iptr+2)-base);
op(*(iptr+1),*(iptr+3),*(iptr+2),i,tri++,
(iptr+1)-base,(iptr+3)-base,(iptr+2)-base);
iptr+=2;
}
iptr=iend;
}
}
}
else
{
osg::uint cindex = 0;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
const int primLength = gset.getPrimLengths()[i];
osg::uint cindex_end = cindex+primLength;
int tri=0;
for(int j = 3; j < primLength; j+=2 )
{
op(cindex,cindex+1,cindex+2,i,tri++,
cindex,cindex+1,cindex+2);
op(cindex+1,cindex+3,cindex+2,i,tri++,
cindex+1,cindex+3,cindex+2);
cindex+=2;
}
cindex = cindex_end;
}
}
}
break;
case(osg::GeoSet::QUADS):
{
if (gset.getCoordIndices().valid())
{
if (gset.getCoordIndices()._is_ushort)
{
osg::ushort* base = gset.getCoordIndices()._ptr._ushort;
osg::ushort* iptr = base;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
op(*(iptr),*(iptr+1),*(iptr+2),i,0,
iptr-base,(iptr+1)-base,(iptr+2)-base);
// rhh FIXME: FIXED 2nd & 3rd vert offset
op(*(iptr),*(iptr+2),*(iptr+3),i,1,
iptr-base,(iptr+2)-base,(iptr+3)-base);
iptr+=4;
}
}
else
{
osg::uint* base = gset.getCoordIndices()._ptr._uint;
osg::uint* iptr = base;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
op(*(iptr),*(iptr+1),*(iptr+2),i,0,
iptr-base,(iptr+1)-base,(iptr+2)-base);
op(*(iptr),*(iptr+2),*(iptr+3),i,1,
iptr-base,(iptr+2)-base,(iptr+3)-base);
iptr+=4;
}
}
}
else
{
osg::uint cindex = 0;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
op(cindex,cindex+1,cindex+2,i,0,
cindex,cindex+1,cindex+2);
op(cindex,cindex+2,cindex+3,i,1,
cindex,cindex+2,cindex+3);
cindex+=4;
}
}
}
break;
case(osg::GeoSet::TRIANGLE_FAN):
case(osg::GeoSet::FLAT_TRIANGLE_FAN): // FIXME: rhh added
case(osg::GeoSet::POLYGON):
{
if (gset.getCoordIndices().valid())
{
if (gset.getCoordIndices()._is_ushort)
{
osg::ushort* base = gset.getCoordIndices()._ptr._ushort;
osg::ushort* iptr = base;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
const int primLength = gset.getPrimLengths()[i];
int tri=0;
if (primLength>0)
{
osg::ushort *start = iptr;
osg::ushort* iend = iptr+primLength;
++iptr;
for(int j = 2; j < primLength; ++j )
{
op(*start,*(iptr),*(iptr+1),i,tri++,
start-base, iptr-base,(iptr+1)-base);
++iptr;
}
iptr=iend;
}
}
}
else
{
osg::uint* base = gset.getCoordIndices()._ptr._uint;
osg::uint* iptr = base;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
const int primLength = gset.getPrimLengths()[i];
int tri=0;
if (primLength>0)
{
osg::uint *start = iptr;
osg::uint* iend = iptr+primLength;
++iptr;
for(int j = 2; j < primLength; ++j )
{
op(*start,*(iptr),*(iptr+1),i,tri++,
start-base, iptr-base,(iptr+1)-base);
++iptr;
}
iptr=iend;
}
}
}
}
else
{
osg::uint cindex = 0;
const int numPrim = gset.getNumPrims();
for(int i=0; i<numPrim; ++i )
{
const int primLength = gset.getPrimLengths()[i];
int tri=0;
if (primLength>0)
{
osg::uint cindex_start = cindex;
osg::uint cindex_end = cindex+primLength;
++cindex;
for(int j = 2; j < primLength; ++j)
{
op(cindex_start,cindex,cindex+1,i,tri++,
cindex_start,cindex,cindex+1);
++cindex;
}
cindex = cindex_end;
}
}
}
}
break;
default:
break;
}
};
//---------------------------------------------------------------------------
osg::GeoSet *AreaGeoSetTriangulator::BuildGeoSet()
// After a triangulation pass, generate a valid TRIANGLE GeoSet containing
// the resulting triangles (w/ colors, normals, and tcoords).
{
int num_tris = _cindex.size() / 3;
osg::GeoSet *res = new osg::GeoSet;
res->setPrimType( osg::GeoSet::TRIANGLES );
res->setNumPrims( num_tris );
// First, dup all of the data arrays -- they haven't changed
// NOTE: We generate fresh arrays for the new GeoSet to be compatible
// with the delete [] behavior of the default GeoSet
// AttributeDeleteFunctor, which is invoked in GeoSet::~GeoSet.
osg::Vec3 *new_coords = 0;
osg::Vec3 *new_normals = 0;
osg::Vec4 *new_colors = 0;
osg::Vec2 *new_tcoords = 0;
const osg::Vec3 *coords = _area_geoset.getCoords();
const osg::Vec3 *normals = _area_geoset.getNormals();
const osg::Vec4 *colors = _area_geoset.getColors();
const osg::Vec2 *tcoords = _area_geoset.getTextureCoords();
if ( coords )
new_coords = new osg::Vec3[ _area_geoset.getNumCoords() ];
if ( normals )
new_normals = new osg::Vec3[ _area_geoset.getNumNormals() ];
if ( colors )
new_colors = new osg::Vec4[ _area_geoset.getNumColors() ];
if ( tcoords )
new_tcoords = new osg::Vec2[ _area_geoset.getNumTextureCoords() ];
memcpy( new_coords, coords,
sizeof(osg::Vec3) * _area_geoset.getNumCoords() );
memcpy( new_normals, normals,
sizeof(osg::Vec3) * _area_geoset.getNumNormals() );
memcpy( new_colors, colors,
sizeof(osg::Vec4) * _area_geoset.getNumColors() );
memcpy( new_tcoords, tcoords,
sizeof(osg::Vec2) * _area_geoset.getNumTextureCoords() );
// Now generate the index arrays
osg::uint *new_cindex = 0;
osg::uint *new_nindex = 0;
osg::uint *new_colindex = 0;
osg::uint *new_tindex = 0;
if ( _cindex.size() ) new_cindex = new osg::uint[ _cindex.size() ];
if ( _nindex.size() ) new_nindex = new osg::uint[ _nindex.size() ];
if ( _colindex.size() ) new_colindex = new osg::uint[ _colindex.size() ];
if ( _tindex.size() ) new_tindex = new osg::uint[ _tindex.size() ];
memcpy( new_cindex , &_cindex [0], sizeof(osg::uint) * _cindex.size() );
memcpy( new_nindex , &_nindex [0], sizeof(osg::uint) * _nindex.size() );
memcpy( new_colindex, &_colindex[0], sizeof(osg::uint) * _colindex.size() );
memcpy( new_tindex , &_tindex [0], sizeof(osg::uint) * _tindex.size() );
res->setCoords ( new_coords , new_cindex );
res->setNormals( new_normals, new_nindex );
res->setColors ( new_colors , new_colindex );
res->setTextureCoords( new_tcoords, new_tindex );
// And finally, set the normal/color/tcoord binding
// (Grrr... FLAT_ primitives lie about binding type... like Performer)
osg::GeoSet::BindingType nbinding = _area_geoset.getNormalBinding();
osg::GeoSet::BindingType cbinding = _area_geoset.getColorBinding();
if ( _area_geoset.getPrimType() == osg::GeoSet::FLAT_TRIANGLE_STRIP ||
_area_geoset.getPrimType() == osg::GeoSet::FLAT_TRIANGLE_FAN ) {
if ( nbinding == osg::GeoSet::BIND_PERVERTEX )
nbinding = osg::GeoSet::BIND_PERPRIM;
if ( cbinding == osg::GeoSet::BIND_PERVERTEX )
cbinding = osg::GeoSet::BIND_PERPRIM;
}
res->setNormalBinding ( nbinding );
res->setColorBinding ( cbinding );
res->setTextureBinding( _area_geoset.getTextureBinding() );
return res;
}
//---------------------------------------------------------------------------
osg::GeoSet *TriangulateAreaGeoSet( const osg::GeoSet &geoset )
// The strategy here is to generate new coord/normal/color/tcoord index
// arrays as we bust up the primitives into triangles. The data arrays
// don't change between the old and new geoset.
{
geoset.computeNumVerts(); // Update # coords/# normals from index arrays
AreaGeoSetTriangulator triangulator( geoset );
for_each_triangle2( geoset, triangulator );
return triangulator.BuildGeoSet();
}
}; // namespace dx

View File

@ -0,0 +1,12 @@
#ifndef __OSG_AREA_GEOSET_TRIANGULATOR_H
#define __OSG_AREA_GEOSET_TRIANGULATOR_H
#include <osg/GeoSet>
namespace dx {
osg::GeoSet *TriangulateAreaGeoSet( const osg::GeoSet &geoset );
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
// This plugin writes an IBM Data Explorer (aka OpenDX) native file.
// (c) Randall Hopper, 2002.
//
// For details on the OpenDX visualization tool, its use, and its file format,
// refer to:
//
// http://www.opendx.org/
// http://www.opendx.org/support.html#docs
// http://www.research.ibm.com/dx/
// http://ftp.cs.umt.edu/DX/
//
// SUPPORTED : Refer to DXWriter.cpp
// UNSUPPORTED: Refer to DXWriter.cpp
//
// DXWriter.h
#ifndef __OSG_DXWRITER_H
#define __OSG_DXWRITER_H
#include <osg/Vec4>
#include <osg/Node>
namespace dx {
//----------------------------------------------------------------------------
struct WriterParms {
bool set_default_color; // Give color to uncolored objects
osg::Vec4 default_color; // Color to assign to uncolored objects
char outfile[ PATH_MAX ]; // Output pathname
//bool binary_mode; // Write DX arrays in binary format
WriterParms()
{ set_default_color = 0, outfile[0] = '\0'; }
};
//----------------------------------------------------------------------------
bool WriteDX( const osg::Node &node, WriterParms &parms,
std::string &messages );
}; // namespace dx
//----------------------------------------------------------------------------
#endif // __OSG_DXWRITER_H

View File

@ -0,0 +1,23 @@
#!smake
include $(OSGHOME)/Make/makedefs
C++FILES = ReaderWriterDX.cpp \
DXWriter.cpp \
AreaGeoSetTriangulator.cpp \
StateSetStr.cpp
TARGET_BASENAME = osgdb_dx
LOADABLE = $(OSGHOME)/lib/osgPlugins/$(TARGET_BASENAME).$(DL_EXT)
LIB=
TARGET_LOADER_FILES = osgPlugins/$(TARGET_BASENAME).$(DL_EXT)
LIBS = $(GL_LIBS) -losg -losgDB
MACOSXLIBS = -L$(OSGHOME)/lib -losg -losgDB -lstdc++
C++FLAGS += -I. -I$(OSGHOME)/include
LDFLAGS += -L$(OSGHOME)/lib
include $(OSGHOME)/Make/makerules

View File

@ -0,0 +1,79 @@
// This plugin writes an IBM Data Explorer (aka OpenDX) native file.
// (c) Randall Hopper, 2002.
//
// For details on the OpenDX visualization tool, its use, and its file format,
// refer to:
//
// http://www.opendx.org/
// http://www.opendx.org/support.html#docs
// http://www.research.ibm.com/dx/
// http://ftp.cs.umt.edu/DX/
//
// SUPPORTED : Refer to DXWriter.cpp
// UNSUPPORTED: Refer to DXWriter.cpp
//
// ReaderWriterDX.cpp
#include <iostream>
#include <string.h>
#include <osg/Notify>
#include "ReaderWriterDX.h"
#include "DXWriter.h"
// FIXME: Support options
osgDB::ReaderWriter::WriteResult ReaderWriterDX::writeObject(
const osg::Object &obj,
const std::string &filename,
const Options *options )
{
const osg::Node *node = dynamic_cast<const osg::Node *>(&obj);
if ( node != 0 )
return writeNode( *node, filename, options );
else
// FIXME: This should probably be "OBJECT_NOT_HANDLED"
return osgDB::ReaderWriter::WriteResult::FILE_NOT_HANDLED;
}
osgDB::ReaderWriter::WriteResult ReaderWriterDX::writeNode(
const osg::Node &node,
const std::string &filename,
const Options *options )
{
dx::WriterParms parms;
std::string messages;
bool ret;
osgDB::ReaderWriter::WriteResult result;
std::string ext = osgDB::getFileExtension(filename);
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
parms.outfile[0] = '\0';
strncat( parms.outfile, filename.c_str(), sizeof(parms.outfile)-1 );
// FIXME: Allow specification via Options
parms.set_default_color = 1;
parms.default_color[0] =
parms.default_color[1] =
parms.default_color[2] = 0.75;
parms.default_color[3] = 1.0; // opaque light gray
ret = dx::WriteDX( node, parms, messages );
if ( ret )
result = osgDB::ReaderWriter::WriteResult(
osgDB::ReaderWriter::WriteResult::FILE_SAVED );
else
result = osgDB::ReaderWriter::WriteResult( messages );
osg::notify( osg::DEBUG_INFO ) << messages;
return result;
}
// now register with Registry to instantiate the above
// reader/writer.
osgDB::RegisterReaderWriterProxy<ReaderWriterDX> g_dxReaderWriterProxy;

View File

@ -0,0 +1,47 @@
// This plugin writes an IBM Data Explorer (aka OpenDX) native file.
// (c) Randall Hopper, 2002.
//
// For details on the OpenDX visualization tool, its use, and its file format,
// refer to:
//
// http://www.opendx.org/
// http://www.opendx.org/support.html#docs
// http://www.research.ibm.com/dx/
// http://ftp.cs.umt.edu/DX/
//
// SUPPORTED : Refer to DXWriter.cpp
// UNSUPPORTED: Refer to DXWriter.cpp
//
// ReaderWriterDX.h
#ifndef __OSG_READER_WRITER_DX_H
#define __OSG_READER_WRITER_DX_H
#include <string>
#include <osg/Object>
#include <osg/Node>
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <osgDB/ReaderWriter>
class ReaderWriterDX : public osgDB::ReaderWriter
{
public:
virtual const char* className() { return "OpenDX Writer"; }
virtual bool acceptsExtension( const std::string &extension )
{ return osgDB::equalCaseInsensitive( extension, "dx" ); }
virtual WriteResult writeObject( const osg::Object &obj,
const std::string &filename,
const Options *options = NULL );
virtual WriteResult writeNode ( const osg::Node &node,
const std::string &filename,
const Options *options = NULL );
};
#endif // __READER_WRITER_DX_H

View File

@ -0,0 +1,162 @@
#include <map>
#include <string>
#include <string.h>
#include <osg/StateAttribute>
namespace dx {
typedef std::map<osg::StateAttribute::GLMode,std::string> ModeMap;
static ModeMap S_mode_map;
#define ADD_NAME(str,mode) (S_mode_map[(mode)] = (str));
// This is a copy of some of the code in src/osgPlugins/osg/StateSet.cpp.
// We need to translate GLModes and StateSet attributes into strings,
// and that's not available in an OSG public API (yet).
static void initGLNames()
{
static bool first_time = true;
if (!first_time) return;
ADD_NAME("GL_ALPHA_TEST",GL_ALPHA_TEST)
ADD_NAME("GL_BLEND",GL_BLEND)
ADD_NAME("GL_COLOR_MATERIAL",GL_COLOR_MATERIAL)
ADD_NAME("GL_CULL_FACE",GL_CULL_FACE)
ADD_NAME("GL_DEPTH_TEST",GL_DEPTH_TEST)
ADD_NAME("GL_FOG",GL_FOG)
ADD_NAME("GL_LIGHTING",GL_LIGHTING)
ADD_NAME("GL_POINT_SMOOTH",GL_POINT_SMOOTH)
ADD_NAME("GL_POLYGON_OFFSET_FILL",GL_POLYGON_OFFSET_FILL)
ADD_NAME("GL_POLYGON_OFFSET_LINE",GL_POLYGON_OFFSET_LINE)
ADD_NAME("GL_POLYGON_OFFSET_POINT",GL_POLYGON_OFFSET_POINT)
ADD_NAME("GL_TEXTURE_2D",GL_TEXTURE_2D)
ADD_NAME("GL_TEXTURE_GEN_Q",GL_TEXTURE_GEN_Q)
ADD_NAME("GL_TEXTURE_GEN_R",GL_TEXTURE_GEN_R)
ADD_NAME("GL_TEXTURE_GEN_S",GL_TEXTURE_GEN_S)
ADD_NAME("GL_TEXTURE_GEN_T",GL_TEXTURE_GEN_T)
ADD_NAME("GL_STENCIL_TEST",GL_STENCIL_TEST)
ADD_NAME("GL_CLIP_PLANE0",GL_CLIP_PLANE0);
ADD_NAME("GL_CLIP_PLANE1",GL_CLIP_PLANE1);
ADD_NAME("GL_CLIP_PLANE2",GL_CLIP_PLANE2);
ADD_NAME("GL_CLIP_PLANE3",GL_CLIP_PLANE3);
ADD_NAME("GL_CLIP_PLANE4",GL_CLIP_PLANE4);
ADD_NAME("GL_CLIP_PLANE5",GL_CLIP_PLANE5);
ADD_NAME("GL_LIGHT0",GL_LIGHT0);
ADD_NAME("GL_LIGHT1",GL_LIGHT1);
ADD_NAME("GL_LIGHT2",GL_LIGHT2);
ADD_NAME("GL_LIGHT3",GL_LIGHT3);
ADD_NAME("GL_LIGHT4",GL_LIGHT4);
ADD_NAME("GL_LIGHT5",GL_LIGHT5);
ADD_NAME("GL_LIGHT6",GL_LIGHT6);
ADD_NAME("GL_LIGHT7",GL_LIGHT7);
first_time = false;
}
const char *GLModeToModeStr( osg::StateAttribute::GLMode mode )
{
initGLNames();
ModeMap::const_iterator mitr = S_mode_map.find(mode);
if ( mitr != S_mode_map.end() )
return mitr->second.c_str();
else
return 0;
}
osg::StateAttribute::GLMode GLModeStrToMode( const char mode_str[] )
{
initGLNames();
for( ModeMap::const_iterator mitr = S_mode_map.begin();
mitr != S_mode_map.end();
++mitr )
if ( strcmp( mode_str, mitr->second.c_str() ) == 0 )
return mitr->first;
return (osg::StateAttribute::GLMode) -1;
}
//===========================================================================
typedef std::map<osg::StateAttribute::Type,std::string> AttrMap;
static AttrMap S_attr_map;
#define ADD_ATTR(attr,str) (S_attr_map[(attr)] = (str));
static void initOSGAttrNames()
{
static bool first_time = true;
if (!first_time) return;
ADD_ATTR( osg::StateAttribute::TEXTURE , "TEXTURE" );
ADD_ATTR( osg::StateAttribute::TEXTURE_0 , "TEXTURE_0" );
ADD_ATTR( osg::StateAttribute::TEXTURE_1 , "TEXTURE_1" );
ADD_ATTR( osg::StateAttribute::TEXTURE_2 , "TEXTURE_2" );
ADD_ATTR( osg::StateAttribute::TEXTURE_3 , "TEXTURE_3" );
ADD_ATTR( osg::StateAttribute::MATERIAL , "MATERIAL" );
ADD_ATTR( osg::StateAttribute::ALPHAFUNC , "ALPHAFUNC" );
ADD_ATTR( osg::StateAttribute::ANTIALIAS , "ANTIALIAS" );
ADD_ATTR( osg::StateAttribute::COLORTABLE , "COLORTABLE" );
ADD_ATTR( osg::StateAttribute::CULLFACE , "CULLFACE" );
ADD_ATTR( osg::StateAttribute::FOG , "FOG" );
ADD_ATTR( osg::StateAttribute::FRONTFACE , "FRONTFACE" );
ADD_ATTR( osg::StateAttribute::LIGHT , "LIGHT" );
ADD_ATTR( osg::StateAttribute::LIGHT_0 , "LIGHT_0" );
ADD_ATTR( osg::StateAttribute::LIGHT_1 , "LIGHT_1" );
ADD_ATTR( osg::StateAttribute::LIGHT_2 , "LIGHT_2" );
ADD_ATTR( osg::StateAttribute::LIGHT_3 , "LIGHT_3" );
ADD_ATTR( osg::StateAttribute::LIGHT_4 , "LIGHT_4" );
ADD_ATTR( osg::StateAttribute::LIGHT_5 , "LIGHT_5" );
ADD_ATTR( osg::StateAttribute::LIGHT_6 , "LIGHT_6" );
ADD_ATTR( osg::StateAttribute::LIGHT_7 , "LIGHT_7" );
ADD_ATTR( osg::StateAttribute::POINT , "POINT" );
ADD_ATTR( osg::StateAttribute::LINEWIDTH , "LINEWIDTH" );
ADD_ATTR( osg::StateAttribute::POLYGONMODE , "POLYGONMODE" );
ADD_ATTR( osg::StateAttribute::POLYGONOFFSET , "POLYGONOFFSET");
ADD_ATTR( osg::StateAttribute::TEXENV , "TEXENV" );
ADD_ATTR( osg::StateAttribute::TEXGEN , "TEXGEN" );
ADD_ATTR( osg::StateAttribute::TEXMAT , "TEXMAT" );
ADD_ATTR( osg::StateAttribute::TRANSPARENCY , "TRANSPARENCY" );
ADD_ATTR( osg::StateAttribute::STENCIL , "STENCIL" );
ADD_ATTR( osg::StateAttribute::COLORMASK , "COLORMASK" );
ADD_ATTR( osg::StateAttribute::DEPTH , "DEPTH" );
ADD_ATTR( osg::StateAttribute::VIEWPORT , "VIEWPORT" );
ADD_ATTR( osg::StateAttribute::CLIPPLANE , "CLIPPLANE" );
ADD_ATTR( osg::StateAttribute::CLIPPLANE_0 , "CLIPPLANE_0" );
ADD_ATTR( osg::StateAttribute::CLIPPLANE_1 , "CLIPPLANE_1" );
ADD_ATTR( osg::StateAttribute::CLIPPLANE_2 , "CLIPPLANE_2" );
ADD_ATTR( osg::StateAttribute::CLIPPLANE_3 , "CLIPPLANE_3" );
ADD_ATTR( osg::StateAttribute::CLIPPLANE_4 , "CLIPPLANE_4" );
ADD_ATTR( osg::StateAttribute::CLIPPLANE_5 , "CLIPPLANE_5" );
ADD_ATTR( osg::StateAttribute::COLORMATRIX , "COLORMATRIX" );
first_time = false;
}
const char *OSGAttrToAttrStr( osg::StateAttribute::Type attr )
{
initOSGAttrNames();
AttrMap::const_iterator aitr = S_attr_map.find(attr);
if ( aitr != S_attr_map.end() )
return aitr->second.c_str();
else
return 0;
}
osg::StateAttribute::Type OSGAttrStrToAttr( const char attr_str[] )
{
initGLNames();
for( AttrMap::const_iterator aitr = S_attr_map.begin();
aitr != S_attr_map.end();
++aitr )
if ( strcmp( attr_str, aitr->second.c_str() ) == 0 )
return aitr->first;
return (osg::StateAttribute::Type) -1;
}
}; // namespace dx

View File

@ -0,0 +1,18 @@
#ifndef __OSG_STATESETSTR_H
#define __OSG_STATESETSTR_H
#include <osg/StateAttribute>
namespace dx {
const char *GLModeToModeStr( osg::StateAttribute::GLMode mode );
osg::StateAttribute::GLMode GLModeStrToMode( const char mode_str[] );
const char *OSGAttrToAttrStr( osg::StateAttribute::Type attr );
osg::StateAttribute::Type OSGAttrStrToAttr( const char attr_str[] );
};
#endif

View File

@ -85,6 +85,9 @@ class OSGReaderWriter : public ReaderWriter
virtual WriteResult writeNode(const Node& node,const std::string& fileName, const osgDB::ReaderWriter::Options*) virtual WriteResult writeNode(const Node& node,const std::string& fileName, const osgDB::ReaderWriter::Options*)
{ {
std::string ext = getFileExtension(fileName);
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
Output fout; Output fout;
fout.open(fileName.c_str()); fout.open(fileName.c_str());
if (fout) if (fout)