Image 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  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. #ifndef OSG_IMAGE
  14. #define OSG_IMAGE 1
  15. #include <osg/BufferObject>
  16. #include <osg/Vec2>
  17. #include <osg/Vec3>
  18. #include <osg/Vec3i>
  19. #include <osg/Vec4>
  20. #include <osg/FrameStamp>
  21. #include <osg/StateAttribute>
  22. #include <string>
  23. #include <vector>
  24. #ifndef GL_VERSION_1_2
  25. // 1.2 definitions...
  26. #define GL_BGR 0x80E0
  27. #define GL_BGRA 0x80E1
  28. #define GL_UNSIGNED_BYTE_3_3_2 0x8032
  29. #define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
  30. #define GL_UNSIGNED_SHORT_5_6_5 0x8363
  31. #define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
  32. #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
  33. #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
  34. #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
  35. #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
  36. #define GL_UNSIGNED_INT_8_8_8_8 0x8035
  37. #define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
  38. #define GL_UNSIGNED_INT_10_10_10_2 0x8036
  39. #define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
  40. #endif
  41. #ifndef GL_COMPRESSED_ALPHA
  42. #define GL_COMPRESSED_ALPHA 0x84E9
  43. #define GL_COMPRESSED_LUMINANCE 0x84EA
  44. #define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
  45. #define GL_COMPRESSED_INTENSITY 0x84EC
  46. #define GL_COMPRESSED_RGB 0x84ED
  47. #define GL_COMPRESSED_RGBA 0x84EE
  48. #endif
  49. #ifndef GL_ABGR_EXT
  50. #define GL_ABGR_EXT 0x8000
  51. #endif
  52. #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
  53. #define GL_RED 0x1903
  54. #define GL_GREEN 0x1904
  55. #define GL_BLUE 0x1905
  56. #define GL_DEPTH_COMPONENT 0x1902
  57. #endif
  58. #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE)
  59. #define GL_STENCIL_INDEX 0x1901
  60. #endif
  61. #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE) || defined(OSG_GL3_AVAILABLE)
  62. #define GL_ALPHA4 0x803B
  63. #define GL_ALPHA8 0x803C
  64. #define GL_ALPHA12 0x803D
  65. #define GL_ALPHA16 0x803E
  66. #define GL_BITMAP 0x1A00
  67. #define GL_COLOR_INDEX 0x1900
  68. #define GL_INTENSITY12 0x804C
  69. #define GL_INTENSITY16 0x804D
  70. #define GL_INTENSITY 0x8049
  71. #define GL_INTENSITY4 0x804A
  72. #define GL_INTENSITY8 0x804B
  73. #define GL_LUMINANCE12 0x8041
  74. #define GL_LUMINANCE12_ALPHA4 0x8046
  75. #define GL_LUMINANCE12_ALPHA12 0x8047
  76. #define GL_LUMINANCE16 0x8042
  77. #define GL_LUMINANCE16_ALPHA16 0x8048
  78. #define GL_LUMINANCE4 0x803F
  79. #define GL_LUMINANCE4_ALPHA4 0x8043
  80. #define GL_LUMINANCE6_ALPHA2 0x8044
  81. #define GL_LUMINANCE8 0x8040
  82. #define GL_LUMINANCE8_ALPHA8 0x8045
  83. #define GL_RGBA8 0x8058
  84. #define GL_RGBA16 0x805B
  85. #define GL_PACK_ROW_LENGTH 0x0D02
  86. #endif
  87. #ifndef GL_PACK_SKIP_IMAGES
  88. #define GL_PACK_SKIP_IMAGES 0x806B
  89. #define GL_PACK_IMAGE_HEIGHT 0x806C
  90. #define GL_UNPACK_SKIP_IMAGES 0x806D
  91. #define GL_UNPACK_IMAGE_HEIGHT 0x806E
  92. #endif
  93. #ifndef GL_OES_compressed_ETC1_RGB8_texture
  94. #define GL_ETC1_RGB8_OES 0x8D64
  95. #endif
  96. #ifndef GL_ARB_ES3_compatibility
  97. #define GL_COMPRESSED_RGB8_ETC2 0x9274
  98. #define GL_COMPRESSED_SRGB8_ETC2 0x9275
  99. #define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
  100. #define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
  101. #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
  102. #define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
  103. #define GL_COMPRESSED_R11_EAC 0x9270
  104. #define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
  105. #define GL_COMPRESSED_RG11_EAC 0x9272
  106. #define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
  107. #endif
  108. #ifndef GL_KHR_texture_compression_astc_hdr
  109. #define GL_KHR_texture_compression_astc_hdr 1
  110. #define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
  111. #define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
  112. #define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
  113. #define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
  114. #define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
  115. #define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
  116. #define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
  117. #define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
  118. #define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
  119. #define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
  120. #define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
  121. #define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
  122. #define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
  123. #define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
  124. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
  125. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
  126. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
  127. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
  128. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
  129. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
  130. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
  131. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
  132. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
  133. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
  134. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
  135. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
  136. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
  137. #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
  138. #endif /* GL_KHR_texture_compression_astc_hdr */
  139. #ifndef GL_DEPTH_COMPONENT
  140. #define GL_DEPTH_COMPONENT 0x1902
  141. #endif
  142. #ifndef GL_VERSION_1_4
  143. #define GL_DEPTH_COMPONENT16 0x81A5
  144. #define GL_DEPTH_COMPONENT24 0x81A6
  145. #define GL_DEPTH_COMPONENT32 0x81A7
  146. #endif
  147. #ifndef GL_DEPTH_COMPONENT32F
  148. #define GL_DEPTH_COMPONENT32F 0x8CAC
  149. #endif
  150. #ifndef GL_DEPTH_COMPONENT32F_NV
  151. #define GL_DEPTH_COMPONENT32F_NV 0x8DAB
  152. #endif
  153. namespace osg {
  154. // forward declare
  155. class NodeVisitor;
  156. /** Image class for encapsulating the storage texture image data. */
  157. class OSG_EXPORT Image : public BufferData
  158. {
  159. public :
  160. Image();
  161. /** Copy constructor using CopyOp to manage deep vs shallow copy. */
  162. Image(const Image& image,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
  163. virtual Object* cloneType() const { return new Image(); }
  164. virtual Object* clone(const CopyOp& copyop) const { return new Image(*this,copyop); }
  165. virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Image*>(obj)!=0; }
  166. virtual const char* libraryName() const { return "osg"; }
  167. virtual const char* className() const { return "Image"; }
  168. virtual osg::Image* asImage() { return this; }
  169. virtual const osg::Image* asImage() const { return this; }
  170. virtual const GLvoid* getDataPointer() const { return data(); }
  171. virtual unsigned int getTotalDataSize() const { return getTotalSizeInBytesIncludingMipmaps(); }
  172. /** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
  173. virtual int compare(const Image& rhs) const;
  174. void setFileName(const std::string& fileName);
  175. inline const std::string& getFileName() const { return _fileName; }
  176. enum WriteHint {
  177. NO_PREFERENCE,
  178. STORE_INLINE,
  179. EXTERNAL_FILE
  180. };
  181. void setWriteHint(WriteHint writeHint) { _writeHint = writeHint; }
  182. WriteHint getWriteHint() const { return _writeHint; }
  183. enum AllocationMode {
  184. NO_DELETE,
  185. USE_NEW_DELETE,
  186. USE_MALLOC_FREE
  187. };
  188. /** Set the method used for deleting data once it goes out of scope. */
  189. void setAllocationMode(AllocationMode mode) { _allocationMode = mode; }
  190. /** Get the method used for deleting data once it goes out of scope. */
  191. AllocationMode getAllocationMode() const { return _allocationMode; }
  192. /** Allocate a pixel block of specified size and type. */
  193. virtual void allocateImage(int s,int t,int r,
  194. GLenum pixelFormat,GLenum type,
  195. int packing=1);
  196. /** Set the image dimensions, format and data. */
  197. virtual void setImage(int s,int t,int r,
  198. GLint internalTextureformat,
  199. GLenum pixelFormat,GLenum type,
  200. unsigned char* data,
  201. AllocationMode mode,
  202. int packing=1, int rowLength=0);
  203. /** Read pixels from current frame buffer at specified position and size, using glReadPixels.
  204. * Create memory for storage if required, reuse existing pixel coords if possible.
  205. */
  206. virtual void readPixels(int x,int y,int width,int height,
  207. GLenum pixelFormat, GLenum type, int packing=1);
  208. /** Read the contents of the current bound texture, handling compressed pixelFormats if present.
  209. * Create memory for storage if required, reuse existing pixel coords if possible.
  210. */
  211. virtual void readImageFromCurrentTexture(unsigned int contextID, bool copyMipMapsIfAvailable, GLenum type = GL_UNSIGNED_BYTE, unsigned int face = 0);
  212. /** swap the data and settings between two image objects.*/
  213. void swap(osg::Image& rhs);
  214. /** Scale image to specified size. */
  215. void scaleImage(int s,int t,int r) { scaleImage(s,t,r, getDataType()); }
  216. /** Scale image to specified size and with specified data type. */
  217. virtual void scaleImage(int s,int t,int r, GLenum newDataType);
  218. /** Copy a source Image into a subpart of this Image at specified position.
  219. * Typically used to copy to an already allocated image, such as creating
  220. * a 3D image from a stack 2D images.
  221. * If this Image is empty then image data is created to
  222. * accommodate the source image in its offset position.
  223. * If source is NULL then no operation happens, this Image is left unchanged.
  224. */
  225. virtual void copySubImage(int s_offset, int t_offset, int r_offset, const osg::Image* source);
  226. enum Origin
  227. {
  228. BOTTOM_LEFT,
  229. TOP_LEFT
  230. };
  231. /** Set the origin of the image.
  232. * The default value is BOTTOM_LEFT and is consistent with OpenGL.
  233. * TOP_LEFT is used for imagery that follows standard Imagery convention, such as movies,
  234. * and hasn't been flipped yet. For such images one much flip the t axis of the tex coords.
  235. * to handle this origin position. */
  236. void setOrigin(Origin origin) { _origin = origin; }
  237. /** Get the origin of the image.*/
  238. Origin getOrigin() const { return _origin; }
  239. /** Width of image. */
  240. inline int s() const { return _s; }
  241. /** Height of image. */
  242. inline int t() const { return _t; }
  243. /** Depth of image. */
  244. inline int r() const { return _r; }
  245. void setRowLength(int length);
  246. inline int getRowLength() const { return _rowLength; }
  247. void setInternalTextureFormat(GLint internalFormat);
  248. inline GLint getInternalTextureFormat() const { return _internalTextureFormat; }
  249. void setPixelFormat(GLenum pixelFormat);
  250. inline GLenum getPixelFormat() const { return _pixelFormat; }
  251. void setDataType(GLenum dataType);
  252. inline GLenum getDataType() const { return _dataType; }
  253. void setPacking(unsigned int packing) { _packing = packing; }
  254. inline unsigned int getPacking() const { return _packing; }
  255. /** Return true of the pixel format is an OpenGL compressed pixel format.*/
  256. bool isCompressed() const;
  257. /** Set the pixel aspect ratio, defined as the pixel width divided by the pixel height.*/
  258. inline void setPixelAspectRatio(float pixelAspectRatio) { _pixelAspectRatio = pixelAspectRatio; }
  259. /** Get the pixel aspect ratio.*/
  260. inline float getPixelAspectRatio() const { return _pixelAspectRatio; }
  261. /** Return the number of bits required for each pixel. */
  262. inline unsigned int getPixelSizeInBits() const { return computePixelSizeInBits(_pixelFormat,_dataType); }
  263. /** Return the number of bytes each row of pixels occupies once it has been packed. */
  264. inline unsigned int getRowSizeInBytes() const { return computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing); }
  265. /** Return the number of bytes between each successive row.
  266. * Note, getRowSizeInBytes() will only equal getRowStepInBytes() when isDataContiguous() return true. */
  267. inline unsigned int getRowStepInBytes() const { return computeRowWidthInBytes(_rowLength==0?_s:_rowLength,_pixelFormat,_dataType,_packing); }
  268. /** Return the number of bytes each image (_s*_t) of pixels occupies. */
  269. inline unsigned int getImageSizeInBytes() const { return getRowSizeInBytes()*_t; }
  270. /** Return the number of bytes between each successive image.
  271. * Note, getImageSizeInBytes() will only equal getImageStepInBytes() when isDataContiguous() return true. */
  272. inline unsigned int getImageStepInBytes() const { return getRowStepInBytes()*_t; }
  273. /** Return the number of bytes the whole row/image/volume of pixels occupies. */
  274. inline unsigned int getTotalSizeInBytes() const { return getImageSizeInBytes()*_r; }
  275. /** Return the number of bytes the whole row/image/volume of pixels occupies, including all mip maps if included. */
  276. unsigned int getTotalSizeInBytesIncludingMipmaps() const;
  277. /** Return true if the Image represent a valid and usable imagery.*/
  278. bool valid() const { return _s!=0 && _t!=0 && _r!=0 && _data!=0 && _dataType!=0; }
  279. /** Raw 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 unsigned char* data() { return _data; }
  283. /** Raw const image data.
  284. * Note, data in successive rows may not be contiguous, isDataContiguous() return false then you should
  285. * take care to access the data per row rather than treating the whole data as a single block. */
  286. inline const unsigned char* data() const { return _data; }
  287. inline unsigned char* data(unsigned int column, unsigned int row = 0, unsigned int image = 0)
  288. {
  289. if (!_data) return NULL;
  290. return _data+(column*getPixelSizeInBits())/8+row*getRowStepInBytes()+image*getImageSizeInBytes();
  291. }
  292. inline const unsigned char* data(unsigned int column, unsigned int row = 0, unsigned int image = 0) const
  293. {
  294. if (!_data) return NULL;
  295. return _data+(column*getPixelSizeInBits())/8+row*getRowStepInBytes()+image*getImageSizeInBytes();
  296. }
  297. /** return true if the data stored in the image is a contiguous block of data.*/
  298. bool isDataContiguous() const { return _rowLength==0 || _rowLength==_s; }
  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. /** advance iterator to next block of data.*/
  307. void operator ++ ();
  308. /** is iterator valid.*/
  309. bool valid() const { return _currentPtr!=0; }
  310. /** data pointer of current block to copy.*/
  311. const unsigned char* data() const { return _currentPtr; }
  312. /** Size of current block to copy.*/
  313. unsigned int size() const { return _currentSize; }
  314. protected:
  315. void assign();
  316. const osg::Image* _image;
  317. int _rowNum;
  318. int _imageNum;
  319. unsigned int _mipmapNum;
  320. const unsigned char* _currentPtr;
  321. unsigned int _currentSize;
  322. };
  323. /** Get the color value for specified texcoord.*/
  324. Vec4 getColor(unsigned int s,unsigned t=0,unsigned r=0) const;
  325. /** Get the color value for specified texcoord.*/
  326. Vec4 getColor(const Vec2& texcoord) const { return getColor(Vec3(texcoord.x(),texcoord.y(),0.0f)); }
  327. /** Get the color value for specified texcoord.*/
  328. Vec4 getColor(const Vec3& texcoord) const;
  329. /** Set the color value for specified texcoord.*/
  330. void setColor(const osg::Vec4& color, unsigned int s, unsigned int t=0, unsigned int r=0);
  331. /** Set the color value for specified texcoord. Note texcoord is clamped to edge.*/
  332. void setColor(const osg::Vec4& color, const osg::Vec2& texcoord ) { setColor(color, osg::Vec3(texcoord, 0.0f)); }
  333. /** Set the color value for specified texcoord. Note texcoord is clamped to edge.*/
  334. void setColor(const osg::Vec4& color, const osg::Vec3& texcoord );
  335. /** Flip the image horizontally, around s dimension. */
  336. void flipHorizontal();
  337. /** Flip the image vertically, around t dimension. */
  338. void flipVertical();
  339. /** Flip the image around the r dimension. Only relevant for 3D textures. */
  340. void flipDepth();
  341. /** Ensure image dimensions are a power of two.
  342. * Mipmapped textures require the image dimensions to be
  343. * power of two and are within the maximum texture size for
  344. * the host machine.
  345. */
  346. void ensureValidSizeForTexturing(GLint maxTextureSize);
  347. static bool isPackedType(GLenum type);
  348. static GLenum computePixelFormat(GLenum pixelFormat);
  349. static GLenum computeFormatDataType(GLenum pixelFormat);
  350. /** return the dimensions of a block of compressed pixels */
  351. static osg::Vec3i computeBlockFootprint(GLenum pixelFormat);
  352. /** return the size in bytes of a block of compressed pixels */
  353. static unsigned int computeBlockSize(GLenum pixelFormat, GLenum packing);
  354. static unsigned int computeNumComponents(GLenum pixelFormat);
  355. static unsigned int computePixelSizeInBits(GLenum pixelFormat,GLenum type);
  356. static unsigned int computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing);
  357. 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);
  358. static int roudUpToMultiple(int s, int pack);
  359. static int computeNearestPowerOfTwo(int s,float bias=0.5f);
  360. static int computeNumberOfMipmapLevels(int s,int t = 1, int r = 1);
  361. /** Precomputed mipmaps stuff. */
  362. typedef std::vector< unsigned int > MipmapDataType;
  363. inline bool isMipmap() const {return !_mipmapData.empty();};
  364. unsigned int getNumMipmapLevels() const
  365. {
  366. return static_cast<unsigned int>(_mipmapData.size())+1;
  367. };
  368. /** Send offsets into data. It is assumed that first mipmap offset (index 0) is 0.*/
  369. inline void setMipmapLevels(const MipmapDataType& mipmapDataVector) { _mipmapData = mipmapDataVector; }
  370. inline const MipmapDataType& getMipmapLevels() const { return _mipmapData; }
  371. inline unsigned int getMipmapOffset(unsigned int mipmapLevel) const
  372. {
  373. if(mipmapLevel == 0)
  374. return 0;
  375. else if (mipmapLevel < getNumMipmapLevels())
  376. return _mipmapData[mipmapLevel-1];
  377. return 0;
  378. };
  379. inline unsigned char* getMipmapData(unsigned int mipmapLevel)
  380. {
  381. return _data+getMipmapOffset(mipmapLevel);
  382. }
  383. inline const unsigned char* getMipmapData(unsigned int mipmapLevel) const
  384. {
  385. return _data+getMipmapOffset(mipmapLevel);
  386. }
  387. /** returns false for texture formats that do not support texture subloading */
  388. bool supportsTextureSubloading() const;
  389. /** Return true if this image is translucent - i.e. it has alpha values that are less 1.0 (when normalized). */
  390. virtual bool isImageTranslucent() const;
  391. /** Set the optional PixelBufferObject used to map the image memory efficiently to graphics memory. */
  392. void setPixelBufferObject(PixelBufferObject* buffer) { setBufferObject(buffer); }
  393. /** Get the PixelBufferObject.*/
  394. PixelBufferObject* getPixelBufferObject() { return dynamic_cast<PixelBufferObject*>(getBufferObject()); }
  395. /** Get the const PixelBufferObject.*/
  396. const PixelBufferObject* getPixelBufferObject() const { return dynamic_cast<const PixelBufferObject*>(getBufferObject()); }
  397. /** Return whether the update(NodeVisitor* nv) should be required on each frame to enable proper working of osg::Image.*/
  398. virtual bool requiresUpdateCall() const { return false; }
  399. /** update method for osg::Image subclasses that update themselves during the update traversal.*/
  400. virtual void update(NodeVisitor* /*nv*/) {}
  401. /** Convenience update callback class that can be attached to a StateAttribute (such as Textures) to ensure
  402. * that the Image::update(NodeVisitor*) method is called during the update traversal. This callback
  403. * is automatically attached when Image::requiresUpdateCall() is true (it's false by default.)
  404. */
  405. struct OSG_EXPORT UpdateCallback : public osg::StateAttributeCallback
  406. {
  407. virtual void operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv);
  408. };
  409. /** 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. */
  410. virtual bool sendFocusHint(bool /*focus*/) { return false; }
  411. /** 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. */
  412. virtual bool sendPointerEvent(int /*x*/, int /*y*/, int /*buttonMask*/) { return false; }
  413. /** 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.*/
  414. virtual bool sendKeyEvent(int /*key*/, bool /*keyDown*/) { return false; }
  415. /** Pass frame information to the custom Image classes, to be called only when objects associated with imagery are not culled.*/
  416. virtual void setFrameLastRendered(const osg::FrameStamp* /*frameStamp*/) {}
  417. class DimensionsChangedCallback : public osg::Referenced {
  418. public:
  419. DimensionsChangedCallback() : osg::Referenced() {}
  420. virtual void operator()(osg::Image* image) = 0;
  421. };
  422. typedef std::vector< osg::ref_ptr<DimensionsChangedCallback> > DimensionsChangedCallbackVector;
  423. void addDimensionsChangedCallback(DimensionsChangedCallback* cb);
  424. void removeDimensionsChangedCallback(DimensionsChangedCallback* cb);
  425. protected :
  426. virtual ~Image();
  427. Image& operator = (const Image&) { return *this; }
  428. void handleDimensionsChangedCallbacks()
  429. {
  430. for(DimensionsChangedCallbackVector::iterator i = _dimensionsChangedCallbacks.begin(); i != _dimensionsChangedCallbacks.end(); ++i)
  431. {
  432. (*i)->operator()(this);
  433. }
  434. }
  435. std::string _fileName;
  436. WriteHint _writeHint;
  437. Origin _origin;
  438. int _s, _t, _r;
  439. int _rowLength;
  440. GLint _internalTextureFormat;
  441. GLenum _pixelFormat;
  442. GLenum _dataType;
  443. unsigned int _packing;
  444. float _pixelAspectRatio;
  445. AllocationMode _allocationMode;
  446. unsigned char* _data;
  447. void deallocateData();
  448. void setData(unsigned char* data,AllocationMode allocationMode);
  449. MipmapDataType _mipmapData;
  450. DimensionsChangedCallbackVector _dimensionsChangedCallbacks;
  451. };
  452. class Geode;
  453. /** Convenience function to be used by image loaders to generate a valid geode
  454. * to return for readNode().
  455. * Use the image's s and t values to scale the dimensions of the image.
  456. */
  457. extern OSG_EXPORT Geode* createGeodeForImage(Image* image);
  458. template<class T> Geode* createGeodeForImage(const ref_ptr<T>& image) { return createGeodeForImage(image.get()); }
  459. /** Convenience function to be used by image loaders to generate a valid geode
  460. * to return for readNode().
  461. * Use the specified s and t values to scale the dimensions of the image.
  462. */
  463. extern OSG_EXPORT Geode* createGeodeForImage(Image* image, float s, float t);
  464. template<class T> Geode* createGeodeForImage(const ref_ptr<T>& image, float s, float t) { return createGeodeForImage(image.get(), s, t); }
  465. }
  466. #endif // __SG_IMAGE_H