Added support in Image::flipVertical for flipping mipmapped imagery

and for flipping compressed imagery.
This commit is contained in:
Robert Osfield 2004-08-16 20:57:24 +00:00
parent bb6fe74738
commit cf99c3c9bd
2 changed files with 89 additions and 40 deletions

View File

@ -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;

View File

@ -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
{ {