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