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

Revision 13041, 20.2 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • 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
59#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
60    #define GL_RED                  0x1903
61    #define GL_GREEN                0x1904
62    #define GL_BLUE                 0x1905
63    #define GL_DEPTH_COMPONENT      0x1902
64    #define GL_STENCIL_INDEX        0x1901
65#endif
66
67#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GL3_AVAILABLE)
68    #define GL_BITMAP               0x1A00
69    #define GL_COLOR_INDEX          0x1900
70    #define GL_INTENSITY12          0x804C
71    #define GL_INTENSITY16          0x804D
72    #define GL_INTENSITY4           0x804A
73    #define GL_INTENSITY8           0x804B
74    #define GL_LUMINANCE12          0x8041
75    #define GL_LUMINANCE12_ALPHA4   0x8046
76    #define GL_LUMINANCE12_ALPHA12  0x8047
77    #define GL_LUMINANCE16          0x8042
78    #define GL_LUMINANCE16_ALPHA16  0x8048
79    #define GL_LUMINANCE4           0x803F
80    #define GL_LUMINANCE4_ALPHA4    0x8043
81    #define GL_LUMINANCE6_ALPHA2    0x8044
82    #define GL_LUMINANCE8           0x8040
83    #define GL_LUMINANCE8_ALPHA8    0x8045
84    #define GL_RGBA8                0x8058
85    #define GL_PACK_ROW_LENGTH      0x0D02
86#endif
87
88#ifndef GL_PACK_SKIP_IMAGES
89    #define GL_PACK_SKIP_IMAGES     0x806B
90    #define GL_PACK_IMAGE_HEIGHT    0x806C
91    #define GL_UNPACK_SKIP_IMAGES   0x806D
92    #define GL_UNPACK_IMAGE_HEIGHT  0x806E
93#endif
94
95#ifndef GL_OES_compressed_ETC1_RGB8_texture
96    #define GL_ETC1_RGB8_OES        0x8D64
97#endif
98
99namespace osg {
100
101// forward declare
102class NodeVisitor;
103
104/** Image class for encapsulating the storage texture image data. */
105class OSG_EXPORT Image : public BufferData
106{
107
108    public :
109
110        Image();
111
112        /** Copy constructor using CopyOp to manage deep vs shallow copy. */
113        Image(const Image& image,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
114
115        virtual Object* cloneType() const { return new Image(); }
116        virtual Object* clone(const CopyOp& copyop) const { return new Image(*this,copyop); }
117        virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Image*>(obj)!=0; }
118        virtual const char* libraryName() const { return "osg"; }
119        virtual const char* className() const { return "Image"; }
120
121        virtual osg::Image* asImage() { return this; }
122        virtual const osg::Image* asImage() const { return this; }
123
124        virtual const GLvoid*   getDataPointer() const { return data(); }
125        virtual unsigned int    getTotalDataSize() const { return getTotalSizeInBytesIncludingMipmaps(); }
126
127        /** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
128        virtual int compare(const Image& rhs) const;
129
130        void setFileName(const std::string& fileName);
131        inline const std::string& getFileName() const { return _fileName; }
132
133        enum WriteHint {
134            NO_PREFERENCE,
135            STORE_INLINE,
136            EXTERNAL_FILE
137        };
138
139        void setWriteHint(WriteHint writeHint) { _writeHint = writeHint; }
140        WriteHint getWriteHint() const { return _writeHint; }
141
142        enum AllocationMode {
143            NO_DELETE,
144            USE_NEW_DELETE,
145            USE_MALLOC_FREE
146        };
147
148        /** Set the method used for deleting data once it goes out of scope. */
149        void setAllocationMode(AllocationMode mode) { _allocationMode = mode; }
150
151        /** Get the method used for deleting data once it goes out of scope. */
152        AllocationMode getAllocationMode() const { return _allocationMode; }
153
154
155        /** Allocate a pixel block of specified size and type. */
156        virtual void allocateImage(int s,int t,int r,
157                           GLenum pixelFormat,GLenum type,
158                           int packing=1);
159
160
161        /** Set the image dimensions, format and data. */
162        virtual void setImage(int s,int t,int r,
163                      GLint internalTextureformat,
164                      GLenum pixelFormat,GLenum type,
165                      unsigned char* data,
166                      AllocationMode mode,
167                      int packing=1, int rowLength=0);
168
169        /** Read pixels from current frame buffer at specified position and size, using glReadPixels.
170          * Create memory for storage if required, reuse existing pixel coords if possible.
171        */
172        virtual void readPixels(int x,int y,int width,int height,
173                        GLenum pixelFormat,GLenum type);
174
175
176        /** Read the contents of the current bound texture, handling compressed pixelFormats if present.
177          * Create memory for storage if required, reuse existing pixel coords if possible.
178        */
179        virtual void readImageFromCurrentTexture(unsigned int contextID, bool copyMipMapsIfAvailable, GLenum type = GL_UNSIGNED_BYTE, unsigned int face = 0);
180
181
182        /** Scale image to specified size. */
183        void scaleImage(int s,int t,int r) { scaleImage(s,t,r, getDataType()); }
184
185        /** Scale image to specified size and with specified data type. */
186        virtual void scaleImage(int s,int t,int r, GLenum newDataType);
187
188        /** Copy a source Image into a subpart of this Image at specified position.
189          * Typically used to copy to an already allocated image, such as creating
190          * a 3D image from a stack 2D images.
191          * If this Image is empty then image data is created to
192          * accomodate the source image in its offset position.
193          * If source is NULL then no operation happens, this Image is left unchanged.
194        */
195        virtual void copySubImage(int s_offset, int t_offset, int r_offset, const osg::Image* source);
196
197
198        enum Origin
199        {
200            BOTTOM_LEFT,
201            TOP_LEFT
202        };
203
204        /** Set the origin of the image.
205          * The default value is BOTTOM_LEFT and is consistent with OpenGL.
206          * TOP_LEFT is used for imagery that follows standard Imagery convention, such as movies,
207          * and hasn't been flipped yet.  For such images one much flip the t axis of the tex coords.
208          * to handle this origin position. */
209        void setOrigin(Origin origin) { _origin = origin; }
210
211        /** Get the origin of the image.*/
212        Origin getOrigin() const { return _origin; }
213
214
215        /** Width of image. */
216        inline int s() const { return _s; }
217
218        /** Height of image. */
219        inline int t() const { return _t; }
220
221        /** Depth of image. */
222        inline int r() const { return _r; }
223
224        void setRowLength(int length);
225        inline int getRowLength() const { return _rowLength; }
226
227        void setInternalTextureFormat(GLint internalFormat);
228        inline GLint getInternalTextureFormat() const { return _internalTextureFormat; }
229
230        void setPixelFormat(GLenum pixelFormat);
231        inline GLenum getPixelFormat() const { return _pixelFormat; }
232
233        void setDataType(GLenum dataType);
234        inline GLenum getDataType() const { return _dataType; }
235
236        void setPacking(unsigned int packing) { _packing = packing; }
237        inline unsigned int getPacking() const { return _packing; }
238
239        /** return true of the pixel format is an OpenGL compressed pixel format.*/
240        bool isCompressed() const;
241
242        /** Set the pixel aspect ratio, defined as the pixel width divided by the pixel height.*/
243        inline void setPixelAspectRatio(float pixelAspectRatio) { _pixelAspectRatio = pixelAspectRatio; }
244
245        /** Get the pixel aspect ratio.*/
246        inline float getPixelAspectRatio() const { return _pixelAspectRatio; }
247
248        /** Return the number of bits required for each pixel. */
249        inline unsigned int getPixelSizeInBits() const { return computePixelSizeInBits(_pixelFormat,_dataType); }
250
251        /** Return the number of bytes each row of pixels occupies once it has been packed. */
252        inline unsigned int getRowSizeInBytes() const { return computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing); }
253
254        /** Return the number of bytes between each successive row.
255          * Note, getRowSizeInBytes() will only equal getRowStepInBytes() when isDataContiguous() return true. */
256        inline unsigned int getRowStepInBytes() const { return computeRowWidthInBytes(_rowLength==0?_s:_rowLength,_pixelFormat,_dataType,_packing); }
257
258        /** Return the number of bytes each image (_s*_t) of pixels occupies. */
259        inline unsigned int getImageSizeInBytes() const { return getRowSizeInBytes()*_t; }
260
261        /** Return the number of bytes between each successive image.
262          * Note, getImageSizeInBytes() will only equal getImageStepInBytes() when isDataContiguous() return true. */
263        inline unsigned int getImageStepInBytes() const { return getRowStepInBytes()*_t; }
264
265        /** Return the number of bytes the whole row/image/volume of pixels occupies. */
266        inline unsigned int getTotalSizeInBytes() const { return getImageSizeInBytes()*_r; }
267
268        /** Return the number of bytes the whole row/image/volume of pixels occupies, including all mip maps if included. */
269        unsigned int getTotalSizeInBytesIncludingMipmaps() const;
270
271        /** Return true if the Image represent a valid and usable imagery.*/
272        bool valid() const { return _s!=0 && _t!=0 && _r!=0 && _data!=0 && _dataType!=0; }
273
274        /** Raw image data.
275          * Note, data in successive rows may not be contiguous, isDataContiguous() return false then you should
276          * take care to access the data per row rather than treating the whole data as a single block. */
277        inline unsigned char* data() { return _data; }
278
279        /** Raw const image data.
280          * Note, data in successive rows may not be contiguous, isDataContiguous() return false then you should
281          * take care to access the data per row rather than treating the whole data as a single block. */
282        inline const unsigned char* data() const { return _data; }
283
284        inline unsigned char* data(int column, int row=0,int image=0)
285        {
286            if (!_data) return NULL;
287            return _data+(column*getPixelSizeInBits())/8+row*getRowStepInBytes()+image*getImageSizeInBytes();
288        }
289
290        inline const unsigned char* data(int column, int row=0,int image=0) const
291        {
292            if (!_data) return NULL;
293            return _data+(column*getPixelSizeInBits())/8+row*getRowStepInBytes()+image*getImageSizeInBytes();
294        }
295
296        /** return true if the data stored in the image is a contiguous block of data.*/
297        bool isDataContiguous() const { return _rowLength==0 || _rowLength==_s; }
298
299        /** Convenience class for assisting the copying of image data when the image data isn't contiguous.*/
300        class OSG_EXPORT DataIterator
301        {
302        public:
303            DataIterator(const Image* image);
304            DataIterator(const DataIterator& ri);
305            ~DataIterator() {}
306
307            /** advance iterator to next block of data.*/
308            void operator ++ ();
309
310            /** is iterator valid.*/
311            bool valid() const { return _currentPtr!=0; }
312
313            /** data pointer of current block to copy.*/
314            const unsigned char* data() const { return _currentPtr; }
315
316            /** Size of current block to copy.*/
317            unsigned int size() const { return _currentSize; }
318
319        protected:
320
321
322            void assign();
323
324            const osg::Image*                   _image;
325            int                                 _rowNum;
326            int                                 _imageNum;
327            unsigned int                        _mipmapNum;
328            const unsigned char*                _currentPtr;
329            unsigned int                        _currentSize;
330        };
331
332        /** Get the color value for specified texcoord.*/
333        Vec4 getColor(unsigned int s,unsigned t=0,unsigned r=0) const;
334
335        /** Get the color value for specified texcoord.*/
336        Vec4 getColor(const Vec2& texcoord) const { return getColor(Vec3(texcoord.x(),texcoord.y(),0.0f)); }
337
338        /** Get the color value for specified texcoord.*/
339        Vec4 getColor(const Vec3& texcoord) const;
340
341
342        /** Flip the image horizontally, around s dimension. */
343        void flipHorizontal();
344
345        /** Flip the image vertically, around t dimension. */
346        void flipVertical();
347
348        /** Flip the image around the r dimension. Only relevent for 3D textures. */
349        void flipDepth();
350
351        /** Ensure image dimensions are a power of two.
352          * Mipmapped textures require the image dimensions to be
353          * power of two and are within the maxiumum texture size for
354          * the host machine.
355        */
356        void ensureValidSizeForTexturing(GLint maxTextureSize);
357
358        static bool isPackedType(GLenum type);
359        static GLenum computePixelFormat(GLenum pixelFormat);
360        static GLenum computeFormatDataType(GLenum pixelFormat);
361        static unsigned int computeBlockSize(GLenum pixelFormat, GLenum packing);
362        static unsigned int computeNumComponents(GLenum pixelFormat);
363        static unsigned int computePixelSizeInBits(GLenum pixelFormat,GLenum type);
364        static unsigned int computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing);
365        static unsigned int computeImageSizeInBytes(int width,int height, int depth, GLenum pixelFormat,GLenum type,int packing);
366        static int computeNearestPowerOfTwo(int s,float bias=0.5f);
367        static int computeNumberOfMipmapLevels(int s,int t = 1, int r = 1);
368
369        /** Precomputed mipmaps stuff. */
370        typedef std::vector< unsigned int > MipmapDataType;
371
372        inline bool isMipmap() const {return !_mipmapData.empty();};
373
374        unsigned int getNumMipmapLevels() const
375        {
376            return static_cast<unsigned int>(_mipmapData.size())+1;
377        };
378
379        /** Send offsets into data. It is assumed that first mipmap offset (index 0) is 0.*/
380        inline void setMipmapLevels(const MipmapDataType& mipmapDataVector) { _mipmapData = mipmapDataVector; }
381
382        inline const MipmapDataType& getMipmapLevels() const { return _mipmapData; }
383
384        inline unsigned int getMipmapOffset(unsigned int mipmapLevel) const
385        {
386            if(mipmapLevel == 0)
387                return 0;
388            else if (mipmapLevel < getNumMipmapLevels())
389               return _mipmapData[mipmapLevel-1];
390            return 0;
391        };
392
393        inline unsigned char* getMipmapData(unsigned int mipmapLevel)
394        {
395           return _data+getMipmapOffset(mipmapLevel);
396        }
397
398        inline const unsigned char* getMipmapData(unsigned int mipmapLevel) const
399        {
400           return _data+getMipmapOffset(mipmapLevel);
401        }
402
403        /** returns false for texture formats that do not support texture subloading */
404        bool supportsTextureSubloading() const;
405
406        /** Return true if this image is translucent - i.e. it has alpha values that are less 1.0 (when normalized). */
407        virtual bool isImageTranslucent() const;
408
409        /** Set the optional PixelBufferObject used to map the image memory efficiently to graphics memory. */
410        void setPixelBufferObject(PixelBufferObject* buffer) { setBufferObject(buffer); }
411
412        /** Get the PixelBufferObject.*/
413        PixelBufferObject* getPixelBufferObject() { return dynamic_cast<PixelBufferObject*>(_bufferObject.get()); }
414
415        /** Get the const PixelBufferObject.*/
416        const PixelBufferObject* getPixelBufferObject() const { return dynamic_cast<const PixelBufferObject*>(_bufferObject.get()); }
417
418        /** return whether the update(NodeVisitor* nv) should be required on each frame to enable proper working of osg::Image.*/
419        virtual bool requiresUpdateCall() const { return false; }
420
421        /** update method for osg::Image subclasses that update themselves during the update traversal.*/
422        virtual void update(NodeVisitor* /*nv*/) {}
423
424        /** convience update callback class that can be attached to StateAttribute (such as Textures) to ensure
425          * that the Image::update(NodeVisitor*) method is called during the update traversal.  This callback
426          * is automatically attached when Image::requiresUpdateCall() is true (it's false by default.)
427          */
428        struct OSG_EXPORT UpdateCallback : public osg::StateAttributeCallback
429        {
430            virtual void operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv);
431        };
432
433        /** method for hinting whether to enable or disable focus to images acting as front ends to interactive surfaces such as a vnc or browser window.  Return true if handled. */
434        virtual bool sendFocusHint(bool /*focus*/) { return false; }
435
436        /** 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. */
437        virtual bool sendPointerEvent(int /*x*/, int /*y*/, int /*buttonMask*/) { return false; }
438
439        /** 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.*/
440        virtual bool sendKeyEvent(int /*key*/, bool /*keyDown*/) { return false; }
441
442        /** method for passing frame information to the custom Image classes, to be called only when objects associated with imagery are not culled.*/
443        virtual void setFrameLastRendered(const osg::FrameStamp* /*frameStamp*/) {}
444
445    protected :
446
447        virtual ~Image();
448
449        Image& operator = (const Image&) { return *this; }
450
451        std::string _fileName;
452        WriteHint   _writeHint;
453
454
455        Origin _origin;
456
457        int _s, _t, _r;
458        int _rowLength;
459        GLint _internalTextureFormat;
460        GLenum _pixelFormat;
461        GLenum _dataType;
462        unsigned int _packing;
463        float _pixelAspectRatio;
464
465        AllocationMode _allocationMode;
466        unsigned char* _data;
467
468        void deallocateData();
469
470        void setData(unsigned char* data,AllocationMode allocationMode);
471
472        MipmapDataType _mipmapData;
473
474        ref_ptr<PixelBufferObject> _bufferObject;
475};
476
477class Geode;
478
479/** Convenience function to be used by image loaders to generate a valid geode
480  * to return for readNode().
481  * Use the image's s and t values to scale the dimensions of the image.
482*/
483extern OSG_EXPORT Geode* createGeodeForImage(Image* image);
484/** Convenience function to be used by image loaders to generate a valid geode
485  * to return for readNode().
486  * Use the specified s and t values to scale the dimensions of the image.
487*/
488extern OSG_EXPORT Geode* createGeodeForImage(Image* image,float s,float t);
489
490}
491
492#endif                                            // __SG_IMAGE_H
Note: See TracBrowser for help on using the browser.