1
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
1
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
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
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
5
* (at your option) any later version. The full license is in LICENSE file
6
6
* included with this distribution, and on the openscenegraph.org website.
8
8
* This library is distributed in the hope that it will be useful,
9
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
* OpenSceneGraph Public License for more details.
92
93
#define GL_UNPACK_IMAGE_HEIGHT 0x806E
96
#ifndef GL_OES_compressed_ETC1_RGB8_texture
97
#define GL_ETC1_RGB8_OES 0x8D64
100
#ifndef GL_DEPTH_COMPONENT
101
#define GL_DEPTH_COMPONENT 0x1902
104
#ifndef GL_VERSION_1_4
105
#define GL_DEPTH_COMPONENT16 0x81A5
106
#define GL_DEPTH_COMPONENT24 0x81A6
107
#define GL_DEPTH_COMPONENT32 0x81A7
110
#ifndef GL_DEPTH_COMPONENT32F
111
#define GL_DEPTH_COMPONENT32F 0x8CAC
114
#ifndef GL_DEPTH_COMPONENT32F_NV
115
#define GL_DEPTH_COMPONENT32F_NV 0x8DAB
97
120
// forward declare
114
137
virtual const char* libraryName() const { return "osg"; }
115
138
virtual const char* className() const { return "Image"; }
140
virtual osg::Image* asImage() { return this; }
141
virtual const osg::Image* asImage() const { return this; }
117
143
virtual const GLvoid* getDataPointer() const { return data(); }
118
144
virtual unsigned int getTotalDataSize() const { return getTotalSizeInBytesIncludingMipmaps(); }
123
149
void setFileName(const std::string& fileName);
124
150
inline const std::string& getFileName() const { return _fileName; }
132
158
void setWriteHint(WriteHint writeHint) { _writeHint = writeHint; }
133
159
WriteHint getWriteHint() const { return _writeHint; }
135
161
enum AllocationMode {
141
167
/** Set the method used for deleting data once it goes out of scope. */
142
168
void setAllocationMode(AllocationMode mode) { _allocationMode = mode; }
149
175
virtual void allocateImage(int s,int t,int r,
150
176
GLenum pixelFormat,GLenum type,
154
180
/** Set the image dimensions, format and data. */
155
181
virtual void setImage(int s,int t,int r,
156
182
GLint internalTextureformat,
157
183
GLenum pixelFormat,GLenum type,
158
184
unsigned char* data,
159
185
AllocationMode mode,
186
int packing=1, int rowLength=0);
162
188
/** Read pixels from current frame buffer at specified position and size, using glReadPixels.
163
189
* Create memory for storage if required, reuse existing pixel coords if possible.
165
191
virtual void readPixels(int x,int y,int width,int height,
166
GLenum pixelFormat,GLenum type);
192
GLenum pixelFormat, GLenum type, int packing=1);
169
195
/** Read the contents of the current bound texture, handling compressed pixelFormats if present.
170
196
* Create memory for storage if required, reuse existing pixel coords if possible.
172
virtual void readImageFromCurrentTexture(unsigned int contextID, bool copyMipMapsIfAvailable, GLenum type = GL_UNSIGNED_BYTE);
198
virtual void readImageFromCurrentTexture(unsigned int contextID, bool copyMipMapsIfAvailable, GLenum type = GL_UNSIGNED_BYTE, unsigned int face = 0);
200
/** swap the data and settings between two image objects.*/
201
void swap(osg::Image& rhs);
175
203
/** Scale image to specified size. */
176
204
void scaleImage(int s,int t,int r) { scaleImage(s,t,r, getDataType()); }
188
216
virtual void copySubImage(int s_offset, int t_offset, int r_offset, const osg::Image* source);
197
225
/** Set the origin of the image.
198
226
* The default value is BOTTOM_LEFT and is consistent with OpenGL.
199
227
* TOP_LEFT is used for imagery that follows standard Imagery convention, such as movies,
200
228
* and hasn't been flipped yet. For such images one much flip the t axis of the tex coords.
201
229
* to handle this origin position. */
202
230
void setOrigin(Origin origin) { _origin = origin; }
204
232
/** Get the origin of the image.*/
205
233
Origin getOrigin() const { return _origin; }
208
236
/** Width of image. */
209
237
inline int s() const { return _s; }
211
239
/** Height of image. */
212
240
inline int t() const { return _t; }
214
242
/** Depth of image. */
215
243
inline int r() const { return _r; }
245
void setRowLength(int length);
246
inline int getRowLength() const { return _rowLength; }
217
248
void setInternalTextureFormat(GLint internalFormat);
218
249
inline GLint getInternalTextureFormat() const { return _internalTextureFormat; }
220
251
void setPixelFormat(GLenum pixelFormat);
221
252
inline GLenum getPixelFormat() const { return _pixelFormat; }
223
254
void setDataType(GLenum dataType);
224
inline GLenum getDataType() const { return _dataType; }
255
inline GLenum getDataType() const { return _dataType; }
226
257
void setPacking(unsigned int packing) { _packing = packing; }
227
258
inline unsigned int getPacking() const { return _packing; }
229
/** return true of the pixel format is an OpenGL compressed pixel format.*/
260
/** Return true of the pixel format is an OpenGL compressed pixel format.*/
230
261
bool isCompressed() const;
232
263
/** Set the pixel aspect ratio, defined as the pixel width divided by the pixel height.*/
235
266
/** Get the pixel aspect ratio.*/
236
267
inline float getPixelAspectRatio() const { return _pixelAspectRatio; }
238
269
/** Return the number of bits required for each pixel. */
239
270
inline unsigned int getPixelSizeInBits() const { return computePixelSizeInBits(_pixelFormat,_dataType); }
241
272
/** Return the number of bytes each row of pixels occupies once it has been packed. */
242
273
inline unsigned int getRowSizeInBytes() const { return computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing); }
275
/** Return the number of bytes between each successive row.
276
* Note, getRowSizeInBytes() will only equal getRowStepInBytes() when isDataContiguous() return true. */
277
inline unsigned int getRowStepInBytes() const { return computeRowWidthInBytes(_rowLength==0?_s:_rowLength,_pixelFormat,_dataType,_packing); }
244
279
/** Return the number of bytes each image (_s*_t) of pixels occupies. */
245
280
inline unsigned int getImageSizeInBytes() const { return getRowSizeInBytes()*_t; }
282
/** Return the number of bytes between each successive image.
283
* Note, getImageSizeInBytes() will only equal getImageStepInBytes() when isDataContiguous() return true. */
284
inline unsigned int getImageStepInBytes() const { return getRowStepInBytes()*_t; }
247
286
/** Return the number of bytes the whole row/image/volume of pixels occupies. */
248
287
inline unsigned int getTotalSizeInBytes() const { return getImageSizeInBytes()*_r; }
253
292
/** Return true if the Image represent a valid and usable imagery.*/
254
293
bool valid() const { return _s!=0 && _t!=0 && _r!=0 && _data!=0 && _dataType!=0; }
256
/** Raw image data. */
296
* Note, data in successive rows may not be contiguous, isDataContiguous() return false then you should
297
* take care to access the data per row rather than treating the whole data as a single block. */
257
298
inline unsigned char* data() { return _data; }
259
/** Raw const image data. */
300
/** Raw const image data.
301
* Note, data in successive rows may not be contiguous, isDataContiguous() return false then you should
302
* take care to access the data per row rather than treating the whole data as a single block. */
260
303
inline const unsigned char* data() const { return _data; }
263
305
inline unsigned char* data(int column, int row=0,int image=0)
265
307
if (!_data) return NULL;
266
return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes();
308
return _data+(column*getPixelSizeInBits())/8+row*getRowStepInBytes()+image*getImageSizeInBytes();
269
311
inline const unsigned char* data(int column, int row=0,int image=0) const
271
313
if (!_data) return NULL;
272
return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes();
314
return _data+(column*getPixelSizeInBits())/8+row*getRowStepInBytes()+image*getImageSizeInBytes();
317
/** return true if the data stored in the image is a contiguous block of data.*/
318
bool isDataContiguous() const { return _rowLength==0 || _rowLength==_s; }
320
/** Convenience class for assisting the copying of image data when the image data isn't contiguous.*/
321
class OSG_EXPORT DataIterator
324
DataIterator(const Image* image);
325
DataIterator(const DataIterator& ri);
328
/** advance iterator to next block of data.*/
331
/** is iterator valid.*/
332
bool valid() const { return _currentPtr!=0; }
334
/** data pointer of current block to copy.*/
335
const unsigned char* data() const { return _currentPtr; }
337
/** Size of current block to copy.*/
338
unsigned int size() const { return _currentSize; }
345
const osg::Image* _image;
348
unsigned int _mipmapNum;
349
const unsigned char* _currentPtr;
350
unsigned int _currentSize;
275
353
/** Get the color value for specified texcoord.*/
276
354
Vec4 getColor(unsigned int s,unsigned t=0,unsigned r=0) const;
282
360
Vec4 getColor(const Vec3& texcoord) const;
285
/** Flip the image horizontally. */
363
/** Flip the image horizontally, around s dimension. */
286
364
void flipHorizontal();
288
/** Flip the image vertically. */
366
/** Flip the image vertically, around t dimension. */
289
367
void flipVertical();
369
/** Flip the image around the r dimension. Only relevent for 3D textures. */
292
372
/** Ensure image dimensions are a power of two.
293
373
* Mipmapped textures require the image dimensions to be
299
379
static bool isPackedType(GLenum type);
300
380
static GLenum computePixelFormat(GLenum pixelFormat);
301
381
static GLenum computeFormatDataType(GLenum pixelFormat);
382
static unsigned int computeBlockSize(GLenum pixelFormat, GLenum packing);
302
383
static unsigned int computeNumComponents(GLenum pixelFormat);
303
384
static unsigned int computePixelSizeInBits(GLenum pixelFormat,GLenum type);
304
385
static unsigned int computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing);
386
static unsigned int computeImageSizeInBytes(int width,int height, int depth, GLenum pixelFormat, GLenum type, int packing = 1, int slice_packing = 1, int image_packing = 1);
305
387
static int computeNearestPowerOfTwo(int s,float bias=0.5f);
306
388
static int computeNumberOfMipmapLevels(int s,int t = 1, int r = 1);
318
400
/** Send offsets into data. It is assumed that first mipmap offset (index 0) is 0.*/
319
401
inline void setMipmapLevels(const MipmapDataType& mipmapDataVector) { _mipmapData = mipmapDataVector; }
321
403
inline const MipmapDataType& getMipmapLevels() const { return _mipmapData; }
323
405
inline unsigned int getMipmapOffset(unsigned int mipmapLevel) const
339
421
return _data+getMipmapOffset(mipmapLevel);
342
/*inline const unsigned char* getMipmapData(unsigned int row, unsigned int column, unsigned int mipmapLevel) const
344
if (!_data) return NULL;
345
return getMipmapData(mipmapLevel) + (column*getPixelSizeInBits())/8+row*getRowSizeInBytes();
424
/** returns false for texture formats that do not support texture subloading */
425
bool supportsTextureSubloading() const;
348
427
/** Return true if this image is translucent - i.e. it has alpha values that are less 1.0 (when normalized). */
349
428
virtual bool isImageTranslucent() const;
351
/** Set the optional PixelBufferObject used to map the image memory efficiently to graphics memory. */
430
/** Set the optional PixelBufferObject used to map the image memory efficiently to graphics memory. */
352
431
void setPixelBufferObject(PixelBufferObject* buffer) { setBufferObject(buffer); }
354
433
/** Get the PixelBufferObject.*/
355
PixelBufferObject* getPixelBufferObject() { return dynamic_cast<PixelBufferObject*>(_bufferObject.get()); }
434
PixelBufferObject* getPixelBufferObject() { return dynamic_cast<PixelBufferObject*>(getBufferObject()); }
357
436
/** Get the const PixelBufferObject.*/
358
const PixelBufferObject* getPixelBufferObject() const { return dynamic_cast<const PixelBufferObject*>(_bufferObject.get()); }
437
const PixelBufferObject* getPixelBufferObject() const { return dynamic_cast<const PixelBufferObject*>(getBufferObject()); }
360
/** return whether the update(NodeVisitor* nv) should be required on each frame to enable proper working of osg::Image.*/
439
/** Return whether the update(NodeVisitor* nv) should be required on each frame to enable proper working of osg::Image.*/
361
440
virtual bool requiresUpdateCall() const { return false; }
363
442
/** update method for osg::Image subclasses that update themselves during the update traversal.*/
364
443
virtual void update(NodeVisitor* /*nv*/) {}
366
/** convience update callback class that can be attached to StateAttribute (such as Textures) to ensure
445
/** Convenience update callback class that can be attached to a StateAttribute (such as Textures) to ensure
367
446
* that the Image::update(NodeVisitor*) method is called during the update traversal. This callback
368
447
* is automatically attached when Image::requiresUpdateCall() is true (it's false by default.)
372
451
virtual void operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv);
375
/** 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. */
454
/** Hint 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. */
376
455
virtual bool sendFocusHint(bool /*focus*/) { return false; }
378
/** 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. */
457
/** Send pointer events to images that are acting as front ends to interactive surfaces such as a vnc or browser window. Return true if handled. */
379
458
virtual bool sendPointerEvent(int /*x*/, int /*y*/, int /*buttonMask*/) { return false; }
381
/** 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.*/
460
/** Send key events to images that are acting as front ends to interactive surfaces such as a vnc or browser window. Return true if handled.*/
382
461
virtual bool sendKeyEvent(int /*key*/, bool /*keyDown*/) { return false; }
384
/** method for passing frame information to the custom Image classes, to be called only when objects associated with imagery are not culled.*/
463
/** Pass frame information to the custom Image classes, to be called only when objects associated with imagery are not culled.*/
385
464
virtual void setFrameLastRendered(const osg::FrameStamp* /*frameStamp*/) {}
466
class DimensionsChangedCallback : public osg::Referenced {
468
DimensionsChangedCallback() : osg::Referenced() {}
469
virtual void operator()(osg::Image* image) = 0;
472
typedef std::vector< osg::ref_ptr<DimensionsChangedCallback> > DimensionsChangedCallbackVector;
474
void addDimensionsChangedCallback(DimensionsChangedCallback* cb);
475
void removeDimensionsChangedCallback(DimensionsChangedCallback* cb);
389
479
virtual ~Image();
391
481
Image& operator = (const Image&) { return *this; }
483
void handleDimensionsChangedCallbacks()
485
for(DimensionsChangedCallbackVector::iterator i = _dimensionsChangedCallbacks.begin(); i != _dimensionsChangedCallbacks.end(); ++i)
487
(*i)->operator()(this);
393
491
std::string _fileName;
394
492
WriteHint _writeHint;
400
498
GLint _internalTextureFormat;
401
499
GLenum _pixelFormat;
402
500
GLenum _dataType;
406
504
AllocationMode _allocationMode;
407
505
unsigned char* _data;
409
507
void deallocateData();
411
509
void setData(unsigned char* data,AllocationMode allocationMode);
413
511
MipmapDataType _mipmapData;
415
ref_ptr<PixelBufferObject> _bufferObject;
513
DimensionsChangedCallbackVector _dimensionsChangedCallbacks;