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>
- port to FreeBSD.
- warning fixes to IRIX compilation.
- Open DX writer.
Ulrich Hertlein <u.hertlein@bit-side.com>
- support for IBM Mirror Repeat extension in osg::Texture

4
NEWS
View File

@ -1,7 +1,7 @@
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.
@ -28,6 +28,8 @@ OSG News (most significant items from ChangeLog)
The Open Flight .flt loader has undergone a number of improvements
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
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

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>
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.
static unsigned int _s_accumulatedButtonMask;
// used to store current button value
static int _s_button;
// used to store window min and max values.
static int _s_Xmin;
static int _s_Xmax;

View File

@ -6,6 +6,7 @@ using namespace osgGLUT;
// default to no mouse buttons being pressed.
unsigned int GLUTEventAdapter::_s_accumulatedButtonMask = 0;
int GLUTEventAdapter::_s_button = 0;
int GLUTEventAdapter::_s_Xmin = 0;
int GLUTEventAdapter::_s_Xmax = 1280;
int GLUTEventAdapter::_s_Ymin = 0;
@ -31,6 +32,7 @@ GLUTEventAdapter::GLUTEventAdapter()
void GLUTEventAdapter::copyStaticVariables()
{
_buttonMask = _s_accumulatedButtonMask;
_button = _s_button;
_Xmin = _s_Xmin;
_Xmax = _s_Xmax;
_Ymin = _s_Ymin;
@ -99,9 +101,21 @@ void GLUTEventAdapter::adaptMouse(float time, int button, int state, int x, int
switch(button)
{
case(GLUT_LEFT_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask | LEFT_MOUSE_BUTTON; break;
case(GLUT_MIDDLE_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask | MIDDLE_MOUSE_BUTTON; break;
case(GLUT_RIGHT_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask | RIGHT_MOUSE_BUTTON; break;
case(GLUT_LEFT_BUTTON):
_s_accumulatedButtonMask =
_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)
{
case(GLUT_LEFT_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask & ~LEFT_MOUSE_BUTTON; break;
case(GLUT_MIDDLE_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask & ~MIDDLE_MOUSE_BUTTON; break;
case(GLUT_RIGHT_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask & ~RIGHT_MOUSE_BUTTON; break;
case(GLUT_LEFT_BUTTON):
_s_accumulatedButtonMask =
_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.
# 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.
# if in this case then its likely you'll want to comment out the below
# 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*)
{
std::string ext = getFileExtension(fileName);
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
Output fout;
fout.open(fileName.c_str());
if (fout)