2012-03-22 01:36:20 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2003-01-22 00:45:36 +08:00
*
2012-03-22 01:36:20 +08:00
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
2003-01-22 00:45:36 +08:00
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
2012-03-22 01:36:20 +08:00
*
2003-01-22 00:45:36 +08:00
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
2012-03-22 01:36:20 +08:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2003-01-22 00:45:36 +08:00
* OpenSceneGraph Public License for more details.
*/
2001-10-04 23:12:57 +08:00
2001-01-11 00:32:10 +08:00
#ifndef OSG_IMAGE
#define OSG_IMAGE 1
2005-02-09 18:39:45 +08:00
#include <osg/BufferObject>
2007-10-31 20:55:15 +08:00
#include <osg/Vec2>
#include <osg/Vec3>
2017-10-13 22:54:04 +08:00
#include <osg/Vec3i>
2007-10-31 20:55:15 +08:00
#include <osg/Vec4>
2008-07-22 01:28:22 +08:00
#include <osg/FrameStamp>
2010-01-07 20:14:47 +08:00
#include <osg/StateAttribute>
2001-01-11 00:32:10 +08:00
2001-09-20 05:08:56 +08:00
#include <string>
2002-04-23 05:13:33 +08:00
#include <vector>
2001-01-11 00:32:10 +08:00
2002-08-26 21:04:43 +08:00
#ifndef GL_VERSION_1_2
2004-09-13 23:14:11 +08:00
// 1.2 definitions...
2002-08-26 21:04:43 +08:00
#define GL_BGR 0x80E0
#define GL_BGRA 0x80E1
#define GL_UNSIGNED_BYTE_3_3_2 0x8032
#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
#define GL_UNSIGNED_INT_8_8_8_8 0x8035
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
#define GL_UNSIGNED_INT_10_10_10_2 0x8036
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
#endif
2005-01-28 19:01:11 +08:00
#ifndef GL_COMPRESSED_ALPHA
#define GL_COMPRESSED_ALPHA 0x84E9
#define GL_COMPRESSED_LUMINANCE 0x84EA
#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
#define GL_COMPRESSED_INTENSITY 0x84EC
#define GL_COMPRESSED_RGB 0x84ED
#define GL_COMPRESSED_RGBA 0x84EE
#endif
2006-10-15 05:50:29 +08:00
2008-12-06 00:41:12 +08:00
#ifndef GL_ABGR_EXT
#define GL_ABGR_EXT 0x8000
#endif
2010-09-14 21:19:12 +08:00
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
#define GL_RED 0x1903
#define GL_GREEN 0x1904
#define GL_BLUE 0x1905
#define GL_DEPTH_COMPONENT 0x1902
2017-03-15 09:35:58 +08:00
#endif
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE)
2010-09-14 21:19:12 +08:00
#define GL_STENCIL_INDEX 0x1901
#endif
2017-03-15 09:35:58 +08:00
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE) || defined(OSG_GL3_AVAILABLE)
2017-10-06 22:37:50 +08:00
#define GL_ALPHA4 0x803B
#define GL_ALPHA8 0x803C
#define GL_ALPHA12 0x803D
#define GL_ALPHA16 0x803E
2010-09-14 21:19:12 +08:00
#define GL_BITMAP 0x1A00
#define GL_COLOR_INDEX 0x1900
#define GL_INTENSITY12 0x804C
#define GL_INTENSITY16 0x804D
2013-11-18 21:31:44 +08:00
#define GL_INTENSITY 0x8049
2010-09-14 21:19:12 +08:00
#define GL_INTENSITY4 0x804A
#define GL_INTENSITY8 0x804B
#define GL_LUMINANCE12 0x8041
#define GL_LUMINANCE12_ALPHA4 0x8046
#define GL_LUMINANCE12_ALPHA12 0x8047
#define GL_LUMINANCE16 0x8042
#define GL_LUMINANCE16_ALPHA16 0x8048
#define GL_LUMINANCE4 0x803F
#define GL_LUMINANCE4_ALPHA4 0x8043
#define GL_LUMINANCE6_ALPHA2 0x8044
#define GL_LUMINANCE8 0x8040
#define GL_LUMINANCE8_ALPHA8 0x8045
#define GL_RGBA8 0x8058
2012-09-07 22:55:09 +08:00
#define GL_RGBA16 0x805B
2010-09-14 21:19:12 +08:00
#define GL_PACK_ROW_LENGTH 0x0D02
#endif
2010-10-07 00:36:30 +08:00
#ifndef GL_PACK_SKIP_IMAGES
#define GL_PACK_SKIP_IMAGES 0x806B
#define GL_PACK_IMAGE_HEIGHT 0x806C
#define GL_UNPACK_SKIP_IMAGES 0x806D
#define GL_UNPACK_IMAGE_HEIGHT 0x806E
#endif
2012-02-20 20:03:14 +08:00
#ifndef GL_OES_compressed_ETC1_RGB8_texture
2012-03-22 01:36:20 +08:00
#define GL_ETC1_RGB8_OES 0x8D64
2012-02-20 20:03:14 +08:00
#endif
2013-10-28 20:03:55 +08:00
#ifndef GL_ARB_ES3_compatibility
#define GL_COMPRESSED_RGB8_ETC2 0x9274
#define GL_COMPRESSED_SRGB8_ETC2 0x9275
#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
#define GL_COMPRESSED_R11_EAC 0x9270
#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
#define GL_COMPRESSED_RG11_EAC 0x9272
#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
#endif
2017-10-13 22:54:04 +08:00
#ifndef GL_KHR_texture_compression_astc_hdr
#define GL_KHR_texture_compression_astc_hdr 1
#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
#endif /* GL_KHR_texture_compression_astc_hdr */
2013-06-24 17:51:30 +08:00
#ifndef GL_DEPTH_COMPONENT
#define GL_DEPTH_COMPONENT 0x1902
#endif
#ifndef GL_VERSION_1_4
#define GL_DEPTH_COMPONENT16 0x81A5
#define GL_DEPTH_COMPONENT24 0x81A6
#define GL_DEPTH_COMPONENT32 0x81A7
#endif
#ifndef GL_DEPTH_COMPONENT32F
#define GL_DEPTH_COMPONENT32F 0x8CAC
#endif
#ifndef GL_DEPTH_COMPONENT32F_NV
#define GL_DEPTH_COMPONENT32F_NV 0x8DAB
#endif
2001-09-20 05:08:56 +08:00
namespace osg {
2001-01-11 00:32:10 +08:00
2008-07-22 05:00:57 +08:00
// forward declare
class NodeVisitor;
2004-09-13 23:14:11 +08:00
/** Image class for encapsulating the storage texture image data. */
2009-10-02 04:19:42 +08:00
class OSG_EXPORT Image : public BufferData
2001-01-11 00:32:10 +08:00
{
public :
Image();
2012-03-22 01:36:20 +08:00
2004-09-13 23:14:11 +08:00
/** Copy constructor using CopyOp to manage deep vs shallow copy. */
2002-01-29 22:04:06 +08:00
Image(const Image& image,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
2001-01-11 00:32:10 +08:00
2002-12-16 21:40:58 +08:00
virtual Object* cloneType() const { return new Image(); }
virtual Object* clone(const CopyOp& copyop) const { return new Image(*this,copyop); }
2001-09-20 05:08:56 +08:00
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Image*>(obj)!=0; }
2002-06-06 21:25:36 +08:00
virtual const char* libraryName() const { return "osg"; }
2001-01-11 00:32:10 +08:00
virtual const char* className() const { return "Image"; }
2012-01-24 22:34:02 +08:00
virtual osg::Image* asImage() { return this; }
virtual const osg::Image* asImage() const { return this; }
2009-10-02 04:19:42 +08:00
virtual const GLvoid* getDataPointer() const { return data(); }
virtual unsigned int getTotalDataSize() const { return getTotalSizeInBytesIncludingMipmaps(); }
2004-09-13 23:14:11 +08:00
/** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
2003-03-11 21:30:03 +08:00
virtual int compare(const Image& rhs) const;
2001-01-11 00:32:10 +08:00
2001-09-20 05:08:56 +08:00
void setFileName(const std::string& fileName);
2002-04-12 01:15:07 +08:00
inline const std::string& getFileName() const { return _fileName; }
2012-03-22 01:36:20 +08:00
2008-09-10 19:26:30 +08:00
enum WriteHint {
NO_PREFERENCE,
STORE_INLINE,
EXTERNAL_FILE
};
2012-03-22 01:36:20 +08:00
2008-09-10 19:26:30 +08:00
void setWriteHint(WriteHint writeHint) { _writeHint = writeHint; }
WriteHint getWriteHint() const { return _writeHint; }
2012-03-22 01:36:20 +08:00
2003-02-25 19:56:18 +08:00
enum AllocationMode {
NO_DELETE,
USE_NEW_DELETE,
USE_MALLOC_FREE
};
2012-03-22 01:36:20 +08:00
2004-09-13 23:14:11 +08:00
/** Set the method used for deleting data once it goes out of scope. */
2003-02-25 19:56:18 +08:00
void setAllocationMode(AllocationMode mode) { _allocationMode = mode; }
2004-09-13 23:14:11 +08:00
/** Get the method used for deleting data once it goes out of scope. */
2003-09-28 17:23:45 +08:00
AllocationMode getAllocationMode() const { return _allocationMode; }
2003-02-25 19:56:18 +08:00
2004-09-13 23:14:11 +08:00
/** Allocate a pixel block of specified size and type. */
2009-12-08 23:38:50 +08:00
virtual void allocateImage(int s,int t,int r,
2003-09-22 17:13:22 +08:00
GLenum pixelFormat,GLenum type,
2002-08-27 18:06:57 +08:00
int packing=1);
2012-03-22 01:36:20 +08:00
2005-11-25 21:45:23 +08:00
/** Set the image dimensions, format and data. */
2009-12-08 23:38:50 +08:00
virtual void setImage(int s,int t,int r,
2002-04-12 01:15:07 +08:00
GLint internalTextureformat,
2003-09-22 17:13:22 +08:00
GLenum pixelFormat,GLenum type,
2005-05-25 17:50:11 +08:00
unsigned char* data,
2003-02-25 19:56:18 +08:00
AllocationMode mode,
2012-01-24 22:34:02 +08:00
int packing=1, int rowLength=0);
2012-03-22 01:36:20 +08:00
2004-09-13 23:14:11 +08:00
/** Read pixels from current frame buffer at specified position and size, using glReadPixels.
* Create memory for storage if required, reuse existing pixel coords if possible.
2005-01-22 03:31:56 +08:00
*/
2009-12-08 23:38:50 +08:00
virtual void readPixels(int x,int y,int width,int height,
2012-03-29 16:27:21 +08:00
GLenum pixelFormat, GLenum type, int packing=1);
2012-03-22 01:36:20 +08:00
2001-01-11 00:32:10 +08:00
2004-09-13 23:14:11 +08:00
/** Read the contents of the current bound texture, handling compressed pixelFormats if present.
* Create memory for storage if required, reuse existing pixel coords if possible.
2005-01-22 03:31:56 +08:00
*/
2012-03-09 00:05:17 +08:00
virtual void readImageFromCurrentTexture(unsigned int contextID, bool copyMipMapsIfAvailable, GLenum type = GL_UNSIGNED_BYTE, unsigned int face = 0);
2003-04-03 02:26:34 +08:00
2012-11-13 21:16:10 +08:00
/** swap the data and settings between two image objects.*/
void swap(osg::Image& rhs);
2003-04-03 02:26:34 +08:00
2010-10-07 18:51:22 +08:00
/** Scale image to specified size. */
2003-10-30 07:10:11 +08:00
void scaleImage(int s,int t,int r) { scaleImage(s,t,r, getDataType()); }
2010-10-07 18:51:22 +08:00
/** Scale image to specified size and with specified data type. */
2009-12-08 23:38:50 +08:00
virtual void scaleImage(int s,int t,int r, GLenum newDataType);
2002-04-12 01:15:07 +08:00
2002-08-27 18:06:57 +08:00
/** Copy a source Image into a subpart of this Image at specified position.
* Typically used to copy to an already allocated image, such as creating
* a 3D image from a stack 2D images.
2004-09-13 23:14:11 +08:00
* If this Image is empty then image data is created to
2015-06-01 21:40:20 +08:00
* accommodate the source image in its offset position.
2004-09-13 23:14:11 +08:00
* If source is NULL then no operation happens, this Image is left unchanged.
2005-01-22 03:31:56 +08:00
*/
2009-12-08 23:38:50 +08:00
virtual void copySubImage(int s_offset, int t_offset, int r_offset, const osg::Image* source);
2002-04-12 01:15:07 +08:00
2007-06-13 00:55:44 +08:00
2012-03-22 01:36:20 +08:00
enum Origin
2007-06-13 00:55:44 +08:00
{
BOTTOM_LEFT,
TOP_LEFT
};
2012-03-22 01:36:20 +08:00
2007-06-13 00:55:44 +08:00
/** Set the origin of the image.
* The default value is BOTTOM_LEFT and is consistent with OpenGL.
* TOP_LEFT is used for imagery that follows standard Imagery convention, such as movies,
* and hasn't been flipped yet. For such images one much flip the t axis of the tex coords.
* to handle this origin position. */
void setOrigin(Origin origin) { _origin = origin; }
2012-03-22 01:36:20 +08:00
2007-06-13 00:55:44 +08:00
/** Get the origin of the image.*/
Origin getOrigin() const { return _origin; }
2012-03-22 01:36:20 +08:00
2007-06-13 00:55:44 +08:00
2004-09-13 23:14:11 +08:00
/** Width of image. */
2002-09-02 20:31:35 +08:00
inline int s() const { return _s; }
2002-04-12 01:15:07 +08:00
2004-09-13 23:14:11 +08:00
/** Height of image. */
2002-09-02 20:31:35 +08:00
inline int t() const { return _t; }
2012-03-22 01:36:20 +08:00
2004-09-13 23:14:11 +08:00
/** Depth of image. */
2002-09-02 20:31:35 +08:00
inline int r() const { return _r; }
2012-01-24 22:34:02 +08:00
2012-02-10 23:57:51 +08:00
void setRowLength(int length);
2012-01-24 22:34:02 +08:00
inline int getRowLength() const { return _rowLength; }
2012-03-22 01:36:20 +08:00
2002-04-16 22:57:39 +08:00
void setInternalTextureFormat(GLint internalFormat);
2002-09-02 20:31:35 +08:00
inline GLint getInternalTextureFormat() const { return _internalTextureFormat; }
2012-03-22 01:36:20 +08:00
2003-09-22 17:13:22 +08:00
void setPixelFormat(GLenum pixelFormat);
2002-09-02 20:31:35 +08:00
inline GLenum getPixelFormat() const { return _pixelFormat; }
2012-03-22 01:36:20 +08:00
2006-08-25 23:49:29 +08:00
void setDataType(GLenum dataType);
2012-03-22 01:36:20 +08:00
inline GLenum getDataType() const { return _dataType; }
2006-08-25 23:49:29 +08:00
void setPacking(unsigned int packing) { _packing = packing; }
2002-09-02 20:31:35 +08:00
inline unsigned int getPacking() const { return _packing; }
2009-03-11 23:12:46 +08:00
2012-03-29 23:08:15 +08:00
/** Return true of the pixel format is an OpenGL compressed pixel format.*/
2010-10-22 00:29:23 +08:00
bool isCompressed() const;
2009-03-12 01:57:33 +08:00
/** Set the pixel aspect ratio, defined as the pixel width divided by the pixel height.*/
2009-03-11 23:12:46 +08:00
inline void setPixelAspectRatio(float pixelAspectRatio) { _pixelAspectRatio = pixelAspectRatio; }
2009-03-12 01:57:33 +08:00
/** Get the pixel aspect ratio.*/
2009-03-11 23:12:46 +08:00
inline float getPixelAspectRatio() const { return _pixelAspectRatio; }
2012-03-22 01:36:20 +08:00
2004-09-13 23:14:11 +08:00
/** Return the number of bits required for each pixel. */
2002-09-02 20:31:35 +08:00
inline unsigned int getPixelSizeInBits() const { return computePixelSizeInBits(_pixelFormat,_dataType); }
2002-04-12 01:15:07 +08:00
2004-09-13 23:14:11 +08:00
/** Return the number of bytes each row of pixels occupies once it has been packed. */
2002-09-02 20:31:35 +08:00
inline unsigned int getRowSizeInBytes() const { return computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing); }
2002-04-12 01:15:07 +08:00
2012-01-24 22:34:02 +08:00
/** Return the number of bytes between each successive row.
* Note, getRowSizeInBytes() will only equal getRowStepInBytes() when isDataContiguous() return true. */
inline unsigned int getRowStepInBytes() const { return computeRowWidthInBytes(_rowLength==0?_s:_rowLength,_pixelFormat,_dataType,_packing); }
2004-09-13 23:14:11 +08:00
/** Return the number of bytes each image (_s*_t) of pixels occupies. */
2002-09-02 20:31:35 +08:00
inline unsigned int getImageSizeInBytes() const { return getRowSizeInBytes()*_t; }
2012-03-22 01:36:20 +08:00
/** Return the number of bytes between each successive image.
2012-01-24 22:34:02 +08:00
* Note, getImageSizeInBytes() will only equal getImageStepInBytes() when isDataContiguous() return true. */
inline unsigned int getImageStepInBytes() const { return getRowStepInBytes()*_t; }
2004-09-13 23:14:11 +08:00
/** Return the number of bytes the whole row/image/volume of pixels occupies. */
2002-09-02 20:31:35 +08:00
inline unsigned int getTotalSizeInBytes() const { return getImageSizeInBytes()*_r; }
2002-04-12 01:15:07 +08:00
2004-09-13 23:14:11 +08:00
/** Return the number of bytes the whole row/image/volume of pixels occupies, including all mip maps if included. */
2003-06-24 23:40:09 +08:00
unsigned int getTotalSizeInBytesIncludingMipmaps() const;
2005-04-22 23:43:34 +08:00
/** Return true if the Image represent a valid and usable imagery.*/
bool valid() const { return _s!=0 && _t!=0 && _r!=0 && _data!=0 && _dataType!=0; }
2012-01-24 22:34:02 +08:00
/** Raw image data.
* Note, data in successive rows may not be contiguous, isDataContiguous() return false then you should
* take care to access the data per row rather than treating the whole data as a single block. */
2005-05-25 17:50:11 +08:00
inline unsigned char* data() { return _data; }
2012-03-22 01:36:20 +08:00
2012-01-24 22:34:02 +08:00
/** Raw const image data.
* Note, data in successive rows may not be contiguous, isDataContiguous() return false then you should
* take care to access the data per row rather than treating the whole data as a single block. */
2005-05-25 17:50:11 +08:00
inline const unsigned char* data() const { return _data; }
2001-09-20 05:08:56 +08:00
2014-06-30 16:46:54 +08:00
inline unsigned char* data(unsigned int column, unsigned int row = 0, unsigned int image = 0)
2002-04-12 01:15:07 +08:00
{
if (!_data) return NULL;
2012-01-24 22:34:02 +08:00
return _data+(column*getPixelSizeInBits())/8+row*getRowStepInBytes()+image*getImageSizeInBytes();
2002-04-12 01:15:07 +08:00
}
2012-03-22 01:36:20 +08:00
2014-06-30 16:46:54 +08:00
inline const unsigned char* data(unsigned int column, unsigned int row = 0, unsigned int image = 0) const
2002-08-16 23:14:43 +08:00
{
if (!_data) return NULL;
2012-01-24 22:34:02 +08:00
return _data+(column*getPixelSizeInBits())/8+row*getRowStepInBytes()+image*getImageSizeInBytes();
2002-08-16 23:14:43 +08:00
}
2012-01-24 22:34:02 +08:00
/** return true if the data stored in the image is a contiguous block of data.*/
bool isDataContiguous() const { return _rowLength==0 || _rowLength==_s; }
/** Convenience class for assisting the copying of image data when the image data isn't contiguous.*/
class OSG_EXPORT DataIterator
{
public:
DataIterator(const Image* image);
DataIterator(const DataIterator& ri);
~DataIterator() {}
/** advance iterator to next block of data.*/
void operator ++ ();
/** is iterator valid.*/
bool valid() const { return _currentPtr!=0; }
/** data pointer of current block to copy.*/
const unsigned char* data() const { return _currentPtr; }
/** Size of current block to copy.*/
unsigned int size() const { return _currentSize; }
protected:
2012-03-22 01:36:20 +08:00
2012-01-24 22:34:02 +08:00
void assign();
2012-03-22 01:36:20 +08:00
2012-01-24 22:34:02 +08:00
const osg::Image* _image;
int _rowNum;
int _imageNum;
unsigned int _mipmapNum;
const unsigned char* _currentPtr;
unsigned int _currentSize;
};
2007-10-31 20:55:15 +08:00
/** Get the color value for specified texcoord.*/
Vec4 getColor(unsigned int s,unsigned t=0,unsigned r=0) const;
/** Get the color value for specified texcoord.*/
Vec4 getColor(const Vec2& texcoord) const { return getColor(Vec3(texcoord.x(),texcoord.y(),0.0f)); }
/** Get the color value for specified texcoord.*/
Vec4 getColor(const Vec3& texcoord) const;
2014-11-22 00:27:29 +08:00
/** Set the color value for specified texcoord.*/
void setColor(const osg::Vec4& color, unsigned int s, unsigned int t=0, unsigned int r=0);
2014-11-22 04:15:30 +08:00
/** Set the color value for specified texcoord. Note texcoord is clamped to edge.*/
2014-11-22 00:27:29 +08:00
void setColor(const osg::Vec4& color, const osg::Vec2& texcoord ) { setColor(color, osg::Vec3(texcoord, 0.0f)); }
2014-11-22 04:15:30 +08:00
/** Set the color value for specified texcoord. Note texcoord is clamped to edge.*/
2014-11-22 00:27:29 +08:00
void setColor(const osg::Vec4& color, const osg::Vec3& texcoord );
2005-02-09 18:39:45 +08:00
2011-10-21 18:59:42 +08:00
/** Flip the image horizontally, around s dimension. */
2004-08-17 04:57:24 +08:00
void flipHorizontal();
2012-03-22 01:36:20 +08:00
2011-10-21 18:59:42 +08:00
/** Flip the image vertically, around t dimension. */
2004-08-17 04:57:24 +08:00
void flipVertical();
2002-04-12 01:15:07 +08:00
2015-04-08 02:01:12 +08:00
/** Flip the image around the r dimension. Only relevant for 3D textures. */
2011-10-21 18:59:42 +08:00
void flipDepth();
2001-01-11 00:32:10 +08:00
/** Ensure image dimensions are a power of two.
2004-09-13 23:14:11 +08:00
* Mipmapped textures require the image dimensions to be
2018-04-21 00:18:22 +08:00
* power of two and are within the maximum texture size for
2004-09-13 23:14:11 +08:00
* the host machine.
2005-01-22 03:31:56 +08:00
*/
2002-09-17 04:58:05 +08:00
void ensureValidSizeForTexturing(GLint maxTextureSize);
2002-04-12 01:15:07 +08:00
2002-09-02 20:31:35 +08:00
static bool isPackedType(GLenum type);
2006-10-15 05:50:29 +08:00
static GLenum computePixelFormat(GLenum pixelFormat);
2008-11-30 23:56:47 +08:00
static GLenum computeFormatDataType(GLenum pixelFormat);
2017-10-13 22:54:04 +08:00
/** return the dimensions of a block of compressed pixels */
static osg::Vec3i computeBlockFootprint(GLenum pixelFormat);
/** return the size in bytes of a block of compressed pixels */
2012-01-24 22:34:02 +08:00
static unsigned int computeBlockSize(GLenum pixelFormat, GLenum packing);
2003-09-22 17:13:22 +08:00
static unsigned int computeNumComponents(GLenum pixelFormat);
static unsigned int computePixelSizeInBits(GLenum pixelFormat,GLenum type);
static unsigned int computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing);
2013-05-28 22:14:45 +08:00
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);
2017-10-13 22:54:04 +08:00
static int roudUpToMultiple(int s, int pack);
2003-04-01 19:49:09 +08:00
static int computeNearestPowerOfTwo(int s,float bias=0.5f);
2007-10-01 16:50:58 +08:00
static int computeNumberOfMipmapLevels(int s,int t = 1, int r = 1);
2010-10-22 00:29:23 +08:00
2004-09-13 23:14:11 +08:00
/** Precomputed mipmaps stuff. */
2002-04-23 18:34:20 +08:00
typedef std::vector< unsigned int > MipmapDataType;
2002-04-12 01:15:07 +08:00
2002-04-23 05:13:33 +08:00
inline bool isMipmap() const {return !_mipmapData.empty();};
2002-08-16 21:33:32 +08:00
unsigned int getNumMipmapLevels() const
2002-04-23 05:13:33 +08:00
{
2009-01-30 18:55:28 +08:00
return static_cast<unsigned int>(_mipmapData.size())+1;
2002-04-23 05:13:33 +08:00
};
2004-09-13 23:14:11 +08:00
/** Send offsets into data. It is assumed that first mipmap offset (index 0) is 0.*/
2004-12-17 09:06:33 +08:00
inline void setMipmapLevels(const MipmapDataType& mipmapDataVector) { _mipmapData = mipmapDataVector; }
2012-03-22 01:36:20 +08:00
2004-12-17 09:06:33 +08:00
inline const MipmapDataType& getMipmapLevels() const { return _mipmapData; }
inline unsigned int getMipmapOffset(unsigned int mipmapLevel) const
2002-04-23 05:13:33 +08:00
{
2004-12-17 09:06:33 +08:00
if(mipmapLevel == 0)
return 0;
else if (mipmapLevel < getNumMipmapLevels())
return _mipmapData[mipmapLevel-1];
return 0;
2002-04-23 05:13:33 +08:00
};
2012-03-22 01:36:20 +08:00
2004-12-17 09:06:33 +08:00
inline unsigned char* getMipmapData(unsigned int mipmapLevel)
2005-01-22 03:31:56 +08:00
{
return _data+getMipmapOffset(mipmapLevel);
}
2004-12-17 09:06:33 +08:00
inline const unsigned char* getMipmapData(unsigned int mipmapLevel) const
2005-01-22 03:31:56 +08:00
{
return _data+getMipmapOffset(mipmapLevel);
}
2008-11-30 23:56:47 +08:00
2012-02-20 20:03:14 +08:00
/** returns false for texture formats that do not support texture subloading */
bool supportsTextureSubloading() const;
2004-09-13 23:14:11 +08:00
/** Return true if this image is translucent - i.e. it has alpha values that are less 1.0 (when normalized). */
2009-03-11 00:52:18 +08:00
virtual bool isImageTranslucent() const;
2002-04-12 01:15:07 +08:00
2012-03-22 01:36:20 +08:00
/** Set the optional PixelBufferObject used to map the image memory efficiently to graphics memory. */
2009-10-02 04:19:42 +08:00
void setPixelBufferObject(PixelBufferObject* buffer) { setBufferObject(buffer); }
2005-02-09 18:39:45 +08:00
2009-10-02 04:19:42 +08:00
/** Get the PixelBufferObject.*/
2012-12-14 01:35:27 +08:00
PixelBufferObject* getPixelBufferObject() { return dynamic_cast<PixelBufferObject*>(getBufferObject()); }
2005-02-09 18:39:45 +08:00
2009-10-02 04:19:42 +08:00
/** Get the const PixelBufferObject.*/
2012-12-14 01:35:27 +08:00
const PixelBufferObject* getPixelBufferObject() const { return dynamic_cast<const PixelBufferObject*>(getBufferObject()); }
2010-01-07 20:14:47 +08:00
2012-03-29 23:08:15 +08:00
/** Return whether the update(NodeVisitor* nv) should be required on each frame to enable proper working of osg::Image.*/
2010-01-07 20:14:47 +08:00
virtual bool requiresUpdateCall() const { return false; }
/** update method for osg::Image subclasses that update themselves during the update traversal.*/
2009-10-02 04:19:42 +08:00
virtual void update(NodeVisitor* /*nv*/) {}
2008-11-03 23:08:04 +08:00
2012-03-29 23:08:15 +08:00
/** Convenience update callback class that can be attached to a StateAttribute (such as Textures) to ensure
2010-01-07 20:14:47 +08:00
* that the Image::update(NodeVisitor*) method is called during the update traversal. This callback
* is automatically attached when Image::requiresUpdateCall() is true (it's false by default.)
*/
struct OSG_EXPORT UpdateCallback : public osg::StateAttributeCallback
{
virtual void operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv);
};
2012-03-29 23:08:15 +08:00
/** 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. */
2010-11-25 20:07:59 +08:00
virtual bool sendFocusHint(bool /*focus*/) { return false; }
2010-05-22 23:45:02 +08:00
2012-03-29 23:08:15 +08:00
/** 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. */
2008-12-18 19:06:57 +08:00
virtual bool sendPointerEvent(int /*x*/, int /*y*/, int /*buttonMask*/) { return false; }
2008-11-03 23:08:04 +08:00
2012-03-29 23:08:15 +08:00
/** 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.*/
2008-12-18 19:06:57 +08:00
virtual bool sendKeyEvent(int /*key*/, bool /*keyDown*/) { return false; }
2008-11-03 23:08:04 +08:00
2012-03-29 23:08:15 +08:00
/** Pass frame information to the custom Image classes, to be called only when objects associated with imagery are not culled.*/
2008-12-18 19:06:57 +08:00
virtual void setFrameLastRendered(const osg::FrameStamp* /*frameStamp*/) {}
2014-11-22 00:27:29 +08:00
2012-10-02 22:07:12 +08:00
class DimensionsChangedCallback : public osg::Referenced {
public:
DimensionsChangedCallback() : osg::Referenced() {}
virtual void operator()(osg::Image* image) = 0;
};
2014-11-22 00:27:29 +08:00
2012-10-02 22:07:12 +08:00
typedef std::vector< osg::ref_ptr<DimensionsChangedCallback> > DimensionsChangedCallbackVector;
2014-11-22 00:27:29 +08:00
2012-10-02 22:07:12 +08:00
void addDimensionsChangedCallback(DimensionsChangedCallback* cb);
void removeDimensionsChangedCallback(DimensionsChangedCallback* cb);
2008-11-03 23:08:04 +08:00
2001-01-11 00:32:10 +08:00
protected :
virtual ~Image();
2002-01-31 00:24:24 +08:00
Image& operator = (const Image&) { return *this; }
2014-11-22 00:27:29 +08:00
void handleDimensionsChangedCallbacks()
2012-10-02 22:07:12 +08:00
{
for(DimensionsChangedCallbackVector::iterator i = _dimensionsChangedCallbacks.begin(); i != _dimensionsChangedCallbacks.end(); ++i)
{
(*i)->operator()(this);
}
}
2001-01-11 00:32:10 +08:00
2001-09-20 05:08:56 +08:00
std::string _fileName;
2008-09-10 19:26:30 +08:00
WriteHint _writeHint;
2007-06-13 00:55:44 +08:00
Origin _origin;
2001-01-11 00:32:10 +08:00
int _s, _t, _r;
2012-01-24 22:34:02 +08:00
int _rowLength;
2002-04-12 01:15:07 +08:00
GLint _internalTextureFormat;
GLenum _pixelFormat;
GLenum _dataType;
2001-01-11 00:32:10 +08:00
unsigned int _packing;
2009-03-11 23:12:46 +08:00
float _pixelAspectRatio;
2003-02-25 19:56:18 +08:00
AllocationMode _allocationMode;
2005-05-25 17:50:11 +08:00
unsigned char* _data;
2012-03-22 01:36:20 +08:00
2003-02-25 19:56:18 +08:00
void deallocateData();
2012-03-22 01:36:20 +08:00
2005-05-25 17:50:11 +08:00
void setData(unsigned char* data,AllocationMode allocationMode);
2001-01-11 00:32:10 +08:00
2002-04-23 05:13:33 +08:00
MipmapDataType _mipmapData;
2014-11-22 00:27:29 +08:00
2012-10-02 22:07:12 +08:00
DimensionsChangedCallbackVector _dimensionsChangedCallbacks;
2001-01-11 00:32:10 +08:00
};
class Geode;
2004-09-13 23:14:11 +08:00
/** Convenience function to be used by image loaders to generate a valid geode
* to return for readNode().
* Use the image's s and t values to scale the dimensions of the image.
*/
2005-04-12 01:14:17 +08:00
extern OSG_EXPORT Geode* createGeodeForImage(Image* image);
2015-10-22 21:42:19 +08:00
template<class T> Geode* createGeodeForImage(const ref_ptr<T>& image) { return createGeodeForImage(image.get()); }
2004-09-13 23:14:11 +08:00
/** Convenience function to be used by image loaders to generate a valid geode
* to return for readNode().
* Use the specified s and t values to scale the dimensions of the image.
*/
2015-10-22 21:42:19 +08:00
extern OSG_EXPORT Geode* createGeodeForImage(Image* image, float s, float t);
template<class T> Geode* createGeodeForImage(const ref_ptr<T>& image, float s, float t) { return createGeodeForImage(image.get(), s, t); }
2001-01-11 00:32:10 +08:00
2002-02-03 20:33:41 +08:00
}
2001-01-11 00:32:10 +08:00
#endif // __SG_IMAGE_H