Files
OpenSceneGraph/src/osgPlugins/flt/ReaderWriterATTR.cpp
2004-10-26 10:26:43 +00:00

793 lines
29 KiB
C++

//
// OpenFlight® texture attribute loader for Open Scene Graph
//
// Copyright (C) 2001 Brede Johansen
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
// The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for
// real-time rendering of large 3D photo-realistic models.
// The OSG homepage is http://www.openscenegraph.org/
//
// MultiGen, OpenFlight, and Flight Format are registered trademarks of MultiGen Inc.
//
#include <stdio.h>
#include <string.h>
#include <osg/Notify>
#include <osg/TexEnv>
#include <osg/Texture2D>
#include <osg/StateSet>
#include <osg/GL>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/Registry>
#include <iostream>
#include <fstream>
#include "AttrData.h"
typedef signed char int8;
typedef unsigned char uint8;
typedef signed short int16;
typedef unsigned short uint16;
typedef signed int int32;
typedef unsigned int uint32;
typedef float float32;
typedef double float64;
#define READ(DST) readField(file, (void*)&(DST), sizeof(DST))
static int isLittleEndianMachine()
{
int a = 1;
return (int)(*(char*)&a);
}
static void endian2(void* pSrc, int nSrc, void* pDst)
{
if (nSrc == 2)
{
short tmp1;
tmp1 = *(short *)pSrc;
tmp1 = (tmp1 << 8) | ((tmp1 >> 8) & 0xff);
*(short *)pDst = tmp1;
}
else if (nSrc == 4)
{
uint32 tmp1;
tmp1 = *(uint32 *)pSrc;
tmp1 = (tmp1 << 24) | ((tmp1 << 8) & 0xff0000) | ((tmp1 >> 8) & 0xff00) | ((tmp1 >> 24) & 0xff);
*(uint32 *)pDst = tmp1;
}
else if (nSrc == 8)
{
uint32 tmp1, tmp2;
tmp1 = *(uint32 *)pSrc;
tmp2 = *(1 + (uint32 *)pSrc);
tmp1 = (tmp1 << 24) | ((tmp1 << 8) & 0xff0000) | ((tmp1 >> 8) & 0xff00) | ((tmp1 >> 24) & 0xff);
tmp2 = (tmp2 << 24) | ((tmp2 << 8) & 0xff0000) | ((tmp2 >> 8) & 0xff00) | ((tmp2 >> 24) & 0xff);
*(uint32 *)pDst = tmp2;
*(1 + (uint32 *)pDst) = tmp1;
}
}
using namespace osg;
class Attr
{
public :
enum MinFilterMode {
MIN_FILTER_POINT = 0,
MIN_FILTER_BILINEAR = 1,
MIN_FILTER_MIPMAP = 2, // (Obsolete)
MIN_FILTER_MIPMAP_POINT = 3,
MIN_FILTER_MIPMAP_LINEAR = 4,
MIN_FILTER_MIPMAP_BILINEAR = 5,
MIN_FILTER_MIPMAP_TRILINEAR = 6,
MIN_FILTER_NONE = 7,
MIN_FILTER_BICUBIC = 8,
MIN_FILTER_BILINEAR_GEQUAL = 9,
MIN_FILTER_BILINEAR_LEQUAL = 10,
MIN_FILTER_BICUBIC_GEQUAL = 11,
MIN_FILTER_BICUBIC_LEQUAL = 12
};
enum MagFilterMode {
MAG_FILTER_POINT = 0,
MAG_FILTER_BILINEAR = 1,
MAG_FILTER_NONE = 2,
MAG_FILTER_BICUBIC = 3,
MAG_FILTER_SHARPEN = 4,
MAG_FILTER_ADD_DETAIL = 5,
MAG_FILTER_MODULATE_DETAIL = 6,
MAG_FILTER_BILINEAR_GEQUAL = 7,
MAG_FILTER_BILINEAR_LEQUAL = 8,
MAG_FILTER_BICUBIC_GEQUAL = 9,
MAG_FILTER_BICUBIC_LEQUAL = 10
};
enum WrapMode {
WRAP_REPEAT = 0,
WRAP_CLAMP = 1
};
enum TexEnvMode {
TEXENV_MODULATE = 0,
TEXENV_BLEND = 1,
TEXENV_DECAL = 2,
TEXENV_COLOR = 3
};
enum Projection {
PROJECTION_FLAT = 0,
PROJECTION_LAMBERT_CONIC = 3,
PROJECTION_UTM = 4,
PROJECTION_UNDEFINED = 7
};
enum Datum {
DATUM_WGS84 = 0,
DATUM_WGS72 = 1,
DATUM_BESSEL = 2,
DATUM_CLARK_1866 = 3,
DATUM_NAD27 = 4
};
Attr(int version) : _flt_version(version) { init(); }
void init();
void readField(std::ifstream& file, void* buf, size_t size);
bool readAttrFile(const char* szName);
flt::AttrData* createOsgStateSet();
int32 texels_u; // Number of texels in u direction
int32 textel_v; // Number of texels in v direction
int32 direction_u; // Real world size u direction
int32 direction_v; // Real world size v direction
int32 x_up; // x component of up vector
int32 y_up; // y component of up vector
int32 fileFormat; // File format type
// -1 Not used
// 0 AT&T image 8 pattern
// 1 AT&T image 8 template
// 2 SGI intensity modulation
// 3 SGI intensity w/ alpha
// 4 SGI RGB
// 5 SGI RGB w/ alpha
int32 minFilterMode; // Minification filter type
// 0 - TX_POINT
// 1 - TX_BILINEAR
// 2 - TX_MIPMAP (Obsolete)
// 3 - TX_MIPMAP_POINT
// 4 - TX_MIPMAP_LINEAR
// 5 - TX_MIPMAP_BILINEAR
// 6 - TX_MIPMAP_TRILINEAR
// 7 - None
// 8 - TX_BICUBIC
// 9 - TX_BILINEAR_GEQUAL
// 10 - TX_BILINEAR_LEQUAL
// 11 - TX_BICUBIC_GEQUAL
// 12 - TX_BICUBIC_LEQUAL
int32 magFilterMode; // Magnification filter type
// 0 - TX_POINT
// 1 - TX_BILINEAR
// 2 - None
// 3 - TX_BICUBIC
// 4 - TX_SHARPEN
// 5 - TX_ADD_DETAIL
// 6 - TX_MODULATE_DETAIL
// 7 - TX_BILINEAR_GEQUAL
// 8 - TX_BILINEAR_LEQUAL
// 9 - TX_BICUBIC_GEQUAL
// 10 - TX_BICUBIC_LEQUAL
int32 wrapMode; // Repetition type
// 0 - TX_REPEAT
// 1 - TX_CLAMP
// 2 - (Obsolete)
int32 wrapMode_u; // Repetition type in u direction (see above)
int32 wrapMode_v; // Repetition type in v direction (see above)
int32 modifyFlag; // Modify flag (for internal use)
int32 pivot_x; // x pivot point for rotating textures
int32 pivot_y; // y pivot point for rotating textures
// --------------
// v11 ends here
// --------------
int32 texEnvMode; // Environment type
// 0 - TV_MODULATE
// 1 - TV_BLEND
// 2 - TV_DECAL
// 3 - TV_COLOR
int32 intensityAsAlpha; // TRUE if intensity pattern to be loaded in alpha with white in color
int32 spare1[8]; // 8 words of spare
float64 size_u; // Real world size u for floating point databases
float64 size_v; // Real world size v for floating point databases
int32 originCode; // Code for origin of imported texture
int32 kernelVersion; // Kernel version number
int32 intFormat; // Internal format type
// 0 - Default
// 1 - TX_I_12A_4
// 2 - TX_IA_8
// 3 - TX_RGB_5
// 4 - TX_RGBA_4
// 5 - TX_IA_12
// 6 - TX_RGBA_8
// 7 - TX_RGBA_12
// 8 - TX_I_16 (shadow mode only)
// 9 - TX_RGB_12
int32 extFormat; // External format type
// 0 - Default
// 1 - TX_PACK_8
// 2 - TX_PACK_16
int32 useMips; // TRUE if using following 8 floats for MIPMAP kernel
float32 _mipMapKernel[8]; // 8 floats for kernel of separable symmetric filter
int32 useLodScale; // Boolean if TRUE send:
float32 lod0; // LOD0 for TX_CONTROL_POINT
float32 scale0; // SCALE0 for TX_CONTROL_POINT
float32 lod1; // LOD1 for TX_CONTROL_POINT
float32 scale1; // SCALE1 for TX_CONTROL_POINT
float32 lod2; // LOD2 for TX_CONTROL_POINT
float32 scale2; // SCALE2 for TX_CONTROL_POINT
float32 lod3; // LOD3 for TX_CONTROL_POINT
float32 scale3; // SCALE3 for TX_CONTROL_POINT
float32 lod4; // LOD4 for TX_CONTROL_POINT
float32 scale4; // SCALE4 for TX_CONTROL_POINT
float32 lod5; // LOD5 for TX_CONTROL_POINT
float32 scale5; // SCALE5 for TX_CONTROL_POINT
float32 lod6; // LOD6 for TX_CONTROL_POINT
float32 scale6; // SCALE6 for TX_CONTROL_POINT
float32 lod7; // LOD7 for TX_CONTROL_POINT
float32 scale7; // SCALE7 for TX_CONTROL_POINT
float32 clamp; // Clamp
int32 magFilterAlpha; // magfilteralpha:
// 0 = TX_POINT
// 1 = TX_BILINEAR
// 2 = None
// 3 = TX_BICUBIC
// 4 = TX_SHARPEN
// 5 = TX_ADD_DETAIL
// 6 = TX_MODULATE_DETAIL
// 7 = TX_BILINEAR_GEQUAL
// 8 = TX_BILINEAR_LEQUAL
// 9 = TX_BICUBIC_GEQUAL
// 10 = TX_BIBICUBIC_LEQUAL
int32 magFilterColor; // magfiltercolor:
// 0 = TX_POINT
// 1 = TX_BILINEAR
// 2 = None
// 3 = TX_BICUBIC
// 4 = TX_SHARPEN
// 5 = TX_ADD_DETAIL
// 6 = TX_MODULATE_DETAIL
// 7 = TX_BILINEAR_GEQUAL
// 8 = TX_BILINEAR_LEQUAL
// 9 = TX_BICUBIC_GEQUAL
// 10 = TX_BIBICUBIC_LEQUAL
float32 reserved1; // Reserved
float32 reserved2[8]; // Reserved
float64 lambertMeridian; // Lambert conic projection central meridian
float64 lambertUpperLat; // Lambert conic projection upper latitude
float64 lambertlowerLat; // Lambert conic projection lower latitude
float64 reserved3; // Reserved
float32 spare2[5]; // Spare
int32 useDetail; // TRUE if using next 5 integers for detail texture
int32 txDetail_j; // J argument for TX_DETAIL
int32 txDetail_k; // K argument for TX_DETAIL
int32 txDetail_m; // M argument for TX_DETAIL
int32 txDetail_n; // N argument for TX_DETAIL
int32 txDetail_s; // Scramble argument for TX_DETAIL
int32 useTile; // TRUE if using next for floats for TX_TILE
float32 txTile_ll_u; // Lower-left u value for TX_TILE
float32 txTile_ll_v; // Lower-left v value for TX_TILE
float32 txTile_ur_u; // Upper-right u value for TX_TILE
float32 txTile_ur_v; // Upper-right v value for TX_TILE
int32 projection; // Projection
// 0 = Flat earth
// 3 = Lambert conic
// 4 = UTM
// 7 = Undefined projection
int32 earthModel; // Earth model
// 0 = WGS84
// 1 = WGS72
// 2 = Bessel
// 3 = Clark 1866
// 4 = NAD27
int32 reserved4; // Reserved
int32 utmZone; // UTM zone
int32 imageOrigin; // Image origin
// 0 = Lower-left
// 1 = Upper-left
int32 geoUnits; // Geospecific points units
// 0 = Degrees
// 1 = Meters
// 2 = Pixels
int32 reserved5; // Reserved
int32 reserved6; // Reserved
int32 hemisphere; // Hemisphere for geospecific points units
// 0 = Southern
// 1 = Northern
int32 reserved7; // Reserved
int32 reserved8; // Reserved
int32 spare3[149]; // Spare
char comments[512]; // Comments
// --------------
// v12 ends here
// --------------
int32 reserved9[13]; // Reserved
int32 attrVersion; // Attribute file version number
int32 controlPoints; // Number of geospecific control points
// If the number of geospecific control points is > 0,
// the following fields are also in the attribute file:
int32 reserved10; // Reserved
#if 0
// For each geospecific control point:
{
float64 texel_u; // Texel u of geospecific control point
float64 texel_v; // Texel v of geospecific control point
float64 geoPoint[2]; // Real earth coordinate of geospecific control point
// (this value depends on the projection, earth model,
// and geospecific points units)
}
// ----------------
// v15.6 ends here
// ----------------
// After all geospecific control points are listed, the following subtexture
// information appears:
int32 subtextures; // Number of subtexture definitions contained in the
// texture attribute file
// If the number of subtexture definitions is >0,
// the following fields are repeated for each subtexture definition:
{
char name[32]; // name of subtexture definition
int32 left; // Coordinate of left edge of subtexture
// definition measured in texels.
int32 bottom; // Coordinate of bottom edge of subtexture
// definition measured in texels.
int32 right; // Coordinate of right edge of subtexture
// definition measured in texels.
int32 top; // Coordinate of top edge of subtexture
// definition measured in texels.
}
#endif
void read();
private :
int _flt_version;
};
void Attr::init()
{
texels_u = 0;
textel_v = 0;
direction_u = 0;
direction_v = 0;
x_up = 0;
y_up = 0;
fileFormat = -1; // -1 Not used
minFilterMode = MIN_FILTER_NONE;
magFilterMode = MAG_FILTER_POINT;
wrapMode = WRAP_REPEAT;
wrapMode_u = WRAP_REPEAT;
wrapMode_v = WRAP_REPEAT;
modifyFlag = 0;
pivot_x = 0;
pivot_y = 0;
texEnvMode = TEXENV_MODULATE;
intensityAsAlpha = 0;
size_u = 0;
size_v = 0;
originCode = 0;
kernelVersion = 0;
intFormat = 0; // 0 - Default
extFormat = 0; // 0 - Default
useMips = 0;
// float32 _mipMapKernel[8];
useLodScale = 0;
// float32 lod0;
// float32 scale0;
// ...
// float32 lod7;
// float32 scale7;
clamp = 0;
magFilterAlpha = 2; // 2 = None
magFilterColor = 2; // 2 = None
lambertMeridian = 0;
lambertUpperLat = 0;
lambertlowerLat = 0;
useDetail = 0;
txDetail_j = 0;
txDetail_k = 0;
txDetail_m = 0;
txDetail_n = 0;
txDetail_s = 0;
useTile = 0;
txTile_ll_u = 0;
txTile_ll_v = 0;
txTile_ur_u = 0;
txTile_ur_v = 0;
projection = PROJECTION_UNDEFINED;
earthModel = DATUM_WGS84;
utmZone = 0;
imageOrigin = 0;
geoUnits = 0;
hemisphere = 1;
comments[0] = '\0';
attrVersion = 0;
controlPoints = 0;
// TODO:
}
void Attr::readField(std::ifstream& file, void* buf, size_t size)
{
if (file.eof()) return;
file.read((char*)buf, size);
if(::isLittleEndianMachine())
::endian2(buf, size, buf);
}
bool Attr::readAttrFile(const char* szName)
{
int n;
std::ifstream file;
file.open (szName, std::ios::in | std::ios::binary);
READ( texels_u );
READ( textel_v );
READ( direction_u );
READ( direction_v );
READ( x_up );
READ( y_up );
READ( fileFormat );
READ( minFilterMode );
READ( magFilterMode );
READ( wrapMode );
READ( wrapMode_u );
READ( wrapMode_v );
READ( modifyFlag );
READ( pivot_x );
READ( pivot_y );
// v11 ends here
if (_flt_version <= 11) return true;
READ( texEnvMode );
READ( intensityAsAlpha );
for (n=0; n<8; n++) {
READ(spare1[n]); }
READ( size_u );
READ( size_v );
READ( originCode );
READ( kernelVersion );
READ( intFormat );
READ( extFormat );
READ( useMips );
for (n=0; n<8; n++) {
READ(_mipMapKernel[n]); }
READ( useLodScale );
READ( lod0 );
READ( scale0 );
READ( lod1 );
READ( scale1 );
READ( lod2 );
READ( scale2 );
READ( lod3 );
READ( scale3 );
READ( lod4 );
READ( scale4 );
READ( lod5 );
READ( scale5 );
READ( lod6 );
READ( scale6 );
READ( lod7 );
READ( scale7 );
READ( clamp );
READ( magFilterAlpha );
READ( magFilterColor );
READ( reserved1 );
for (n=0; n<8; n++) {
READ(reserved2[n]); }
READ( lambertMeridian );
READ( lambertUpperLat );
READ( lambertlowerLat );
READ( reserved3 );
for (n=0; n<5; n++) {
READ(spare2[n]); }
// I don't know why I get a 4 bytes displacement before reading Detail Texture parameters
// My ATTR files have been created with Creator 2.5.1
// Julian Ortiz, June 18th 2003.
int32 dummyAjust;
READ( dummyAjust);
READ( useDetail );
READ( txDetail_j );
READ( txDetail_k );
READ( txDetail_m );
READ( txDetail_n );
READ( txDetail_s );
READ( useTile );
READ( txTile_ll_u );
READ( txTile_ll_v );
READ( txTile_ur_u );
READ( txTile_ur_v );
READ( projection );
READ( earthModel );
READ( reserved4 );
READ( utmZone );
READ( imageOrigin);
READ( geoUnits );
READ( reserved5 );
READ( reserved6 );
READ( hemisphere );
READ( reserved7 );
READ( reserved8 );
for (n=0; n<149; n++) {
READ(spare3[n]); }
file.read(comments, sizeof(comments));
// v12 ends here
if (_flt_version <= 12) return true;
for (n=0; n<13; n++) {
READ(reserved9[n]); }
READ( attrVersion );
READ( controlPoints);
READ( reserved10 );
file.close();
return true;
}
flt::AttrData* Attr::createOsgStateSet()
{
TexEnv* osgTexEnv = new TexEnv;
Texture2D* osgTexture = new Texture2D;
flt::AttrData* attrdata = new flt::AttrData;
if ((wrapMode_u != WRAP_CLAMP) && ((wrapMode_u != WRAP_REPEAT)))
wrapMode_u = wrapMode;
if ((wrapMode_v != WRAP_CLAMP) && ((wrapMode_v != WRAP_REPEAT)))
wrapMode_v = wrapMode;
if (wrapMode_u == WRAP_CLAMP) osgTexture->setWrap(Texture2D::WRAP_S,Texture2D::CLAMP);
else osgTexture->setWrap(Texture2D::WRAP_S,Texture2D::REPEAT);
if (wrapMode_v == WRAP_CLAMP) osgTexture->setWrap(Texture2D::WRAP_T,Texture2D::CLAMP);
else osgTexture->setWrap(Texture2D::WRAP_T,Texture2D::REPEAT);
switch (texEnvMode)
{
case TEXENV_MODULATE:
osgTexEnv->setMode(TexEnv::MODULATE);
break;
case TEXENV_BLEND:
osgTexEnv->setMode(TexEnv::BLEND);
break;
case TEXENV_DECAL:
osgTexEnv->setMode(TexEnv::DECAL);
break;
case TEXENV_COLOR:
osgTexEnv->setMode(TexEnv::REPLACE);
break;
}
/* An email on ATTR mappings to OpenGL : "[osg-news] OpenFlight Texture Filter Modes"
from Joseph Steel:
I posted a query on a forum on the Multigen web site re. the OpenFlight
texture filer modes. This is the reply:
Here are the mappings used by Creator under OpenGL:
For Minification:
Point (0): GL_NEAREST
Bilinear (1): GL_LINEAR
Mipmap Point (3): GL_NEAREST_MIPMAP_NEAREST
Mipmap Linear (4): GL_NEAREST_MIPMAP_LINEAR
Mipmap Bilinear (5): GL_LINEAR_MIPMAP_NEAREST
Mipmap Trilinear (6): GL_LINEAR_MIPMAP_LINEAR
Bicubic (8): GL_LINEAR_MIPMAP_NEAREST
Bilinear Greater/Equal (9): GL_LINEAR_MIPMAP_NEAREST
Bilinear Less/Equal (10): GL_LINEAR_MIPMAP_NEAREST
Bicubic Greater/Equal (11): GL_LINEAR_MIPMAP_NEAREST
Bicubic Less/Equal (12): GL_LINEAR_MIPMAP_NEAREST
For Magnification:
Point (0): GL_NEAREST
Bilinear (1): GL_LINEAR
Bicubic (3): GL_LINEAR
Sharpen (4): GL_LINEAR
Add Detail (5): GL_LINEAR
Modulate Detail (6): GL_LINEAR
Bilinear Greater/Equal (7): GL_LINEAR
Bilinear Less/Equal (8): GL_LINEAR
Bicubic Greater/Equal (9): GL_LINEAR
Bicubic Less/Equal (10): GL_LINEAR
Note that mode 2 for both minification & magnification are no longer
supported.
*/
// -----------
// Min filter
// -----------
switch (minFilterMode)
{
case MIN_FILTER_POINT:
osgTexture->setFilter(osg::Texture2D::MIN_FILTER, Texture2D::NEAREST);
break;
case MIN_FILTER_BILINEAR:
osgTexture->setFilter(osg::Texture2D::MIN_FILTER, Texture2D::LINEAR);
break;
case MIN_FILTER_MIPMAP_POINT:
osgTexture->setFilter(osg::Texture2D::MIN_FILTER, Texture2D::NEAREST_MIPMAP_NEAREST);
break;
case MIN_FILTER_MIPMAP_LINEAR:
osgTexture->setFilter(osg::Texture2D::MIN_FILTER, Texture2D::NEAREST_MIPMAP_LINEAR);
break;
case MIN_FILTER_MIPMAP_BILINEAR:
osgTexture->setFilter(osg::Texture2D::MIN_FILTER, Texture2D::LINEAR_MIPMAP_NEAREST);
break;
case MIN_FILTER_MIPMAP_TRILINEAR:
osgTexture->setFilter(osg::Texture2D::MIN_FILTER, Texture2D::LINEAR_MIPMAP_LINEAR);
break;
case MIN_FILTER_BICUBIC:
case MIN_FILTER_BILINEAR_GEQUAL:
case MIN_FILTER_BILINEAR_LEQUAL:
case MIN_FILTER_BICUBIC_GEQUAL:
case MIN_FILTER_BICUBIC_LEQUAL:
osgTexture->setFilter(osg::Texture2D::MIN_FILTER, Texture2D::LINEAR_MIPMAP_NEAREST);
break;
default:
osgTexture->setFilter(osg::Texture2D::MIN_FILTER, Texture2D::LINEAR_MIPMAP_LINEAR);
break;
break;
}
// -----------
// Mag filter
// -----------
switch (magFilterMode)
{
case MAG_FILTER_POINT:
osgTexture->setFilter(osg::Texture2D::MAG_FILTER, Texture2D::NEAREST);
break;
case MAG_FILTER_BILINEAR:
case MAG_FILTER_BILINEAR_GEQUAL:
case MAG_FILTER_BILINEAR_LEQUAL:
case MAG_FILTER_SHARPEN:
case MAG_FILTER_BICUBIC:
case MAG_FILTER_BICUBIC_GEQUAL:
case MAG_FILTER_BICUBIC_LEQUAL:
case MAG_FILTER_ADD_DETAIL:
case MAG_FILTER_MODULATE_DETAIL:
osgTexture->setFilter(osg::Texture2D::MAG_FILTER, Texture2D::LINEAR);
break;
}
// I have just ported the two below set*Attribute lines to use the new
// texture attribute methods, however this tieing to the texture unit 0
// is probably inappropriate. Perhaps it would be better to create a
// StateSet to store the texture an modes, it is probably best
// to use an intermediate data structure for the flt loader to use to
// encapsulate ATTR files. Need to speak to Brede about this issue.
// Robert Osfield, July 9th 2002.
// This is now a bit diferrent. We create a new AttrData object, and StateSet object
// is instead with attribute information needed to setup detail texutre
//
// Julian Ortiz, June 18th 2003.
attrdata->stateset = new StateSet;
attrdata->stateset->setTextureAttribute( 0, osgTexEnv );
attrdata->stateset->setTextureAttributeAndModes( 0, osgTexture, StateAttribute::ON );
attrdata->useDetail = useDetail;
attrdata->txDetail_j = txDetail_j;
attrdata->txDetail_k = txDetail_k;
attrdata->txDetail_m = txDetail_m;
attrdata->txDetail_n = txDetail_n;
attrdata->txDetail_s = txDetail_s;
if (magFilterMode == MAG_FILTER_MODULATE_DETAIL)
attrdata->modulateDetail = true;
else
attrdata->modulateDetail = false;
return attrdata;
}
class ReaderWriterATTR : public osgDB::ReaderWriter
{
public:
virtual const char* className() const { return "ATTR Image Attribute Reader/Writer"; }
virtual bool acceptsExtension(const std::string& extension)
{
return osgDB::equalCaseInsensitive(extension,"attr");
}
virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options*)
{
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
std::string fileName = osgDB::findDataFile( file );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
// options
char buf[256];
int version=0;
const osgDB::ReaderWriter::Options* rwOptions=
osgDB::Registry::instance()->getOptions();
if (rwOptions)
{
sscanf(rwOptions->getOptionString().c_str(),"%s %d", buf, &version);
if (strcmp(buf, "FLT_VER")) version=0;
}
Attr attr(version);
if (!attr.readAttrFile(fileName.c_str()))
{
return "Unable to open \""+fileName+"\"";
}
//StateSet* stateset = attr.createOsgStateSet();
// Julian Ortiz, June 18th 2003.
flt::AttrData* attrdata = attr.createOsgStateSet();
notify(INFO) << "texture attribute read ok" << std::endl;
return attrdata;
}
};
// now register with Registry to instantiate the above
// reader/writer.
osgDB::RegisterReaderWriterProxy<ReaderWriterATTR> g_readerWriter_ATTR_Proxy;