Added support in Image::flipVertical for flipping mipmapped imagery
and for flipping compressed imagery.
This commit is contained in:
parent
bb6fe74738
commit
cf99c3c9bd
@ -181,10 +181,10 @@ class SG_EXPORT Image : public Object
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Flip the image horizontally.*/
|
/** Flip the image horizontally.*/
|
||||||
void flipHorizontal(int image=0);
|
void flipHorizontal();
|
||||||
|
|
||||||
/** Flip the image vertically.*/
|
/** Flip the image vertically.*/
|
||||||
void flipVertical(int image=0);
|
void flipVertical();
|
||||||
|
|
||||||
|
|
||||||
/** Ensure image dimensions are a power of two.
|
/** Ensure image dimensions are a power of two.
|
||||||
@ -236,9 +236,6 @@ class SG_EXPORT Image : public Object
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** converts a single image into mip mapped version image.*/
|
|
||||||
void computeMipMaps();
|
|
||||||
|
|
||||||
/** return true of this image is translucent - i.e. it has alpha values that are less 1.0 (when normalized).*/
|
/** return true of this image is translucent - i.e. it has alpha values that are less 1.0 (when normalized).*/
|
||||||
bool isImageTranslucent() const;
|
bool isImageTranslucent() const;
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <osg/StateSet>
|
#include <osg/StateSet>
|
||||||
#include <osg/Texture2D>
|
#include <osg/Texture2D>
|
||||||
|
|
||||||
|
#include "dxtctool.h"
|
||||||
|
|
||||||
using namespace osg;
|
using namespace osg;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -657,7 +658,7 @@ void Image::copySubImage(int s_offset,int t_offset,int r_offset,osg::Image* sour
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Image::flipHorizontal(int image)
|
void Image::flipHorizontal()
|
||||||
{
|
{
|
||||||
if (_data==NULL)
|
if (_data==NULL)
|
||||||
{
|
{
|
||||||
@ -667,28 +668,45 @@ void Image::flipHorizontal(int image)
|
|||||||
|
|
||||||
unsigned int elemSize = getPixelSizeInBits()/8;
|
unsigned int elemSize = getPixelSizeInBits()/8;
|
||||||
|
|
||||||
for (int t=0; t<_t; ++t)
|
for(int r=0;r<_r;++r)
|
||||||
{
|
{
|
||||||
unsigned char* rowData = _data+t*getRowSizeInBytes()+image*getImageSizeInBytes();
|
for (int t=0; t<_t; ++t)
|
||||||
unsigned char* left = rowData ;
|
|
||||||
unsigned char* right = rowData + ((_s-1)*getPixelSizeInBits())/8;
|
|
||||||
|
|
||||||
while (left < right)
|
|
||||||
{
|
{
|
||||||
char tmp[32]; // max elem size is four floats
|
unsigned char* rowData = _data+t*getRowSizeInBytes()+r*getImageSizeInBytes();
|
||||||
memcpy(tmp, left, elemSize);
|
unsigned char* left = rowData ;
|
||||||
memcpy(left, right, elemSize);
|
unsigned char* right = rowData + ((_s-1)*getPixelSizeInBits())/8;
|
||||||
memcpy(right, tmp, elemSize);
|
|
||||||
left += elemSize;
|
while (left < right)
|
||||||
right -= elemSize;
|
{
|
||||||
|
char tmp[32]; // max elem size is four floats
|
||||||
|
memcpy(tmp, left, elemSize);
|
||||||
|
memcpy(left, right, elemSize);
|
||||||
|
memcpy(right, tmp, elemSize);
|
||||||
|
left += elemSize;
|
||||||
|
right -= elemSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++_modifiedTag;
|
++_modifiedTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void flipImageVertical(unsigned char* top, unsigned char* bottom, unsigned int rowSize)
|
||||||
|
{
|
||||||
|
while(top<bottom)
|
||||||
|
{
|
||||||
|
for(unsigned int i=0;i<rowSize;++i, ++top,++bottom)
|
||||||
|
{
|
||||||
|
unsigned char temp=*top;
|
||||||
|
*top = *bottom;
|
||||||
|
*bottom = temp;
|
||||||
|
}
|
||||||
|
bottom -= 2*rowSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Image::flipVertical(int image)
|
|
||||||
|
void Image::flipVertical()
|
||||||
{
|
{
|
||||||
if (_data==NULL)
|
if (_data==NULL)
|
||||||
{
|
{
|
||||||
@ -696,25 +714,64 @@ void Image::flipVertical(int image)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int rowSizeInBytes = getRowSizeInBytes();
|
if (!_mipmapData.empty() && _r>1)
|
||||||
unsigned int imageSizeInBytes = getImageSizeInBytes();
|
|
||||||
unsigned char* imageData = _data+image*imageSizeInBytes;
|
|
||||||
|
|
||||||
// make temp. buffer for one image
|
|
||||||
unsigned char *tmpData = new unsigned char [imageSizeInBytes];
|
|
||||||
|
|
||||||
for (int t=0; t<_t; ++t)
|
|
||||||
{
|
{
|
||||||
unsigned char* srcRowData = imageData+t*rowSizeInBytes;
|
notify(WARN) << "Error Image::flipVertical() do not succeed : flipping of mipmap 3d textures not yet supported."<<std::endl;
|
||||||
unsigned char* dstRowData = tmpData+(_t-1-t)*rowSizeInBytes;
|
return;
|
||||||
memcpy(dstRowData, srcRowData, rowSizeInBytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert fliped image
|
if (_mipmapData.empty())
|
||||||
memcpy(imageData, tmpData, imageSizeInBytes);
|
{
|
||||||
|
// no mipmaps,
|
||||||
|
// so we can safely handle 3d textures
|
||||||
|
for(int r=0;r<_r;++r)
|
||||||
|
{
|
||||||
|
if (!dxtc_tool::VerticalFlip(_s,_t,_pixelFormat,data(0,0,r)))
|
||||||
|
{
|
||||||
|
// its not a compressed image, so implement flip oursleves.
|
||||||
|
|
||||||
|
unsigned int rowSize = computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing);
|
||||||
|
unsigned char* top = data(0,0,r);
|
||||||
|
unsigned char* bottom = top + (_t-1)*rowSize;
|
||||||
|
|
||||||
|
flipImageVertical(top, bottom, rowSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_r==1)
|
||||||
|
{
|
||||||
|
if (!dxtc_tool::VerticalFlip(_s,_t,_pixelFormat,_data))
|
||||||
|
{
|
||||||
|
// its not a compressed image, so implement flip oursleves.
|
||||||
|
unsigned int rowSize = computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing);
|
||||||
|
unsigned char* top = data(0,0,0);
|
||||||
|
unsigned char* bottom = top + (_t-1)*rowSize;
|
||||||
|
|
||||||
|
flipImageVertical(top, bottom, rowSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
int s = _s;
|
||||||
|
int t = _t;
|
||||||
|
//int r = _r;
|
||||||
|
|
||||||
|
for(unsigned int i=0;i<_mipmapData.size() && _mipmapData[i];++i)
|
||||||
|
{
|
||||||
|
s >>= 1;
|
||||||
|
t >>= 1;
|
||||||
|
if (s==0) s=1;
|
||||||
|
if (t==0) t=1;
|
||||||
|
if (!dxtc_tool::VerticalFlip(s,t,_pixelFormat,_data+_mipmapData[i]))
|
||||||
|
{
|
||||||
|
// its not a compressed image, so implement flip oursleves.
|
||||||
|
unsigned int rowSize = computeRowWidthInBytes(s,_pixelFormat,_dataType,_packing);
|
||||||
|
unsigned char* top = _data+_mipmapData[i];
|
||||||
|
unsigned char* bottom = top + (t-1)*rowSize;
|
||||||
|
|
||||||
|
flipImageVertical(top, bottom, rowSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete [] tmpData;
|
|
||||||
|
|
||||||
++_modifiedTag;
|
++_modifiedTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,11 +794,6 @@ void Image::ensureValidSizeForTexturing(GLint maxTextureSize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::computeMipMaps()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Image::isImageTranslucent() const
|
bool Image::isImageTranslucent() const
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user