1 /*****************************************************************************
2 * $LastChangedDate: 2010-02-03 13:50:46 -0500 (Wed, 03 Feb 2010) $
3 * @file
4 * @author Jim E. Brooks http://www.palomino3d.org
5 * @brief Texture class.
6 *//*
7 * LEGAL: COPYRIGHT (C) 2008 JIM E. BROOKS
8 * THIS SOURCE CODE IS RELEASED UNDER THE TERMS
9 * OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
10 *****************************************************************************/
11
12 #define FX_TEXTURE_CC 1
13 #include "base/module.hh"
14 using namespace base;
15 #include "fx/module.hh"
16 #include "fx/texture.hh"
17 #include "fx/image_cache.hh"
18
19 #include <osgDB/WriteFile>
20
21 namespace fx {
22
23 ////////////////////////////////////////////////////////////////////////////////
24 ///////////////////////////////// Texture ////////////////////////////////////
25 ////////////////////////////////////////////////////////////////////////////////
26
27 /*****************************************************************************
28 * Construct Texture from raw memory buffer.
29 * @param buf
30 * RGBA array. Whether OSG will own buf depends on allocationMode.
31 * @param width
32 * Texture width defines size of buf.
33 * @param allocationMode
34 * osg::Image::AllocationMode { NO_DELETE, USE_NEW_DELETE, USE_MALLOC_FREE }
35 *****************************************************************************/
Texture(uint8 * buf,const uint width,const osg::Image::AllocationMode allocationMode)36 Texture::Texture( uint8* buf, const uint width, const osg::Image::AllocationMode allocationMode )
37 : mTextureObject(new osg::Texture2D)
38 {
39 SET_TYPESIG(this,TYPESIG_TEXTURE);
40
41 Configure();
42
43 // man glTexImage2D
44 RefPtr<osg::Image> image = new osg::Image;
45 image->setImage( width, // s
46 width, // t
47 1, // r
48 GL_COMPRESSED_RGBA, // internalTextureformat (use texture compression)
49 GL_RGBA, // pixelFormat
50 GL_UNSIGNED_BYTE, // type
51 buf, // data
52 allocationMode ); // AllocationMode
53 mTextureObject->setImage( image.get() );
54 }
55
56 /*****************************************************************************
57 * Construct Texture from osg::Image.
58 *****************************************************************************/
Texture(RefPtr<osg::Image> image)59 Texture::Texture( RefPtr<osg::Image> image )
60 : mTextureObject(new osg::Texture2D)
61 {
62 SET_TYPESIG(this,TYPESIG_TEXTURE);
63
64 Configure();
65
66 mTextureObject->setImage( image.get() );
67 }
68
69 /*****************************************************************************
70 * Construct Texture from file. Uses ImageCache.
71 *****************************************************************************/
Texture(const string & filename)72 Texture::Texture( const string& filename )
73 : mTextureObject(new osg::Texture2D)
74 {
75 ASSERT( not filename.empty() );
76 SET_TYPESIG(this,TYPESIG_TEXTURE);
77
78 Configure();
79
80 // Load texture image into texture object. Might throw C++ exception.
81 mTextureObject->setImage( GET_IMAGE_CACHE().LoadImage(filename).get() );
82 }
83
84 /*****************************************************************************
85 * dtor.
86 *****************************************************************************/
~Texture()87 Texture::~Texture()
88 {
89 INVALIDATE_TYPESIG(this,TYPESIG_TEXTURE);
90 }
91
92 /*****************************************************************************
93 * Attach texture to node.
94 *****************************************************************************/
95 void
Bind(osg::StateSet & stateset)96 Texture::Bind( osg::StateSet& stateset )
97 {
98 CHECK_TYPESIG(this,TYPESIG_TEXTURE);
99
100 stateset.setTextureAttributeAndModes( 0, mTextureObject.get(), osg::StateAttribute::ON );
101 }
102
103 /*****************************************************************************
104 * Write texture image to file.
105 * @return True else exception.
106 *****************************************************************************/
107 bool
SaveToFile(const string & filename)108 Texture::SaveToFile( const string& filename )
109 {
110 // Set the filename of the Image so that OSG has a way
111 // to reference the file if the scene-graph is dumped.
112 RefPtr<osg::Image> image = mTextureObject->getImage();
113 if ( image == NULL )
114 throw Exception( string("ERROR: no osg::Image to be written to file ") + filename );
115 image->setFileName( filename );
116 if ( not osgDB::writeImageFile( *image, filename ) )
117 throw Exception( string("ERROR: writing texture to file ") + filename );
118 return true;
119 }
120
121 /*****************************************************************************
122 * Create osg::StateSet with new Texture bound to it.
123 *****************************************************************************/
124 RefPtr<osg::StateSet> // CLASS_METHOD
NewTextureAsStateSet(const string & filename)125 Texture::NewTextureAsStateSet( const string& filename )
126 {
127 shptr<Texture> texture = new Texture( filename );
128 RefPtr<osg::StateSet> stateSet = new osg::StateSet;
129 texture->Bind( *stateSet );
130 return stateSet;
131 }
132
133 } // namespace fx
134