root/OpenSceneGraph/trunk/include/osg/Image @ 10924

Revision 10924, 16.1 kB (checked in by robert, 5 years ago)

Refactored the way that osg::Image/ImageSequence manages the update callback that needs to be attached to Textures to make it possible to use the Image::update() mechansim in other subclasses from osg::Image.
To enable the automatic attachment of the required update callback to call osg::Image::update(..) subclasses from osg::Image will
need to implement the osg::Image::requestUpdateCall() and return true, and implement the osg::Image::update(NodeVisitor?*) method to recieve the update call during the update traversal.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSG_IMAGE
15#define OSG_IMAGE 1
16
17#include <osg/BufferObject>
18#include <osg/Vec2>
19#include <osg/Vec3>
20#include <osg/Vec4>
21#include <osg/FrameStamp>
22#include <osg/StateAttribute>
23
24#include <string>
25#include <vector>
26
27#ifndef GL_VERSION_1_2
28    // 1.2 definitions...
29    #define GL_BGR                          0x80E0
30    #define GL_BGRA                         0x80E1
31    #define GL_UNSIGNED_BYTE_3_3_2          0x8032
32    #define GL_UNSIGNED_BYTE_2_3_3_REV      0x8362
33    #define GL_UNSIGNED_SHORT_5_6_5         0x8363
34    #define GL_UNSIGNED_SHORT_5_6_5_REV     0x8364
35    #define GL_UNSIGNED_SHORT_4_4_4_4       0x8033
36    #define GL_UNSIGNED_SHORT_4_4_4_4_REV   0x8365
37    #define GL_UNSIGNED_SHORT_5_5_5_1       0x8034
38    #define GL_UNSIGNED_SHORT_1_5_5_5_REV   0x8366
39    #define GL_UNSIGNED_INT_8_8_8_8         0x8035
40    #define GL_UNSIGNED_INT_8_8_8_8_REV     0x8367
41    #define GL_UNSIGNED_INT_10_10_10_2      0x8036
42    #define GL_UNSIGNED_INT_2_10_10_10_REV  0x8368
43#endif
44
45#ifndef GL_COMPRESSED_ALPHA
46    #define GL_COMPRESSED_ALPHA             0x84E9
47    #define GL_COMPRESSED_LUMINANCE         0x84EA
48    #define GL_COMPRESSED_LUMINANCE_ALPHA   0x84EB
49    #define GL_COMPRESSED_INTENSITY         0x84EC
50    #define GL_COMPRESSED_RGB               0x84ED
51    #define GL_COMPRESSED_RGBA              0x84EE
52#endif
53
54
55#ifndef GL_ABGR_EXT
56#define GL_ABGR_EXT                         0x8000
57#endif
58
59namespace osg {
60
61// forward declare
62class NodeVisitor;
63
64/** Image class for encapsulating the storage texture image data. */
65class OSG_EXPORT Image : public BufferData
66{
67
68    public :
69
70        Image();
71       
72        /** Copy constructor using CopyOp to manage deep vs shallow copy. */
73        Image(const Image& image,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
74
75        virtual Object* cloneType() const { return new Image(); }
76        virtual Object* clone(const CopyOp& copyop) const { return new Image(*this,copyop); }
77        virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Image*>(obj)!=0; }
78        virtual const char* libraryName() const { return "osg"; }
79        virtual const char* className() const { return "Image"; }
80
81        virtual const GLvoid*   getDataPointer() const { return data(); }
82        virtual unsigned int    getTotalDataSize() const { return getTotalSizeInBytesIncludingMipmaps(); }
83
84        /** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
85        virtual int compare(const Image& rhs) const;
86
87        void setFileName(const std::string& fileName);
88        inline const std::string& getFileName() const { return _fileName; }
89       
90        enum WriteHint {
91            NO_PREFERENCE,
92            STORE_INLINE,
93            EXTERNAL_FILE
94        };
95       
96        void setWriteHint(WriteHint writeHint) { _writeHint = writeHint; }
97        WriteHint getWriteHint() const { return _writeHint; }
98       
99        enum AllocationMode {
100            NO_DELETE,
101            USE_NEW_DELETE,
102            USE_MALLOC_FREE
103        };
104       
105        /** Set the method used for deleting data once it goes out of scope. */
106        void setAllocationMode(AllocationMode mode) { _allocationMode = mode; }
107
108        /** Get the method used for deleting data once it goes out of scope. */
109        AllocationMode getAllocationMode() const { return _allocationMode; }
110
111
112        /** Allocate a pixel block of specified size and type. */
113        virtual void allocateImage(int s,int t,int r,
114                           GLenum pixelFormat,GLenum type,
115                           int packing=1);
116       
117       
118        /** Set the image dimensions, format and data. */
119        virtual void setImage(int s,int t,int r,
120                      GLint internalTextureformat,
121                      GLenum pixelFormat,GLenum type,
122                      unsigned char* data,
123                      AllocationMode mode,
124                      int packing=1);
125           
126        /** Read pixels from current frame buffer at specified position and size, using glReadPixels.
127          * Create memory for storage if required, reuse existing pixel coords if possible.
128        */
129        virtual void readPixels(int x,int y,int width,int height,
130                        GLenum pixelFormat,GLenum type);
131           
132
133        /** Read the contents of the current bound texture, handling compressed pixelFormats if present.
134          * Create memory for storage if required, reuse existing pixel coords if possible.
135        */
136        virtual void readImageFromCurrentTexture(unsigned int contextID, bool copyMipMapsIfAvailable, GLenum type = GL_UNSIGNED_BYTE);
137
138
139        /** Scale image to specified size.
140          * \warning The method uses gluScaleImage() and thus needs a valid rendering context.
141        */
142        void scaleImage(int s,int t,int r) { scaleImage(s,t,r, getDataType()); }
143
144        /** Scale image to specified size and with specified data type.
145          * \warning The method uses gluScaleImage() and thus needs a valid rendering context.
146        */
147        virtual void scaleImage(int s,int t,int r, GLenum newDataType);
148
149        /** Copy a source Image into a subpart of this Image at specified position.
150          * Typically used to copy to an already allocated image, such as creating
151          * a 3D image from a stack 2D images.
152          * If this Image is empty then image data is created to
153          * accomodate the source image in its offset position.
154          * If source is NULL then no operation happens, this Image is left unchanged.
155        */
156        virtual void copySubImage(int s_offset, int t_offset, int r_offset, const osg::Image* source);
157
158
159        enum Origin
160        {
161            BOTTOM_LEFT,
162            TOP_LEFT
163        };
164       
165        /** Set the origin of the image.
166          * The default value is BOTTOM_LEFT and is consistent with OpenGL.
167          * TOP_LEFT is used for imagery that follows standard Imagery convention, such as movies,
168          * and hasn't been flipped yet.  For such images one much flip the t axis of the tex coords.
169          * to handle this origin position. */
170        void setOrigin(Origin origin) { _origin = origin; }
171       
172        /** Get the origin of the image.*/
173        Origin getOrigin() const { return _origin; }
174       
175
176        /** Width of image. */
177        inline int s() const { return _s; }
178
179        /** Height of image. */
180        inline int t() const { return _t; }
181       
182        /** Depth of image. */
183        inline int r() const { return _r; }
184       
185        void setInternalTextureFormat(GLint internalFormat);
186        inline GLint getInternalTextureFormat() const { return _internalTextureFormat; }
187       
188        void setPixelFormat(GLenum pixelFormat);
189        inline GLenum getPixelFormat() const { return _pixelFormat; }
190       
191        void setDataType(GLenum dataType);
192        inline GLenum getDataType() const { return _dataType; }       
193       
194        void setPacking(unsigned int packing) { _packing = packing; }
195        inline unsigned int getPacking() const { return _packing; }
196
197        /** Set the pixel aspect ratio, defined as the pixel width divided by the pixel height.*/
198        inline void setPixelAspectRatio(float pixelAspectRatio) { _pixelAspectRatio = pixelAspectRatio; }
199
200        /** Get the pixel aspect ratio.*/
201        inline float getPixelAspectRatio() const { return _pixelAspectRatio; }
202       
203        /** Return the number of bits required for each pixel. */
204        inline unsigned int getPixelSizeInBits() const { return computePixelSizeInBits(_pixelFormat,_dataType); }
205
206        /** Return the number of bytes each row of pixels occupies once it has been packed. */
207        inline unsigned int getRowSizeInBytes() const { return computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing); }
208
209        /** Return the number of bytes each image (_s*_t) of pixels occupies. */
210        inline unsigned int getImageSizeInBytes() const { return getRowSizeInBytes()*_t; }
211       
212        /** Return the number of bytes the whole row/image/volume of pixels occupies. */
213        inline unsigned int getTotalSizeInBytes() const { return getImageSizeInBytes()*_r; }
214
215        /** Return the number of bytes the whole row/image/volume of pixels occupies, including all mip maps if included. */
216        unsigned int getTotalSizeInBytesIncludingMipmaps() const;
217
218        /** Return true if the Image represent a valid and usable imagery.*/
219        bool valid() const { return _s!=0 && _t!=0 && _r!=0 && _data!=0 && _dataType!=0; }
220
221        /** Raw image data. */
222        inline unsigned char* data() { return _data; }
223       
224        /** Raw const image data. */
225        inline const unsigned char* data() const { return _data; }
226
227
228        inline unsigned char* data(int column, int row=0,int image=0)
229        {
230            if (!_data) return NULL;
231            return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes();
232        }
233       
234        inline const unsigned char* data(int column, int row=0,int image=0) const
235        {
236            if (!_data) return NULL;
237            return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes();
238        }
239
240        /** Get the color value for specified texcoord.*/
241        Vec4 getColor(unsigned int s,unsigned t=0,unsigned r=0) const;
242
243        /** Get the color value for specified texcoord.*/
244        Vec4 getColor(const Vec2& texcoord) const { return getColor(Vec3(texcoord.x(),texcoord.y(),0.0f)); }
245
246        /** Get the color value for specified texcoord.*/
247        Vec4 getColor(const Vec3& texcoord) const;
248
249
250        /** Flip the image horizontally. */
251        void flipHorizontal();
252       
253        /** Flip the image vertically. */
254        void flipVertical();
255
256
257        /** Ensure image dimensions are a power of two.
258          * Mipmapped textures require the image dimensions to be
259          * power of two and are within the maxiumum texture size for
260          * the host machine.
261        */
262        void ensureValidSizeForTexturing(GLint maxTextureSize);
263
264        static bool isPackedType(GLenum type);
265        static GLenum computePixelFormat(GLenum pixelFormat);
266        static GLenum computeFormatDataType(GLenum pixelFormat);
267        static unsigned int computeNumComponents(GLenum pixelFormat);
268        static unsigned int computePixelSizeInBits(GLenum pixelFormat,GLenum type);
269        static unsigned int computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing);
270        static int computeNearestPowerOfTwo(int s,float bias=0.5f);
271        static int computeNumberOfMipmapLevels(int s,int t = 1, int r = 1);
272               
273        /** Precomputed mipmaps stuff. */
274        typedef std::vector< unsigned int > MipmapDataType;
275
276        inline bool isMipmap() const {return !_mipmapData.empty();};
277
278        unsigned int getNumMipmapLevels() const
279        {
280            return static_cast<unsigned int>(_mipmapData.size())+1;
281        };
282
283        /** Send offsets into data. It is assumed that first mipmap offset (index 0) is 0.*/
284        inline void setMipmapLevels(const MipmapDataType& mipmapDataVector) { _mipmapData = mipmapDataVector; }
285       
286        inline const MipmapDataType& getMipmapLevels() const { return _mipmapData; }
287
288        inline unsigned int getMipmapOffset(unsigned int mipmapLevel) const
289        {
290            if(mipmapLevel == 0)
291                return 0;
292            else if (mipmapLevel < getNumMipmapLevels())
293               return _mipmapData[mipmapLevel-1];
294            return 0;
295        };
296       
297        inline unsigned char* getMipmapData(unsigned int mipmapLevel)
298        {
299           return _data+getMipmapOffset(mipmapLevel);
300        }
301
302        inline const unsigned char* getMipmapData(unsigned int mipmapLevel) const
303        {
304           return _data+getMipmapOffset(mipmapLevel);
305        }
306
307        /*inline const unsigned char* getMipmapData(unsigned int row, unsigned int column, unsigned int mipmapLevel) const
308        {
309           if (!_data) return NULL;
310           return getMipmapData(mipmapLevel) + (column*getPixelSizeInBits())/8+row*getRowSizeInBytes();
311        }*/
312
313        /** Return true if this image is translucent - i.e. it has alpha values that are less 1.0 (when normalized). */
314        virtual bool isImageTranslucent() const;
315
316        /** Set the optional PixelBufferObject used to map the image memory efficiently to graphics memory. */
317        void setPixelBufferObject(PixelBufferObject* buffer) { setBufferObject(buffer); }
318
319        /** Get the PixelBufferObject.*/
320        PixelBufferObject* getPixelBufferObject() { return dynamic_cast<PixelBufferObject*>(_bufferObject.get()); }
321
322        /** Get the const PixelBufferObject.*/
323        const PixelBufferObject* getPixelBufferObject() const { return dynamic_cast<const PixelBufferObject*>(_bufferObject.get()); }
324
325        /** return whether the update(NodeVisitor* nv) should be required on each frame to enable proper working of osg::Image.*/
326        virtual bool requiresUpdateCall() const { return false; }
327
328        /** update method for osg::Image subclasses that update themselves during the update traversal.*/
329        virtual void update(NodeVisitor* /*nv*/) {}
330
331        /** convience update callback class that can be attached to StateAttribute (such as Textures) to ensure
332          * that the Image::update(NodeVisitor*) method is called during the update traversal.  This callback
333          * is automatically attached when Image::requiresUpdateCall() is true (it's false by default.)
334          */
335        struct OSG_EXPORT UpdateCallback : public osg::StateAttributeCallback
336        {
337            virtual void operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv);
338        };
339
340        /** method for sending pointer events to images that are acting as front ends to interactive surfaces such as a vnc or browser window.  Return true if handled. */
341        virtual bool sendPointerEvent(int /*x*/, int /*y*/, int /*buttonMask*/) { return false; }
342
343        /** method for sending key events to images that are acting as front ends to interactive surfaces such as a vnc or browser window.  Return true if handled.*/
344        virtual bool sendKeyEvent(int /*key*/, bool /*keyDown*/) { return false; }
345
346        /** method for passing frame information to the custom Image classes, to be called only when objects associated with imagery are not culled.*/
347        virtual void setFrameLastRendered(const osg::FrameStamp* /*frameStamp*/) {}
348
349    protected :
350
351        virtual ~Image();
352
353        Image& operator = (const Image&) { return *this; }
354
355        std::string _fileName;
356        WriteHint   _writeHint;
357
358
359        Origin _origin;
360
361        int _s, _t, _r;
362        GLint _internalTextureFormat;
363        GLenum _pixelFormat;
364        GLenum _dataType;
365        unsigned int _packing;
366        float _pixelAspectRatio;
367
368        AllocationMode _allocationMode;
369        unsigned char* _data;
370       
371        void deallocateData();
372       
373        void setData(unsigned char* data,AllocationMode allocationMode);
374
375        MipmapDataType _mipmapData;
376       
377        ref_ptr<PixelBufferObject> _bufferObject;
378};
379
380class Geode;
381
382/** Convenience function to be used by image loaders to generate a valid geode
383  * to return for readNode().
384  * Use the image's s and t values to scale the dimensions of the image.
385*/
386extern OSG_EXPORT Geode* createGeodeForImage(Image* image);
387/** Convenience function to be used by image loaders to generate a valid geode
388  * to return for readNode().
389  * Use the specified s and t values to scale the dimensions of the image.
390*/
391extern OSG_EXPORT Geode* createGeodeForImage(Image* image,float s,float t);
392
393}
394
395#endif                                            // __SG_IMAGE_H
Note: See TracBrowser for help on using the browser.