1 #include <osg/Texture>
2 #include <osgDB/ObjectWrapper>
3 #include <osgDB/InputStream>
4 #include <osgDB/OutputStream>
5 
6 #define WRAP_FUNCTIONS( PROP, VALUE ) \
7     static bool check##PROP( const osg::Texture& tex ) { return true; } \
8     static bool read##PROP( osgDB::InputStream& is, osg::Texture& tex ) { \
9         DEF_GLENUM(mode); is >> mode; \
10         tex.setWrap( VALUE, (osg::Texture::WrapMode)mode.get() ); \
11         return true; \
12     } \
13     static bool write##PROP( osgDB::OutputStream& os, const osg::Texture& tex ) { \
14         os << GLENUM(tex.getWrap(VALUE)) << std::endl; \
15         return true; \
16     }
17 
WRAP_FUNCTIONS(WRAP_S,osg::Texture::WRAP_S)18 WRAP_FUNCTIONS( WRAP_S, osg::Texture::WRAP_S )
19 WRAP_FUNCTIONS( WRAP_T, osg::Texture::WRAP_T )
20 WRAP_FUNCTIONS( WRAP_R, osg::Texture::WRAP_R )
21 
22 #define FILTER_FUNCTIONS( PROP, VALUE ) \
23     static bool check##PROP( const osg::Texture& tex ) { return true; } \
24     static bool read##PROP( osgDB::InputStream& is, osg::Texture& tex ) { \
25         DEF_GLENUM(mode); is >> mode; \
26         tex.setFilter( VALUE, (osg::Texture::FilterMode)mode.get() ); \
27         return true; \
28     } \
29     static bool write##PROP( osgDB::OutputStream& os, const osg::Texture& tex ) { \
30         os << GLENUM(tex.getFilter(VALUE)) << std::endl; \
31         return true; \
32     }
33 
34 FILTER_FUNCTIONS( MIN_FILTER, osg::Texture::MIN_FILTER )
35 FILTER_FUNCTIONS( MAG_FILTER, osg::Texture::MAG_FILTER )
36 
37 #define GL_FORMAT_FUNCTIONS( PROP ) \
38     static bool check##PROP( const osg::Texture& tex ) { \
39         return tex.get##PROP()!=GL_NONE; \
40     } \
41     static bool read##PROP( osgDB::InputStream& is, osg::Texture& tex ) { \
42         DEF_GLENUM(mode); is >> mode; tex.set##PROP( mode.get() ); \
43         return true; \
44     } \
45     static bool write##PROP( osgDB::OutputStream& os, const osg::Texture& tex ) { \
46         os << GLENUM(tex.get##PROP()) << std::endl; \
47         return true; \
48     }
49 
50 GL_FORMAT_FUNCTIONS( SourceFormat )
51 GL_FORMAT_FUNCTIONS( SourceType )
52 
53 static bool checkInternalFormat( const osg::Texture& tex )
54 { return tex.getInternalFormatMode()==osg::Texture::USE_USER_DEFINED_FORMAT; }
55 
readInternalFormat(osgDB::InputStream & is,osg::Texture & tex)56 static bool readInternalFormat( osgDB::InputStream& is, osg::Texture& tex )
57 {
58     DEF_GLENUM(mode); is >> mode;
59     if ( tex.getInternalFormatMode()==osg::Texture::USE_USER_DEFINED_FORMAT )
60         tex.setInternalFormat( mode.get() );
61     return true;
62 }
63 
writeInternalFormat(osgDB::OutputStream & os,const osg::Texture & tex)64 static bool writeInternalFormat( osgDB::OutputStream& os, const osg::Texture& tex )
65 {
66     if ( os.isBinary() && tex.getInternalFormatMode()!=osg::Texture::USE_USER_DEFINED_FORMAT )
67         os << GLENUM(GL_NONE) << std::endl;  // Avoid use of OpenGL extensions
68     else
69         os << GLENUM(tex.getInternalFormat()) << std::endl;
70     return true;
71 }
72 
73 // _imageAttachment
checkImageAttachment(const osg::Texture & attr)74 static bool checkImageAttachment( const osg::Texture& attr )
75 {
76     return attr.getImageAttachment().access!=0;
77 }
78 
readImageAttachment(osgDB::InputStream & is,osg::Texture & attr)79 static bool readImageAttachment( osgDB::InputStream& is, osg::Texture& attr )
80 {
81     osg::Texture::ImageAttachment attachment;
82     is >> attachment.unit >> attachment.level >> attachment.layered
83        >> attachment.layer >> attachment.access >> attachment.format;
84     attr.bindToImageUnit( attachment.unit, attachment.access, attachment.format,
85                           attachment.level, attachment.layered!=GL_FALSE, attachment.layer );
86     return true;
87 }
88 
writeImageAttachment(osgDB::OutputStream & os,const osg::Texture & attr)89 static bool writeImageAttachment( osgDB::OutputStream& os, const osg::Texture& attr )
90 {
91     const osg::Texture::ImageAttachment& attachment = attr.getImageAttachment();
92     os << attachment.unit << attachment.level << attachment.layered
93        << attachment.layer << attachment.access << attachment.format << std::endl;
94     return true;
95 }
96 
97 // _swizzle
checkSwizzle(const osg::Texture & attr)98 static bool checkSwizzle( const osg::Texture& attr )
99 {
100     return true;
101 }
102 
swizzleToCharacter(GLint swizzle,unsigned char defaultCharacter)103 static unsigned char swizzleToCharacter(GLint swizzle, unsigned char defaultCharacter)
104 {
105     switch (swizzle)
106     {
107     case GL_RED:
108         return 'R';
109     case GL_GREEN:
110         return 'G';
111     case GL_BLUE:
112         return 'B';
113     case GL_ALPHA:
114         return 'A';
115     case GL_ZERO:
116         return '0';
117     case GL_ONE:
118         return '1';
119     default:
120         break;
121     }
122 
123     return defaultCharacter;
124 }
125 
characterToSwizzle(unsigned char character,GLint defaultSwizzle)126 static GLint characterToSwizzle(unsigned char character, GLint defaultSwizzle)
127 {
128     switch (character)
129     {
130     case 'R':
131         return GL_RED;
132     case 'G':
133         return GL_GREEN;
134     case 'B':
135         return GL_BLUE;
136     case 'A':
137         return GL_ALPHA;
138     case '0':
139         return GL_ZERO;
140     case '1':
141         return GL_ONE;
142     default:
143         break;
144     }
145 
146     return defaultSwizzle;
147 }
148 
swizzleToString(const osg::Vec4i & swizzle)149 static std::string swizzleToString(const osg::Vec4i& swizzle)
150 {
151     std::string result;
152 
153     result.push_back(swizzleToCharacter(swizzle.r(), 'R'));
154     result.push_back(swizzleToCharacter(swizzle.g(), 'G'));
155     result.push_back(swizzleToCharacter(swizzle.b(), 'B'));
156     result.push_back(swizzleToCharacter(swizzle.a(), 'A'));
157 
158     return result;
159 }
160 
stringToSwizzle(const std::string & swizzleString)161 static osg::Vec4i stringToSwizzle(const std::string& swizzleString)
162 {
163     osg::Vec4i swizzle;
164 
165     swizzle.r() = characterToSwizzle(swizzleString[0], GL_RED);
166     swizzle.g() = characterToSwizzle(swizzleString[1], GL_GREEN);
167     swizzle.b() = characterToSwizzle(swizzleString[2], GL_BLUE);
168     swizzle.a() = characterToSwizzle(swizzleString[3], GL_ALPHA);
169 
170     return swizzle;
171 }
172 
readSwizzle(osgDB::InputStream & is,osg::Texture & attr)173 static bool readSwizzle( osgDB::InputStream& is, osg::Texture& attr )
174 {
175     std::string swizzleString;
176     is >> swizzleString;
177     attr.setSwizzle(stringToSwizzle(swizzleString));
178 
179     return true;
180 }
181 
writeSwizzle(osgDB::OutputStream & os,const osg::Texture & attr)182 static bool writeSwizzle( osgDB::OutputStream& os, const osg::Texture& attr )
183 {
184     os << swizzleToString(attr.getSwizzle()) << std::endl;
185 
186     return true;
187 }
188 
189 REGISTER_OBJECT_WRAPPER( Texture,
190                          /*new osg::Texture*/NULL,
191                          osg::Texture,
192                          "osg::Object osg::StateAttribute osg::Texture" )
193 {
194     ADD_USER_SERIALIZER( WRAP_S );  // _wrap_s
195     ADD_USER_SERIALIZER( WRAP_T );  // _wrap_t
196     ADD_USER_SERIALIZER( WRAP_R );  // _wrap_r
197     ADD_USER_SERIALIZER( MIN_FILTER );  // _min_filter
198     ADD_USER_SERIALIZER( MAG_FILTER );  // _mag_filter
199     ADD_FLOAT_SERIALIZER( MaxAnisotropy, 1.0f );  // _maxAnisotropy
200     ADD_BOOL_SERIALIZER( UseHardwareMipMapGeneration, true );  // _useHardwareMipMapGeneration
201     ADD_BOOL_SERIALIZER( UnRefImageDataAfterApply, false );  // _unrefImageDataAfterApply
202     ADD_BOOL_SERIALIZER( ClientStorageHint, false );  // _clientStorageHint
203     ADD_BOOL_SERIALIZER( ResizeNonPowerOfTwoHint, true );  // _resizeNonPowerOfTwoHint
204     ADD_VEC4D_SERIALIZER( BorderColor, osg::Vec4d(0.0,0.0,0.0,0.0) );  // _borderColor
205     ADD_GLINT_SERIALIZER( BorderWidth, 0 );  // _borderWidth
206 
207     BEGIN_ENUM_SERIALIZER( InternalFormatMode, USE_IMAGE_DATA_FORMAT );
208         ADD_ENUM_VALUE( USE_IMAGE_DATA_FORMAT );
209         ADD_ENUM_VALUE( USE_USER_DEFINED_FORMAT );
210         ADD_ENUM_VALUE( USE_ARB_COMPRESSION );
211         ADD_ENUM_VALUE( USE_S3TC_DXT1_COMPRESSION );
212         ADD_ENUM_VALUE( USE_S3TC_DXT3_COMPRESSION );
213         ADD_ENUM_VALUE( USE_S3TC_DXT5_COMPRESSION );
214         ADD_ENUM_VALUE( USE_PVRTC_2BPP_COMPRESSION );
215         ADD_ENUM_VALUE( USE_PVRTC_4BPP_COMPRESSION );
216         ADD_ENUM_VALUE( USE_ETC_COMPRESSION );
217         ADD_ENUM_VALUE( USE_RGTC1_COMPRESSION );
218         ADD_ENUM_VALUE( USE_RGTC2_COMPRESSION );
219         ADD_ENUM_VALUE( USE_S3TC_DXT1c_COMPRESSION );
220         ADD_ENUM_VALUE( USE_S3TC_DXT1a_COMPRESSION );
221     END_ENUM_SERIALIZER();  // _internalFormatMode
222 
223     ADD_USER_SERIALIZER( InternalFormat );  // _internalFormat
224     ADD_USER_SERIALIZER( SourceFormat );  // _sourceFormat
225     ADD_USER_SERIALIZER( SourceType );  // _sourceType
226     ADD_BOOL_SERIALIZER( ShadowComparison, false );  // _use_shadow_comparison
227 
228     BEGIN_ENUM_SERIALIZER( ShadowCompareFunc, LEQUAL );
229         ADD_ENUM_VALUE( NEVER );
230         ADD_ENUM_VALUE( LESS );
231         ADD_ENUM_VALUE( EQUAL );
232         ADD_ENUM_VALUE( LEQUAL );
233         ADD_ENUM_VALUE( GREATER );
234         ADD_ENUM_VALUE( NOTEQUAL );
235         ADD_ENUM_VALUE( GEQUAL );
236         ADD_ENUM_VALUE( ALWAYS );
237     END_ENUM_SERIALIZER();  // _shadow_compare_func
238 
239     BEGIN_ENUM_SERIALIZER( ShadowTextureMode, LUMINANCE );
240         ADD_ENUM_VALUE( LUMINANCE );
241         ADD_ENUM_VALUE( INTENSITY );
242         ADD_ENUM_VALUE( ALPHA );
243     END_ENUM_SERIALIZER();  // _shadow_texture_mode
244 
245     ADD_FLOAT_SERIALIZER( ShadowAmbient, 0.0f );  // _shadow_ambient
246 
247     {
248         UPDATE_TO_VERSION_SCOPED( 95 )
249         ADD_USER_SERIALIZER( ImageAttachment );  // _imageAttachment
250     }
251 
252     {
253         UPDATE_TO_VERSION_SCOPED( 98 )
254         ADD_USER_SERIALIZER( Swizzle );  // _swizzle
255     }
256 }
257