From eb3917060f8ae1ef16f3bfcf1ff188caa0b7880b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 25 May 2004 16:10:28 +0000 Subject: [PATCH] From George Tarantilis, fixes to DDS size computations. From Robert Osfield, addition of constructors for internal DDS structures. --- src/osg/Image.cpp | 42 ++++++-- src/osgPlugins/dds/ReaderWriterDDS.cpp | 143 ++++++++++++++++--------- 2 files changed, 122 insertions(+), 63 deletions(-) diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index 04fd3c09c..49d87d0bf 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -173,16 +173,29 @@ unsigned int Image::computeNumComponents(GLenum pixelFormat) unsigned int Image::computePixelSizeInBits(GLenum format,GLenum type) { + + if(format & 0x80F0) /* DXT* compressed formats */ + { + switch(format) + { + case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT): return 4; + + case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT): return 4; + + case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): return 8; + + case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): return 8; + default: + { + notify(WARN)<<"error format = "<setImage(s,t,r, internalFormat, pixelFormat, dataType, 0, osg::Image::USE_NEW_DELETE); - if (mipmaps.size()>0) osgImage->setMipmapData(mipmaps); - size = osgImage->getTotalSizeInBytesIncludingMipmaps(); - } + osgImage->setImage(s,t,r, internalFormat, pixelFormat, dataType, 0, osg::Image::USE_NEW_DELETE); + if (mipmaps.size()>0) osgImage->setMipmapData(mipmaps); + unsigned int size = osgImage->getTotalSizeInBytesIncludingMipmaps(); if(size <= 0) { @@ -433,13 +460,13 @@ bool WriteDDSFile(const osg::Image *img, const char *filename) return false; // Initialize ddsd structure and its members - DDSURFACEDESC2 ddsd = {0}; - DDPIXELFORMAT ddpf = {0}; - DDCOLORKEY ddckCKDestOverlay = {0}; - DDCOLORKEY ddckCKDestBlt = {0}; - DDCOLORKEY ddckCKSrcOverlay = {0}; - DDCOLORKEY ddckCKSrcBlt = {0}; - DDSCAPS2 ddsCaps = {0}; + DDSURFACEDESC2 ddsd; + DDPIXELFORMAT ddpf; + DDCOLORKEY ddckCKDestOverlay; + DDCOLORKEY ddckCKDestBlt; + DDCOLORKEY ddckCKSrcOverlay; + DDCOLORKEY ddckCKSrcBlt; + DDSCAPS2 ddsCaps; ddsd.dwSize = sizeof(ddsd); ddpf.dwSize = sizeof(ddpf); @@ -456,7 +483,7 @@ bool WriteDDSFile(const osg::Image *img, const char *filename) unsigned int internalFormat = img->getInternalTextureFormat(); unsigned int components = osg::Image::computeNumComponents(pixelFormat); unsigned int pixelSize = osg::Image::computePixelSizeInBits(pixelFormat, dataType); - unsigned int imageSize = img->getImageSizeInBytes() / components; + unsigned int imageSize = img->getImageSizeInBytes(); bool is3dImage = false; int s = ddsd.dwWidth = img->s(); @@ -478,7 +505,7 @@ bool WriteDDSFile(const osg::Image *img, const char *filename) //Uncompressed case GL_RGBA: { - ddpf.dwRBitMask = 0x00ff0000; //1st change + ddpf.dwRBitMask = 0x00ff0000; ddpf.dwGBitMask = 0x0000ff00; ddpf.dwBBitMask = 0x000000ff; ddpf.dwRGBAlphaBitMask = 0xff000000; @@ -490,7 +517,7 @@ bool WriteDDSFile(const osg::Image *img, const char *filename) break; case GL_BGRA: { - ddpf.dwBBitMask = 0x00ff0000; //2nd change + ddpf.dwBBitMask = 0x00ff0000; ddpf.dwGBitMask = 0x0000ff00; ddpf.dwRBitMask = 0x000000ff; ddpf.dwRGBAlphaBitMask = 0xff000000; @@ -504,7 +531,7 @@ bool WriteDDSFile(const osg::Image *img, const char *filename) { ddpf.dwRBitMask = 0x00ff0000; ddpf.dwRGBAlphaBitMask = 0x000000ff; - PF_flags |= (DDPF_ALPHAPIXELS | DDPF_LUMINANCE); //3rd change + PF_flags |= (DDPF_ALPHAPIXELS | DDPF_LUMINANCE); ddpf.dwRGBBitCount = pixelSize; ddsd.lPitch = img->getRowSizeInBytes(); SD_flags |= DDSD_PITCH; @@ -519,7 +546,6 @@ bool WriteDDSFile(const osg::Image *img, const char *filename) ddpf.dwRGBBitCount = pixelSize; ddsd.lPitch = img->getRowSizeInBytes(); SD_flags |= DDSD_PITCH; - } break; case GL_LUMINANCE: @@ -531,6 +557,15 @@ bool WriteDDSFile(const osg::Image *img, const char *filename) SD_flags |= DDSD_PITCH; } break; + case GL_ALPHA: + { + ddpf.dwRGBAlphaBitMask = 0x000000ff; + PF_flags |= DDPF_ALPHA; + ddpf.dwRGBBitCount = pixelSize; + ddsd.lPitch = img->getRowSizeInBytes(); + SD_flags |= DDSD_PITCH; + } + break; //Compressed case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: @@ -570,7 +605,7 @@ bool WriteDDSFile(const osg::Image *img, const char *filename) return false; } - + // set even more flags if(img->isMipmap() && !is3dImage) { @@ -614,7 +649,11 @@ bool WriteDDSFile(const osg::Image *img, const char *filename) unsigned char *mmdPtr, *next_mmdPtr; int offset; unsigned int mipmaps = img->getNumMipmapLevels(); - unsigned int blockSize = (pixelFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16; + unsigned int blockSize; + if(ddsd.dwFlags & DDSD_LINEARSIZE) // COMPRESSED + blockSize = (pixelFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16; + else + blockSize = pixelSize; mmdPtr = img->getMipmapData(1); /* get the first mipmap address */ @@ -635,8 +674,8 @@ bool WriteDDSFile(const osg::Image *img, const char *filename) { for(int i = 0; i < r; ++i) { - memcpy(dataPtr, img->data(0, 0, i), imageSize*components); //4th change - dataPtr += imageSize*components; + memcpy(dataPtr, img->data(0, 0, i), imageSize); + dataPtr += imageSize; } }