📄 readerwriterdds.cpp
字号:
{ "B8G8R8", 24, 0x0000ff, 0x00ff00, 0xff0000, 0x000000, GL_RGB , GL_RGB , GL_UNSIGNED_BYTE }, { "A8R8G8B8", 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, GL_RGBA, GL_BGRA, GL_UNSIGNED_BYTE }, { "X8R8G8B8", 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000, GL_RGB , GL_BGRA, GL_UNSIGNED_BYTE }, { "A8B8G8R8", 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE }, { "X8B8G8R8", 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000, GL_RGB , GL_RGBA, GL_UNSIGNED_BYTE }, { "A2R10G10B10", 32, 0x000003ff, 0x000ffc00, 0x3ff00000, 0xc0000000, GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV }, { "A2B10G10R10", 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000, GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV }, { "G16R16", 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000, GL_RGB, UNSUPPORTED, GL_UNSIGNED_SHORT }, }; bool found = false; for ( unsigned int i = 0; i < sizeof ( rgbFormats ) / sizeof ( RGBFormat ); i++ ) { const RGBFormat& f = rgbFormats[ i ]; if ( ddsd.ddpfPixelFormat.dwRGBBitCount == f.bitCount && ddsd.ddpfPixelFormat.dwRBitMask == f.rBitMask && ddsd.ddpfPixelFormat.dwGBitMask == f.gBitMask && ddsd.ddpfPixelFormat.dwBBitMask == f.bBitMask && ddsd.ddpfPixelFormat.dwRGBAlphaBitMask == f.aBitMask ) { if ( f.internalFormat != UNSUPPORTED && f.pixelFormat != UNSUPPORTED && f.dataType != UNSUPPORTED ) { osg::notify(osg::INFO) << "ReadDDSFile info : format = " << f.name << std::endl; internalFormat = f.internalFormat; pixelFormat = f.pixelFormat; dataType = f.dataType; found = true; break; } else { osg::notify(osg::INFO) << "ReadDDSFile info : " << f.name << " format is not supported" << std::endl; return NULL; } } } if ( !found ) { osg::notify(osg::WARN) << "ReadDDSFile warning: unhandled RGB pixel format in dds file, image not loaded" << std::endl; osg::notify(osg::INFO) << "ReadDDSFile info : ddsd.ddpfPixelFormat.dwRGBBitCount = " << ddsd.ddpfPixelFormat.dwRGBBitCount << std::endl; osg::notify(osg::INFO) << "ReadDDSFile info : ddsd.ddpfPixelFormat.dwRBitMask = 0x" << std::hex << std::setw(8) << std::setfill('0') << ddsd.ddpfPixelFormat.dwRBitMask << std::endl; osg::notify(osg::INFO) << "ReadDDSFile info : ddsd.ddpfPixelFormat.dwGBitMask = 0x" << std::hex << std::setw(8) << std::setfill('0') << ddsd.ddpfPixelFormat.dwGBitMask << std::endl; osg::notify(osg::INFO) << "ReadDDSFile info : ddsd.ddpfPixelFormat.dwBBitMask = 0x" << std::hex << std::setw(8) << std::setfill('0') << ddsd.ddpfPixelFormat.dwBBitMask << std::endl; osg::notify(osg::INFO) << "ReadDDSFile info : ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0x" << std::hex << std::setw(8) << std::setfill('0') << ddsd.ddpfPixelFormat.dwRGBAlphaBitMask << std::dec << std::endl; return NULL; } } else if(ddsd.ddpfPixelFormat.dwFlags & DDPF_LUMINANCE) { internalFormat = usingAlpha ? GL_LUMINANCE_ALPHA : GL_LUMINANCE; pixelFormat = usingAlpha ? GL_LUMINANCE_ALPHA : GL_LUMINANCE; if ( usingAlpha && ddsd.ddpfPixelFormat.dwLuminanceBitDepth == 8 ) { osg::notify(osg::INFO) << "ReadDDSFile info : format = L4A4" << std::endl; pixelFormat = GL_LUMINANCE4_ALPHA4; // invalid enumerant? } else if ( usingAlpha && ddsd.ddpfPixelFormat.dwLuminanceBitDepth == 32 ) { osg::notify(osg::INFO) << "ReadDDSFile info : format = L16A16" << std::endl; dataType = GL_UNSIGNED_SHORT; } else if ( !usingAlpha && ddsd.ddpfPixelFormat.dwLuminanceBitDepth == 16 ) { osg::notify(osg::INFO) << "ReadDDSFile info : format = L16" << std::endl; dataType = GL_UNSIGNED_SHORT; } else if ( usingAlpha ) { osg::notify(osg::INFO) << "ReadDDSFile info : format = L8A8" << std::endl; } else { osg::notify(osg::INFO) << "ReadDDSFile info : format = L8" << std::endl; }// else if ( ddsd.ddpfPixelFormat.dwLuminanceBitDepth == (usingAlpha ? 64 : 32) )// {// dataType = GL_UNSIGNED_INT;// } } else if(ddsd.ddpfPixelFormat.dwFlags & DDPF_ALPHA) { osg::notify(osg::INFO) << "ReadDDSFile info : format = ALPHA" << std::endl; internalFormat = GL_ALPHA; pixelFormat = GL_ALPHA; } // Compressed formats else if(ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC) { // TODO: Image::isImageTranslucent() doesn't work with S3TC compressed files switch(ddsd.ddpfPixelFormat.dwFourCC) { case FOURCC_DXT1: osg::notify(osg::INFO) << "ReadDDSFile info : format = DXT1" << std::endl; if (usingAlpha) { internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; } else { internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; pixelFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; checkIfUsingOneBitAlpha = true; } break; case FOURCC_DXT3: osg::notify(osg::INFO) << "ReadDDSFile info : format = DXT3" << std::endl; internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; case FOURCC_DXT5: osg::notify(osg::INFO) << "ReadDDSFile info : format = DXT5" << std::endl; internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; case 0x00000024: // A16B16G16R16 osg::notify(osg::INFO) << "ReadDDSFile info : format = A16B16G16R16" << std::endl; internalFormat = GL_RGBA; pixelFormat = GL_RGBA; dataType = GL_UNSIGNED_SHORT; break; case 0x00000071: // A16B16G16R16F osg::notify(osg::INFO) << "ReadDDSFile info : format = A16B16G16R16F" << std::endl; internalFormat = GL_RGBA; // why no transparency? pixelFormat = GL_RGBA; dataType = GL_HALF_FLOAT_NV; break; case 0x0000006E: // Q16W16V16U16 osg::notify(osg::INFO) << "ReadDDSFile info : format = Q16W16V16U16" << std::endl; internalFormat = GL_RGBA; pixelFormat = GL_RGBA; dataType = GL_UNSIGNED_SHORT; break; case 0x00000070: // G16R16F osg::notify(osg::INFO) << "ReadDDSFile info : G16R16F format is not supported" << std::endl; return NULL;// internalFormat = GL_RGB;// pixelFormat = must be GL_RED and GL_GREEN// dataType = GL_HALF_FLOAT_NV; break; case 0x00000073: // G32R32F osg::notify(osg::INFO) << "ReadDDSFile info : G32R32F format is not supported" << std::endl; return NULL;// internalFormat = GL_RGB;// pixelFormat = must be GL_RED and GL_GREEN// dataType = GL_FLOAT; break; case 0x00000072: // R32F osg::notify(osg::INFO) << "ReadDDSFile info : format = R32F" << std::endl; internalFormat = GL_RGB; pixelFormat = GL_RED; dataType = GL_FLOAT; break; case 0x0000006F: // R16F osg::notify(osg::INFO) << "ReadDDSFile info : format = R16F" << std::endl; internalFormat = GL_RGB; pixelFormat = GL_RED; dataType = GL_HALF_FLOAT_NV; break; case 0x00000074: // A32B32G32R32F osg::notify(osg::INFO) << "ReadDDSFile info : format = A32B32G32R32F" << std::endl; internalFormat = GL_RGBA; pixelFormat = GL_RGBA; dataType = GL_FLOAT; break; case 0x00000075: // CxV8U8 osg::notify(osg::INFO) << "ReadDDSFile info : CxV8U8 format is not supported" << std::endl; return NULL; case MAKEFOURCC( 'U', 'Y', 'V', 'Y' ): // not supported in OSG case MAKEFOURCC( 'U', 'Y', 'V', '2' ): // not supported in OSG case MAKEFOURCC( 'R', 'G', 'B', 'G' ): // R8G8_B8G8 -- what is it? case MAKEFOURCC( 'G', 'R', 'G', 'B' ): // G8R8_G8B8 -- what is it? //break; default: osg::notify(osg::WARN) << "ReadDDSFile warning: unhandled FOURCC pixel format (" << (char)((ddsd.ddpfPixelFormat.dwFourCC & 0x000000ff)) << (char)((ddsd.ddpfPixelFormat.dwFourCC & 0x0000ff00) >> 8) << (char)((ddsd.ddpfPixelFormat.dwFourCC & 0x00ff0000) >> 16) << (char)((ddsd.ddpfPixelFormat.dwFourCC & 0xff000000) >> 24) << " = 0x" << std::hex << std::setw(8) << std::setfill('0') << ddsd.ddpfPixelFormat.dwFourCC << std::dec << ") in dds file, image not loaded." << std::endl; return NULL; } } else { osg::notify(osg::WARN) << "ReadDDSFile warning: unhandled pixel format (ddsd.ddpfPixelFormat.dwFlags" << " = 0x" << std::hex << std::setw(8) << std::setfill('0') << ddsd.ddpfPixelFormat.dwFlags << std::dec << ") in dds file, image not loaded."<<std::endl; return NULL; } //###[afarre_051904] /*if (is3dImage) size = osg::Image::computeNumComponents(pixelFormat) * ddsd.dwWidth * ddsd.dwHeight * depth; //delayed allocation og image data after all checks unsigned char* imageData = new unsigned char [size]; if(!imageData) { return NULL; } // Read image data _istream.read((char*)imageData, size); // NOTE: We need to set the image data before setting the mipmap data, this // is because the setImage method clears the _mipmapdata vector in osg::Image. // Set image data and properties. osgImage->setImage(s,t,r, internalFormat, pixelFormat, dataType, imageData, osg::Image::USE_NEW_DELETE); */ // Now set mipmap data (offsets into image raw data) //###[afarre_051904] osg::Image::MipmapDataType mipmaps; // Take care of mipmaps if any. if (ddsd.dwMipMapCount>1) { // Now set mipmap data (offsets into image raw data). //###[afarre_051904]osg::Image::MipmapDataType mipmaps; //This is to complete mipmap sequence until level Nx1 //debugging messages float power2_s = logf((float)s)/logf((float)2); float power2_t = logf((float)t)/logf((float)2); osg::notify(osg::NOTICE) << "ReadDDSFile NOTICE : ddsd.dwMipMapCount = "<<ddsd.dwMipMapCount<<std::endl; osg::notify(osg::NOTICE) << "ReadDDSFile NOTICE : s = "<<s<<std::endl; osg::notify(osg::NOTICE) << "ReadDDSFile NOTICE : t = "<<t<<std::endl; osg::notify(osg::NOTICE) << "ReadDDSFile NOTICE : power2_s="<<power2_s<<std::endl; osg::notify(osg::NOTICE) << "ReadDDSFile NOTICE : power2_t="<<power2_t<<std::endl; mipmaps.resize((unsigned int)osg::maximum(power2_s,power2_t),0); // Handle S3TC compressed mipmaps. if( (ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && (ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT1 || ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT3 || ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT5)) { int width = ddsd.dwWidth; int height = ddsd.dwHeight; int blockSize = (ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT1) ? 8 : 16; int offset = 0; for (unsigned int k = 1; k < ddsd.dwMipMapCount && (width || height); ++k) { if (width == 0) width = 1; if (height == 0) height = 1; offset += (((width+3)/4) * ((height+3)/4) * blockSize); mipmaps[k-1] = offset; width >>= 1; height >>= 1; } //###[afarre_051904] osgImage->setMipmapData(mipmaps); } // Handle uncompressed mipmaps else { int offset = 0; int width = ddsd.dwWidth; int height = ddsd.dwHeight; for (unsigned int k = 1; k < ddsd.dwMipMapCount && (width || height); ++k) { if (width == 0) width = 1; if (height == 0) height = 1; offset += height * osg::Image::computeRowWidthInBytes( width, pixelFormat, dataType, 1 ); mipmaps[k-1] = offset; width >>= 1; height >>= 1; } //###[afarre_051904] osgImage->setMipmapData(mipmaps); } } osgImage->setImage(s,t,r, internalFormat, pixelFormat, dataType, 0, osg::Image::USE_NEW_DELETE); if (mipmaps.size()>0) osgImage->setMipmapLevels(mipmaps); unsigned int size = osgImage->getTotalSizeInBytesIncludingMipmaps(); osg::notify(osg::NOTICE) << "ReadDDSFile NOTICE : size = " << size << std::endl; if(size <= 0) { osg::notify(osg::WARN) << "ReadDDSFile warning: size <= 0" << std::endl; return NULL; } unsigned char* imageData = new unsigned char [size]; if(!imageData) { osg::notify(osg::WARN) << "ReadDDSFile warning: imageData == NULL" << std::endl; return NULL; } // Read image data _istream.read((char*)imageData, size); // Check if alpha information embedded in the 8-byte encoding blocks if (checkIfUsingOneBitAlpha) { const DXT1TexelsBlock *texelsBlock = reinterpret_cast<const DXT1TexelsBlock*>(imageData);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -