📄 readerwriterdds.cpp
字号:
/************************************************************************ FILE: ReaderWriterdds.cpp** DESCRIPTION: Class for reading a DDS file into an osg::Image.** Example on reading a DDS file code can be found at:* http://developer.nvidia.com/docs/IO/1327/ATT/* ARB_texture_compression.pdf* Author: Sebastien Domine, NVIDIA Corporation** CREATED BY: Rune Schmidt Jensen, rsj@uni-dk** HISTORY: Created 31.03.2003* Modified 13.05.2004* by George Tarantilis, gtaranti@nps.navy.mil***********************************************************************/#include <osg/Texture>#include <osg/Notify>#include <osgDB/Registry>#include <osgDB/FileNameUtils>#include <osgDB/FileUtils>#include <osgDB/fstream>#include <iomanip>#include <stdio.h>// NOTICE ON WIN32:// typedef DWORD unsigned long;// sizeof(DWORD) = 4typedef unsigned int UI32;typedef int I32;struct DDCOLORKEY{ DDCOLORKEY(): dwColorSpaceLowValue(0), dwColorSpaceHighValue(0) {} UI32 dwColorSpaceLowValue; UI32 dwColorSpaceHighValue;};struct DDPIXELFORMAT{ DDPIXELFORMAT(): dwSize(0), dwFlags(0), dwFourCC(0), dwRGBBitCount(0), dwRBitMask(0), dwGBitMask(0), dwBBitMask(0), dwRGBAlphaBitMask(0) {} UI32 dwSize; UI32 dwFlags; UI32 dwFourCC; union { UI32 dwRGBBitCount; UI32 dwYUVBitCount; UI32 dwZBufferBitDepth; UI32 dwAlphaBitDepth; UI32 dwLuminanceBitDepth; }; union { UI32 dwRBitMask; UI32 dwYBitMask; }; union { UI32 dwGBitMask; UI32 dwUBitMask; }; union { UI32 dwBBitMask; UI32 dwVBitMask; }; union { UI32 dwRGBAlphaBitMask; UI32 dwYUVAlphaBitMask; UI32 dwRGBZBitMask; UI32 dwYUVZBitMask; };};struct DDSCAPS2{ DDSCAPS2(): dwCaps(0), dwCaps2(0), dwCaps3(0), dwCaps4(0) {} UI32 dwCaps; UI32 dwCaps2; UI32 dwCaps3; union { UI32 dwCaps4; UI32 dwVolumeDepth; };};struct DDSURFACEDESC2{ DDSURFACEDESC2(): dwSize(0), dwFlags(0), dwHeight(0), dwWidth(0), lPitch(0), dwBackBufferCount(0), dwMipMapCount(0), dwAlphaBitDepth(0), dwReserved(0), lpSurface(0), dwTextureStage(0) {} UI32 dwSize; UI32 dwFlags; UI32 dwHeight; UI32 dwWidth; union { I32 lPitch; UI32 dwLinearSize; }; union { UI32 dwBackBufferCount; UI32 dwDepth; }; union { UI32 dwMipMapCount; UI32 dwRefreshRate; }; UI32 dwAlphaBitDepth; UI32 dwReserved; UI32 lpSurface; //Fred Marmond: removed from pointer type to UI32 for 64bits compatibility. it is unused data DDCOLORKEY ddckCKDestOverlay; DDCOLORKEY ddckCKDestBlt; DDCOLORKEY ddckCKSrcOverlay; DDCOLORKEY ddckCKSrcBlt; DDPIXELFORMAT ddpfPixelFormat; DDSCAPS2 ddsCaps; UI32 dwTextureStage; };//// Structure of a DXT-1 compressed texture block// see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/Opaque_and_1_Bit_Alpha_Textures.asp//struct DXT1TexelsBlock{ unsigned short color_0; // colors at their unsigned short color_1; // extreme unsigned int texels4x4; // interpolated colors (2 bits per texel)};//// DDSURFACEDESC2 flags that mark the validity of the struct data//#define DDSD_CAPS 0x00000001l // default#define DDSD_HEIGHT 0x00000002l // default#define DDSD_WIDTH 0x00000004l // default#define DDSD_PIXELFORMAT 0x00001000l // default#define DDSD_PITCH 0x00000008l // For uncompressed formats#define DDSD_MIPMAPCOUNT 0x00020000l#define DDSD_LINEARSIZE 0x00080000l // For compressed formats#define DDSD_DEPTH 0x00800000l // Volume Textures//// DDPIXELFORMAT flags//#define DDPF_ALPHAPIXELS 0x00000001l#define DDPF_FOURCC 0x00000004l // Compressed formats #define DDPF_RGB 0x00000040l // Uncompressed formats#define DDPF_ALPHA 0x00000002l#define DDPF_COMPRESSED 0x00000080l#define DDPF_LUMINANCE 0x00020000l#define DDPF_BUMPLUMINANCE 0x00040000l // L,U,V#define DDPF_BUMPDUDV 0x00080000l // U,V//// DDSCAPS flags//#define DDSCAPS_TEXTURE 0x00001000l // default#define DDSCAPS_COMPLEX 0x00000008l#define DDSCAPS_MIPMAP 0x00400000l#define DDSCAPS2_VOLUME 0x00200000l#ifndef MAKEFOURCC#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ ((UI32)(char)(ch0) | ((UI32)(char)(ch1) << 8) | \ ((UI32)(char)(ch2) << 16) | ((UI32)(char)(ch3) << 24 ))#endif //defined(MAKEFOURCC)/** FOURCC codes for DX compressed-texture pixel formats*/#define FOURCC_DXT1 (MAKEFOURCC('D','X','T','1'))#define FOURCC_DXT2 (MAKEFOURCC('D','X','T','2'))#define FOURCC_DXT3 (MAKEFOURCC('D','X','T','3'))#define FOURCC_DXT4 (MAKEFOURCC('D','X','T','4'))#define FOURCC_DXT5 (MAKEFOURCC('D','X','T','5'))osg::Image* ReadDDSFile(std::istream& _istream){ DDSURFACEDESC2 ddsd; char filecode[4]; _istream.read(filecode, 4); if (strncmp(filecode, "DDS ", 4) != 0) { return NULL; } // Get the surface desc. _istream.read((char*)(&ddsd), sizeof(ddsd)); // Size of 2d images - 3d images don't set dwLinearSize //###[afarre_051904] /*unsigned int size = ddsd.dwMipMapCount > 1 ? ddsd.dwLinearSize * (ddsd.ddpfPixelFormat.dwFourCC==FOURCC_DXT1 ? 2: 4) : ddsd.dwLinearSize; if(size <= 0) { osg::notify(osg::WARN)<<"Warning:: dwLinearSize is not defined in dds file, image not loaded."<<std::endl; return NULL; }*/ osg::ref_ptr<osg::Image> osgImage = new osg::Image(); //Check valid structure sizes if(ddsd.dwSize != 124 && ddsd.ddpfPixelFormat.dwSize != 32) { return NULL; } bool is3dImage = false; int depth = 1; // Check for volume image if( ddsd.dwDepth > 0 && (ddsd.dwFlags & DDSD_DEPTH)) { is3dImage = true; depth = ddsd.dwDepth; } // Retreive image properties. int s = ddsd.dwWidth; int t = ddsd.dwHeight; int r = depth; unsigned int dataType = GL_UNSIGNED_BYTE; unsigned int pixelFormat = 0; unsigned int internalFormat = 0; // Handle some esoteric formats if(ddsd.ddpfPixelFormat.dwFlags & DDPF_BUMPDUDV) { osg::notify(osg::WARN) << "ReadDDSFile warning: DDPF_BUMPDUDV format is not supported" << std::endl; return NULL;// ddsd.ddpfPixelFormat.dwFlags =// DDPF_LUMINANCE + DDPF_ALPHAPIXELS;// // handle V8U8 as A8L8// // handle V16U16 as A16L16// // but Q8W8U8L8 as RGB?// // A2W10U10V10 as RGBA (dwFlags == DDPF_BUMPDUDV + DDPF_ALPHAPIXELS) } if(ddsd.ddpfPixelFormat.dwFlags & DDPF_BUMPLUMINANCE) { osg::notify(osg::WARN) << "ReadDDSFile warning: DDPF_BUMPLUMINANCE format is not supported" << std::endl; return NULL;// ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;// // handle as RGB// // L6V5U5 -- 655 is not supported data type in GL// // X8L8V8U8 -- just as RGB } // Uncompressed formats will usually use DDPF_RGB to indicate an RGB format, // while compressed formats will use DDPF_FOURCC with a four-character code. bool usingAlpha = ddsd.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS; bool checkIfUsingOneBitAlpha = false; // Uncompressed formats. if(ddsd.ddpfPixelFormat.dwFlags & DDPF_RGB) { struct RGBFormat { const char* name; UI32 bitCount; UI32 rBitMask; UI32 gBitMask; UI32 bBitMask; UI32 aBitMask; unsigned int internalFormat; unsigned int pixelFormat; unsigned int dataType; }; const unsigned int UNSUPPORTED = 0; static const RGBFormat rgbFormats[] = { { "R3G3B2" , 8, 0xe0, 0x1c, 0x03, 0x00, GL_RGB , GL_RGB , GL_UNSIGNED_BYTE_3_3_2 }, { "R5G6B5" , 16, 0xf800, 0x07e0, 0x001f, 0x0000, GL_RGB , GL_RGB , GL_UNSIGNED_SHORT_5_6_5 }, { "A1R5G5B5" , 16, 0x7c00, 0x03e0, 0x001f, 0x8000, GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV }, { "X1R5G5B5" , 16, 0x7c00, 0x03e0, 0x001f, 0x0000, GL_RGB , GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV }, { "A4R4G4B4" , 16, 0x0f00, 0x00f0, 0x000f, 0xf000, GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV }, { "X4R4G4B4" , 16, 0x0f00, 0x00f0, 0x000f, 0x0000, GL_RGB , GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV }, { "A8R3G3B2" , 16, 0x00e0, 0x001c, 0x0003, 0xff00, GL_RGBA, GL_BGRA, UNSUPPORTED }, { "R8G8B8", 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000, GL_RGB , GL_BGR , GL_UNSIGNED_BYTE },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -