2001-10-04 23:12:57 +08:00
|
|
|
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
|
|
|
|
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
|
|
|
//as published by the Free Software Foundation.
|
|
|
|
|
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
|
|
|
|
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-03-27 07:52:52 +08:00
|
|
|
virtual Object* cloneType() const { return osgNew Image(); }
|
|
|
|
virtual Object* clone(const CopyOp& copyop) const { return osgNew 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; }
|
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
|
|
|
|
2002-04-12 01:15:07 +08:00
|
|
|
/* allocated a pixel block of specified size and type.*/
|
|
|
|
void createImage(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,
|
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. */
|
|
|
|
void scaleImage(const int s,const int t,const int r);
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
/** Width of image.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
inline const int s() const { return _s; }
|
2002-04-12 01:15:07 +08:00
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
/** Height of image.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
inline const int t() const { return _t; }
|
2002-04-12 01:15:07 +08:00
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
/** Depth of image.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
inline const 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);
|
|
|
|
inline const GLint getInternalTextureFormat() const { return _internalTextureFormat; }
|
2002-04-11 05:51:34 +08:00
|
|
|
|
2002-04-16 22:57:39 +08:00
|
|
|
void setPixelFormat(const GLenum format);
|
|
|
|
inline const GLenum getPixelFormat() const { return _pixelFormat; }
|
2002-04-11 05:51:34 +08:00
|
|
|
|
2002-04-16 22:57:39 +08:00
|
|
|
inline const GLenum getDataType() const { return _dataType; }
|
2002-04-11 05:51:34 +08:00
|
|
|
|
2002-04-16 22:57:39 +08:00
|
|
|
inline const 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-04-16 22:57:39 +08:00
|
|
|
inline const 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-04-16 22:57:39 +08:00
|
|
|
inline const 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-04-16 22:57:39 +08:00
|
|
|
inline const 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-04-16 22:57:39 +08:00
|
|
|
inline const 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
|
|
|
|
|
|
|
unsigned char* data(int column, int row=0,int image=0)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
|
|
|
/** 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.*/
|
|
|
|
void ensureValidSizeForTexturing();
|
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. */
|
|
|
|
inline void setModifiedTag(const unsigned int value) { _modifiedTag=value; }
|
|
|
|
|
|
|
|
/** Get modified tag value, only used by osg::Texture when using texture subloading. */
|
2001-09-20 05:08:56 +08:00
|
|
|
inline const unsigned int getModifiedTag() const { return _modifiedTag; }
|
|
|
|
|
2002-04-12 01:15:07 +08:00
|
|
|
|
|
|
|
static const bool isPackedType(GLenum type);
|
|
|
|
static const unsigned int computeNumComponents(GLenum format);
|
|
|
|
static const unsigned int computePixelSizeInBits(GLenum format,GLenum type);
|
|
|
|
static const unsigned int computeRowWidthInBytes(int width,GLenum format,GLenum type,int packing);
|
|
|
|
|
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-04-23 18:34:20 +08:00
|
|
|
unsigned int getNumMipmaps() 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;
|
|
|
|
else if(mipmapNumber < getNumMipmaps())
|
|
|
|
return _data + _mipmapData[mipmapNumber-1];
|
|
|
|
return 0L;
|
|
|
|
};
|
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;
|
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;
|
|
|
|
unsigned char *_data;
|
|
|
|
|
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.
|
|
|
|
*/
|
2001-01-11 00:32:10 +08:00
|
|
|
SG_EXPORT extern 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.
|
|
|
|
*/
|
|
|
|
SG_EXPORT extern Geode* createGeodeForImage(Image* image,const float s,const 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
|