2003-01-22 00:45:36 +08:00
|
|
|
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
|
|
|
|
*
|
|
|
|
* 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
|
|
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* OpenSceneGraph Public License for more details.
|
|
|
|
*/
|
2001-10-04 23:12:57 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
// -*-c++-*-
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
#ifndef OSG_IMAGE
|
|
|
|
#define OSG_IMAGE 1
|
|
|
|
|
|
|
|
#include <osg/Object>
|
2002-04-12 01:15:07 +08:00
|
|
|
#include <osg/GL>
|
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
|
|
|
|
/* 1.2 definitions...*/
|
|
|
|
#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
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
namespace osg {
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
/** Image class for encapsulating the storage texture image data.*/
|
|
|
|
class SG_EXPORT Image : public Object
|
|
|
|
{
|
|
|
|
|
|
|
|
public :
|
|
|
|
|
|
|
|
Image();
|
Added support for shallow and deep copy of nodes, drawables and state, via a
copy constructor which takes an optional Cloner object, and the old
osg::Object::clone() has changed so that it now requires a Cloner as paramter.
This is passed on to the copy constructor to help control the shallow vs
deep copying. The old functionality of clone() which was clone of type has
been renamed to cloneType().
Updated all of the OSG to work with these new conventions, implemention all
the required copy constructors etc. A couple of areas will do shallow
copies by design, a couple of other still need to be updated to do either
shallow or deep.
Neither of the shallow or deep copy operations have been tested yet, only
the old functionality of the OSG has been checked so far, such running the
viewer on various demo datasets.
Also fixed a problem in osg::Optimize::RemoveRendundentNodesVisitor which
was not checking that Group didn't have have any attached StateSet's, Callbacks
or UserData. These checks have now been added, which fixes a bug which was
revealled by the new osgscribe demo, this related to removal of group acting
as state decorator.
method
2002-01-29 05:17:01 +08:00
|
|
|
|
2002-01-29 22:04:06 +08:00
|
|
|
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
|
|
|
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"; }
|
|
|
|
|
|
|
|
|
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; }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2002-04-11 05:51:34 +08:00
|
|
|
|
2003-02-25 19:56:18 +08:00
|
|
|
enum AllocationMode {
|
|
|
|
NO_DELETE,
|
|
|
|
USE_NEW_DELETE,
|
|
|
|
USE_MALLOC_FREE
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Set the method used for deleting data once it goes out of scope.*/
|
|
|
|
void setAllocationMode(AllocationMode mode) { _allocationMode = mode; }
|
|
|
|
|
|
|
|
/** Get the method used for deleting data once it goes out of scope.*/
|
|
|
|
AllocationMode setAllocationMode() const { return _allocationMode; }
|
|
|
|
|
|
|
|
|
2002-04-12 01:15:07 +08:00
|
|
|
/* allocated a pixel block of specified size and type.*/
|
2002-08-27 18:06:57 +08:00
|
|
|
void allocateImage(int s,int t,int r,
|
|
|
|
GLenum format,GLenum type,
|
|
|
|
int packing=1);
|
2002-04-11 05:51:34 +08:00
|
|
|
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
/** set the image data and format.
|
2001-09-20 05:08:56 +08:00
|
|
|
* note, when the packing value is negative (the default is -1) this method assumes
|
2001-01-11 00:32:10 +08:00
|
|
|
* a _packing width of 1 if the width is not a multiple of 4,
|
2001-09-29 04:10:41 +08:00
|
|
|
* otherwise automatically sets to _packing to 4. If a positive
|
2001-01-11 00:32:10 +08:00
|
|
|
* value of packing is supplied than _packing is simply set to that value.
|
|
|
|
*/
|
2002-04-12 01:15:07 +08:00
|
|
|
void setImage(int s,int t,int r,
|
|
|
|
GLint internalTextureformat,
|
|
|
|
GLenum format,GLenum type,
|
2002-04-11 05:51:34 +08:00
|
|
|
unsigned char *data,
|
2003-02-25 19:56:18 +08:00
|
|
|
AllocationMode mode,
|
2002-04-12 01:15:07 +08:00
|
|
|
int packing=1);
|
2002-04-11 05:51:34 +08:00
|
|
|
|
|
|
|
/** readPixels from screen at specified position and size, using glReadPixels.
|
|
|
|
* Create memory for storage if required, reuse existing pixel coords if possible.
|
|
|
|
* if pixelFormat or dataType*/
|
|
|
|
void readPixels(int x,int y,int width,int height,
|
2002-04-12 01:15:07 +08:00
|
|
|
GLenum format,GLenum type);
|
2002-04-11 05:51:34 +08:00
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2002-04-12 01:15:07 +08:00
|
|
|
/** Scale image to specified size. */
|
2002-09-02 20:31:35 +08:00
|
|
|
void scaleImage(int s,int t,int r);
|
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.
|
|
|
|
* If the this Image is empty then image data is created to
|
|
|
|
* accomodate the imaging image in its offset position.
|
|
|
|
* If source is NULL then no operation happens, this Image is left unchanged.*/
|
|
|
|
void copySubImage(int s_offset,int t_offset,int r_offset,osg::Image* source);
|
2002-04-12 01:15:07 +08:00
|
|
|
|
|
|
|
|
2001-01-11 00:32:10 +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
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
/** Height of image.*/
|
2002-09-02 20:31:35 +08:00
|
|
|
inline int t() const { return _t; }
|
2002-04-12 01:15:07 +08:00
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
/** Depth of image.*/
|
2002-09-02 20:31:35 +08:00
|
|
|
inline int r() const { return _r; }
|
2001-01-11 00:32:10 +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; }
|
2002-04-11 05:51:34 +08:00
|
|
|
|
2002-09-02 20:31:35 +08:00
|
|
|
void setPixelFormat(GLenum format);
|
|
|
|
inline GLenum getPixelFormat() const { return _pixelFormat; }
|
2002-04-11 05:51:34 +08:00
|
|
|
|
2002-09-02 20:31:35 +08:00
|
|
|
inline GLenum getDataType() const { return _dataType; }
|
2002-04-11 05:51:34 +08:00
|
|
|
|
2002-09-02 20:31:35 +08:00
|
|
|
inline unsigned int getPacking() const { return _packing; }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2002-04-12 01:15:07 +08:00
|
|
|
/** return the numbers 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
|
|
|
|
|
|
|
/** return the numbers 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
|
|
|
|
|
|
|
/** return the numbers 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; }
|
2002-04-11 05:51:34 +08:00
|
|
|
|
2002-04-12 01:15:07 +08:00
|
|
|
/** return the numbers 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
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
/** raw image data.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
inline unsigned char *data() { return _data; }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** raw const image data.*/
|
|
|
|
inline const unsigned char *data() const { return _data; }
|
|
|
|
|
2002-04-12 01:15:07 +08:00
|
|
|
|
2002-08-16 23:14:43 +08:00
|
|
|
inline unsigned char* data(int column, int row=0,int image=0)
|
2002-04-12 01:15:07 +08:00
|
|
|
{
|
|
|
|
if (!_data) return NULL;
|
2002-04-16 22:57:39 +08:00
|
|
|
return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes();
|
2002-04-12 01:15:07 +08:00
|
|
|
}
|
2002-05-14 17:34:11 +08:00
|
|
|
|
2002-09-02 20:31:35 +08:00
|
|
|
inline unsigned char* data(int column, int row=0,int image=0) const
|
2002-08-16 23:14:43 +08:00
|
|
|
{
|
|
|
|
if (!_data) return NULL;
|
|
|
|
return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes();
|
|
|
|
}
|
|
|
|
|
2002-05-14 17:34:11 +08:00
|
|
|
/** Flip the image horizontally.*/
|
|
|
|
void flipHorizontal(int image=0);
|
|
|
|
|
|
|
|
/** Flip the image vertically.*/
|
|
|
|
void flipVertical(int image=0);
|
2002-04-12 01:15:07 +08:00
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
/** Ensure image dimensions are a power of two.
|
|
|
|
* Mip Mapped texture require the image dimensions to be
|
2002-04-15 06:21:59 +08:00
|
|
|
* power of two and are within the maxiumum texture size for
|
|
|
|
* the host machine.*/
|
2002-09-17 04:58:05 +08:00
|
|
|
void ensureValidSizeForTexturing(GLint maxTextureSize);
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2001-11-19 05:31:16 +08:00
|
|
|
/** Dirty the image, which increments the modified flag, to force osg::Texture to reload the image.*/
|
2001-12-05 04:38:27 +08:00
|
|
|
inline void dirty() { ++_modifiedTag; }
|
2001-11-19 05:31:16 +08:00
|
|
|
|
|
|
|
/** Set the modified tag value, only used by osg::Texture when using texture subloading. */
|
2002-09-02 20:31:35 +08:00
|
|
|
inline void setModifiedTag(unsigned int value) { _modifiedTag=value; }
|
2001-11-19 05:31:16 +08:00
|
|
|
|
|
|
|
/** Get modified tag value, only used by osg::Texture when using texture subloading. */
|
2002-09-02 20:31:35 +08:00
|
|
|
inline unsigned int getModifiedTag() const { return _modifiedTag; }
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2002-04-12 01:15:07 +08:00
|
|
|
|
2002-09-02 20:31:35 +08:00
|
|
|
static bool isPackedType(GLenum type);
|
|
|
|
static unsigned int computeNumComponents(GLenum format);
|
|
|
|
static unsigned int computePixelSizeInBits(GLenum format,GLenum type);
|
|
|
|
static unsigned int computeRowWidthInBytes(int width,GLenum format,GLenum type,int packing);
|
|
|
|
static unsigned int computeNearestPowerOfTwo(unsigned int s,float bias=0.5f);
|
|
|
|
|
2002-04-23 05:13:33 +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
|
|
|
{
|
|
|
|
return _mipmapData.size()+1;
|
|
|
|
};
|
|
|
|
|
|
|
|
// send offsets into data
|
|
|
|
// It is assumed that first mipmap offset (index 0) is 0
|
|
|
|
inline void setMipmapData(const MipmapDataType& mipmapDataVector)
|
|
|
|
{
|
|
|
|
_mipmapData = mipmapDataVector;
|
|
|
|
};
|
|
|
|
|
2002-04-23 18:34:20 +08:00
|
|
|
inline unsigned char* getMipmapData(unsigned int mipmapNumber) const
|
2002-04-23 05:13:33 +08:00
|
|
|
{
|
|
|
|
if(mipmapNumber == 0)
|
|
|
|
return _data;
|
2002-08-16 21:33:32 +08:00
|
|
|
else if(mipmapNumber < getNumMipmapLevels())
|
2002-04-23 05:13:33 +08:00
|
|
|
return _data + _mipmapData[mipmapNumber-1];
|
|
|
|
return 0L;
|
|
|
|
};
|
2002-08-16 21:33:32 +08:00
|
|
|
|
|
|
|
|
|
|
|
/** converts a single image into mip mapped version image.*/
|
|
|
|
void computeMipMaps();
|
2002-11-26 00:38:33 +08:00
|
|
|
|
|
|
|
/** return true of this image is translucent - i.e. it has alpha values that are less 1.0 (when normalized).*/
|
|
|
|
bool isImageTranslucent() const;
|
2002-04-12 01:15:07 +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; }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
std::string _fileName;
|
2003-02-25 19:56:18 +08:00
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
int _s, _t, _r;
|
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;
|
2003-02-25 19:56:18 +08:00
|
|
|
|
|
|
|
AllocationMode _allocationMode;
|
2001-01-11 00:32:10 +08:00
|
|
|
unsigned char *_data;
|
2003-02-25 19:56:18 +08:00
|
|
|
|
|
|
|
void deallocateData();
|
|
|
|
|
|
|
|
void setData(unsigned char *data,AllocationMode allocationMode);
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
unsigned int _modifiedTag;
|
2002-04-23 05:13:33 +08:00
|
|
|
|
|
|
|
MipmapDataType _mipmapData;
|
2001-01-11 00:32:10 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class Geode;
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** Convenience function to be used by images loaders to generate a valid geode
|
|
|
|
* to return for readNode().
|
|
|
|
* Use the images s and t values scale the dimensions of the image.
|
|
|
|
*/
|
2002-12-05 20:43:08 +08:00
|
|
|
extern SG_EXPORT Geode* createGeodeForImage(Image* image);
|
2001-09-20 05:08:56 +08:00
|
|
|
/** Convenience function to be used by images loaders to generate a valid geode
|
|
|
|
* to return for readNode().
|
|
|
|
* Use the specified s and t values scale the dimensions of the image.
|
|
|
|
*/
|
2002-12-05 20:43:08 +08:00
|
|
|
extern SG_EXPORT Geode* createGeodeForImage(Image* image,float s,float 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
|