Show
Ignore:
Timestamp:
01/24/12 15:34:02 (2 years ago)
Author:
robert
Message:

Added support for using GL_UNPACK_ROW_LENGTH in conjunction with texture's + osg::Image via new RowLength?
parameter in osg::Image. To support this Image::setData(..) now has a new optional rowLength parameter which
defaults to 0, which provides the original behaviour, Image::setRowLength(int) and int Image::getRowLength() are also provided.

With the introduction of RowLength? support in osg::Image it is now possible to create a sub image where
the t size of the image are smaller than the row length, useful for when you have a large image on the CPU
and which to use a small portion of it on the GPU. However, when these sub images are created the data
within the image is no longer contiguous so data access can no longer assume that all the data is in
one block. The new method Image::isDataContiguous() enables the user to check whether the data is contiguous,
and if not one can either access the data row by row using Image::data(column,row,image) accessor, or use the
new Image::DataIterator? for stepping through each block on memory assocatied with the image.

To support the possibility of non contiguous osg::Image usage of image objects has had to be updated to
check DataContiguous? and handle the case or use access via the DataIerator? or by row by row. To achieve
this a relatively large number of files has had to be modified, in particular the texture classes and
image plugins that doing writing.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/include/osg/Image

    r12842 r12912  
    115115        virtual const char* className() const { return "Image"; } 
    116116 
     117        virtual osg::Image* asImage() { return this; } 
     118        virtual const osg::Image* asImage() const { return this; } 
     119 
    117120        virtual const GLvoid*   getDataPointer() const { return data(); } 
    118121        virtual unsigned int    getTotalDataSize() const { return getTotalSizeInBytesIncludingMipmaps(); } 
     
    158161                      unsigned char* data, 
    159162                      AllocationMode mode, 
    160                       int packing=1); 
     163                      int packing=1, int rowLength=0); 
    161164             
    162165        /** Read pixels from current frame buffer at specified position and size, using glReadPixels. 
     
    214217        /** Depth of image. */ 
    215218        inline int r() const { return _r; } 
     219 
     220        void setRowLength(int length) { _rowLength = length; } 
     221        inline int getRowLength() const { return _rowLength; } 
    216222         
    217223        void setInternalTextureFormat(GLint internalFormat); 
     
    242248        inline unsigned int getRowSizeInBytes() const { return computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing); } 
    243249 
     250        /** Return the number of bytes between each successive row. 
     251          * Note, getRowSizeInBytes() will only equal getRowStepInBytes() when isDataContiguous() return true. */ 
     252        inline unsigned int getRowStepInBytes() const { return computeRowWidthInBytes(_rowLength==0?_s:_rowLength,_pixelFormat,_dataType,_packing); } 
     253 
    244254        /** Return the number of bytes each image (_s*_t) of pixels occupies. */ 
    245255        inline unsigned int getImageSizeInBytes() const { return getRowSizeInBytes()*_t; } 
    246256         
     257        /** Return the number of bytes between each successive image.  
     258          * Note, getImageSizeInBytes() will only equal getImageStepInBytes() when isDataContiguous() return true. */ 
     259        inline unsigned int getImageStepInBytes() const { return getRowStepInBytes()*_t; } 
     260 
    247261        /** Return the number of bytes the whole row/image/volume of pixels occupies. */ 
    248262        inline unsigned int getTotalSizeInBytes() const { return getImageSizeInBytes()*_r; } 
     
    254268        bool valid() const { return _s!=0 && _t!=0 && _r!=0 && _data!=0 && _dataType!=0; } 
    255269 
    256         /** Raw image data. */ 
     270        /** Raw image data. 
     271          * Note, data in successive rows may not be contiguous, isDataContiguous() return false then you should 
     272          * take care to access the data per row rather than treating the whole data as a single block. */ 
    257273        inline unsigned char* data() { return _data; } 
    258274         
    259         /** Raw const image data. */ 
     275        /** Raw const image data. 
     276          * Note, data in successive rows may not be contiguous, isDataContiguous() return false then you should 
     277          * take care to access the data per row rather than treating the whole data as a single block. */ 
    260278        inline const unsigned char* data() const { return _data; } 
    261279 
    262  
    263280        inline unsigned char* data(int column, int row=0,int image=0) 
    264281        { 
    265282            if (!_data) return NULL; 
    266             return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes(); 
     283            return _data+(column*getPixelSizeInBits())/8+row*getRowStepInBytes()+image*getImageSizeInBytes(); 
    267284        } 
    268285         
     
    270287        { 
    271288            if (!_data) return NULL; 
    272             return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes(); 
     289            return _data+(column*getPixelSizeInBits())/8+row*getRowStepInBytes()+image*getImageSizeInBytes(); 
    273290        } 
     291 
     292        /** return true if the data stored in the image is a contiguous block of data.*/ 
     293        bool isDataContiguous() const { return _rowLength==0 || _rowLength==_s; } 
     294 
     295        /** Convenience class for assisting the copying of image data when the image data isn't contiguous.*/ 
     296        class OSG_EXPORT DataIterator 
     297        { 
     298        public: 
     299            DataIterator(const Image* image); 
     300            DataIterator(const DataIterator& ri); 
     301            ~DataIterator() {} 
     302 
     303            /** advance iterator to next block of data.*/ 
     304            void operator ++ (); 
     305 
     306            /** is iterator valid.*/ 
     307            bool valid() const { return _currentPtr!=0; } 
     308 
     309            /** data pointer of current block to copy.*/ 
     310            const unsigned char* data() const { return _currentPtr; } 
     311 
     312            /** Size of current block to copy.*/ 
     313            unsigned int size() const { return _currentSize; } 
     314 
     315        protected: 
     316 
     317             
     318            void assign(); 
     319             
     320            const osg::Image*                   _image; 
     321            int                                 _rowNum; 
     322            int                                 _imageNum; 
     323            unsigned int                        _mipmapNum; 
     324            const unsigned char*                _currentPtr; 
     325            unsigned int                        _currentSize; 
     326        }; 
    274327 
    275328        /** Get the color value for specified texcoord.*/ 
     
    302355        static GLenum computePixelFormat(GLenum pixelFormat); 
    303356        static GLenum computeFormatDataType(GLenum pixelFormat); 
     357        static unsigned int computeBlockSize(GLenum pixelFormat, GLenum packing); 
    304358        static unsigned int computeNumComponents(GLenum pixelFormat); 
    305359        static unsigned int computePixelSizeInBits(GLenum pixelFormat,GLenum type); 
    306360        static unsigned int computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing); 
     361        static unsigned int computeImageSizeInBytes(int width,int height, int depth, GLenum pixelFormat,GLenum type,int packing); 
    307362        static int computeNearestPowerOfTwo(int s,float bias=0.5f); 
    308363        static int computeNumberOfMipmapLevels(int s,int t = 1, int r = 1); 
     
    342397        } 
    343398 
    344         /*inline const unsigned char* getMipmapData(unsigned int row, unsigned int column, unsigned int mipmapLevel) const 
    345         { 
    346            if (!_data) return NULL; 
    347            return getMipmapData(mipmapLevel) + (column*getPixelSizeInBits())/8+row*getRowSizeInBytes(); 
    348         }*/ 
    349  
    350399        /** Return true if this image is translucent - i.e. it has alpha values that are less 1.0 (when normalized). */ 
    351400        virtual bool isImageTranslucent() const; 
     
    400449 
    401450        int _s, _t, _r; 
     451        int _rowLength; 
    402452        GLint _internalTextureFormat; 
    403453        GLenum _pixelFormat;