Work in progress:

- better support for DDS10 file format.
- support for RGBA pixel formats with more than 32 bits.
- support for pixel types other than UNORM.
pull/216/head
castano 16 years ago
parent 529c0075e1
commit 96655b3e7c

@ -1144,6 +1144,27 @@ uint DirectDrawSurface::blockSize() const
case FOURCC_RXGB:
case FOURCC_ATI2:
return 16;
case FOURCC_DX10:
switch(header.header10.dxgiFormat)
{
case DXGI_FORMAT_BC1_TYPELESS:
case DXGI_FORMAT_BC1_UNORM:
case DXGI_FORMAT_BC1_UNORM_SRGB:
case DXGI_FORMAT_BC4_TYPELESS:
case DXGI_FORMAT_BC4_UNORM:
case DXGI_FORMAT_BC4_SNORM:
return 8;
case DXGI_FORMAT_BC2_TYPELESS:
case DXGI_FORMAT_BC2_UNORM:
case DXGI_FORMAT_BC2_UNORM_SRGB:
case DXGI_FORMAT_BC3_TYPELESS:
case DXGI_FORMAT_BC3_UNORM:
case DXGI_FORMAT_BC3_UNORM_SRGB:
case DXGI_FORMAT_BC5_TYPELESS:
case DXGI_FORMAT_BC5_UNORM:
case DXGI_FORMAT_BC5_SNORM:
return 16;
};
};
// Not a block image.

@ -46,6 +46,8 @@ namespace nvtt
uint bmask;
uint amask;
PixelType pixelType;
nv::String externalCompressor;
// Quantization.

@ -323,80 +323,154 @@ bool Compressor::Private::outputHeader(const InputOptions::Private & inputOption
return true;
}
DDSHeader header;
header.setWidth(inputOptions.targetWidth);
header.setHeight(inputOptions.targetHeight);
int mipmapCount = inputOptions.realMipmapCount();
nvDebugCheck(mipmapCount > 0);
header.setMipmapCount(mipmapCount);
if (inputOptions.textureType == TextureType_2D) {
header.setTexture2D();
}
else if (inputOptions.textureType == TextureType_Cube) {
header.setTextureCube();
}
/*else if (inputOptions.textureType == TextureType_3D) {
header.setTexture3D();
header.setDepth(inputOptions.targetDepth);
}*/
if (compressionOptions.format == Format_RGBA)
{
header.setPitch(computePitch(inputOptions.targetWidth, compressionOptions.bitcount));
header.setPixelFormat(compressionOptions.bitcount, compressionOptions.rmask, compressionOptions.gmask, compressionOptions.bmask, compressionOptions.amask);
}
else
if (outputOptions.container == Container_DDS || outputOptions.container == Container_DDS10)
{
header.setLinearSize(computeImageSize(inputOptions.targetWidth, inputOptions.targetHeight, inputOptions.targetDepth, compressionOptions.bitcount, compressionOptions.format));
DDSHeader header;
header.setWidth(inputOptions.targetWidth);
header.setHeight(inputOptions.targetHeight);
if (compressionOptions.format == Format_DXT1 || compressionOptions.format == Format_DXT1a || compressionOptions.format == Format_DXT1n) {
header.setFourCC('D', 'X', 'T', '1');
if (inputOptions.isNormalMap) header.setNormalFlag(true);
}
else if (compressionOptions.format == Format_DXT3) {
header.setFourCC('D', 'X', 'T', '3');
}
else if (compressionOptions.format == Format_DXT5) {
header.setFourCC('D', 'X', 'T', '5');
}
else if (compressionOptions.format == Format_DXT5n) {
header.setFourCC('D', 'X', 'T', '5');
if (inputOptions.isNormalMap) header.setNormalFlag(true);
int mipmapCount = inputOptions.realMipmapCount();
nvDebugCheck(mipmapCount > 0);
header.setMipmapCount(mipmapCount);
bool supported = true;
if (outputOptions.container == Container_DDS10)
{
if (compressionOptions.format == Format_RGBA)
{
if (compressionOptions.bitcount == 16)
{
// B5G6R5_UNORM
// B5G5R5A1_UNORM
supported = false;
}
else if (compressionOptions.bitcount == 32)
{
// B8G8R8A8_UNORM
// B8G8R8X8_UNORM
// R8G8B8A8_UNORM
// R10G10B10A2_UNORM
supported = false;
}
else {
supported = false;
}
}
else
{
if (compressionOptions.format == Format_DXT1 || compressionOptions.format == Format_DXT1a || compressionOptions.format == Format_DXT1n) {
header.setDX10Format(71);
if (inputOptions.isNormalMap) header.setNormalFlag(true);
}
else if (compressionOptions.format == Format_DXT3) {
header.setDX10Format(74);
}
else if (compressionOptions.format == Format_DXT5) {
header.setDX10Format(77);
}
else if (compressionOptions.format == Format_DXT5n) {
header.setDX10Format(77);
if (inputOptions.isNormalMap) header.setNormalFlag(true);
}
else if (compressionOptions.format == Format_BC4) {
header.setDX10Format(80);
}
else if (compressionOptions.format == Format_BC5) {
header.setDX10Format(83);
if (inputOptions.isNormalMap) header.setNormalFlag(true);
}
else {
supported = false;
}
}
}
else if (compressionOptions.format == Format_BC4) {
header.setFourCC('A', 'T', 'I', '1');
else
{
if (compressionOptions.format == Format_RGBA)
{
header.setPitch(computePitch(inputOptions.targetWidth, compressionOptions.bitcount));
header.setPixelFormat(compressionOptions.bitcount, compressionOptions.rmask, compressionOptions.gmask, compressionOptions.bmask, compressionOptions.amask);
}
else
{
header.setLinearSize(computeImageSize(inputOptions.targetWidth, inputOptions.targetHeight, inputOptions.targetDepth, compressionOptions.bitcount, compressionOptions.format));
if (compressionOptions.format == Format_DXT1 || compressionOptions.format == Format_DXT1a || compressionOptions.format == Format_DXT1n) {
header.setFourCC('D', 'X', 'T', '1');
if (inputOptions.isNormalMap) header.setNormalFlag(true);
}
else if (compressionOptions.format == Format_DXT3) {
header.setFourCC('D', 'X', 'T', '3');
}
else if (compressionOptions.format == Format_DXT5) {
header.setFourCC('D', 'X', 'T', '5');
}
else if (compressionOptions.format == Format_DXT5n) {
header.setFourCC('D', 'X', 'T', '5');
if (inputOptions.isNormalMap) header.setNormalFlag(true);
}
else if (compressionOptions.format == Format_BC4) {
header.setFourCC('A', 'T', 'I', '1');
}
else if (compressionOptions.format == Format_BC5) {
header.setFourCC('A', 'T', 'I', '2');
if (inputOptions.isNormalMap) header.setNormalFlag(true);
}
else if (compressionOptions.format == Format_CTX1) {
header.setFourCC('C', 'T', 'X', '1');
if (inputOptions.isNormalMap) header.setNormalFlag(true);
}
else {
supported = false;
}
}
}
else if (compressionOptions.format == Format_BC5) {
header.setFourCC('A', 'T', 'I', '2');
if (inputOptions.isNormalMap) header.setNormalFlag(true);
if (!supported)
{
// This container does not support the requested format.
if (outputOptions.errorHandler != NULL)
{
outputOptions.errorHandler->error(Error_UnsupportedFeature);
}
return false;
}
else if (compressionOptions.format == Format_CTX1) {
header.setFourCC('C', 'T', 'X', '1');
if (inputOptions.isNormalMap) header.setNormalFlag(true);
if (inputOptions.textureType == TextureType_2D) {
header.setTexture2D();
}
else if (inputOptions.textureType == TextureType_Cube) {
header.setTextureCube();
}
/*else if (inputOptions.textureType == TextureType_3D) {
header.setTexture3D();
header.setDepth(inputOptions.targetDepth);
}*/
// Swap bytes if necessary.
header.swapBytes();
uint headerSize = 128;
if (header.hasDX10Header())
{
nvStaticCheck(sizeof(DDSHeader) == 128 + 20);
headerSize = 128 + 20;
}
}
// Swap bytes if necessary.
header.swapBytes();
uint headerSize = 128;
if (header.hasDX10Header())
{
nvStaticCheck(sizeof(DDSHeader) == 128 + 20);
headerSize = 128 + 20;
}
bool writeSucceed = outputOptions.outputHandler->writeData(&header, headerSize);
if (!writeSucceed && outputOptions.errorHandler != NULL)
{
outputOptions.errorHandler->error(Error_FileWrite);
bool writeSucceed = outputOptions.outputHandler->writeData(&header, headerSize);
if (!writeSucceed && outputOptions.errorHandler != NULL)
{
outputOptions.errorHandler->error(Error_FileWrite);
}
return writeSucceed;
}
return writeSucceed;
return true;
}

@ -43,6 +43,7 @@ void OutputOptions::reset()
m.outputHandler = NULL;
m.errorHandler = NULL;
m.outputHeader = true;
m.container = Container_DDS;
}
@ -72,6 +73,12 @@ void OutputOptions::setOutputHeader(bool outputHeader)
m.outputHeader = outputHeader;
}
/// Set container.
void OutputOptions::setContainer(Container container)
{
m.container = container;
}
bool OutputOptions::Private::openFile() const
{

@ -64,6 +64,7 @@ namespace nvtt
mutable OutputHandler * outputHandler;
ErrorHandler * errorHandler;
bool outputHeader;
Container container;
bool openFile() const;
void closeFile() const;

@ -87,6 +87,16 @@ namespace nvtt
Format_DXT1n,
Format_CTX1,
};
/// Pixel types.
enum PixelType
{
PixelType_UnsignedNorm,
PixelType_SignedNorm,
PixelType_UnsignedInt,
PixelType_SignedInt,
PixelType_Float,
};
/// Quality modes.
enum Quality
@ -115,10 +125,25 @@ namespace nvtt
// Set color mask to describe the RGB/RGBA format.
NVTT_API void setPixelFormat(unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask);
// As
NVTT_API void setPixelFormat2(unsigned int rsize, unsigned int gsize, unsigned int bsize, unsigned int asize);
NVTT_API void setPixelType(PixelType pixelType);
NVTT_API void setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold = 127);
};
/*
// DXGI_FORMAT_R16G16_FLOAT
compressionOptions.setPixelType(PixelType_Float);
compressionOptions.setPixelFormat2(16, 16, 0, 0);
// DXGI_FORMAT_R32G32B32A32_FLOAT
compressionOptions.setPixelType(PixelType_Float);
compressionOptions.setPixelFormat2(32, 32, 32, 32);
*/
/// Wrap modes.
enum WrapMode
@ -267,6 +292,13 @@ namespace nvtt
virtual void error(Error e) = 0;
};
/// Container.
enum Container
{
Container_DDS,
Container_DDS10,
};
/// Output Options. This class holds pointers to the interfaces that are used to report the output of
/// the compressor to the user.
@ -285,6 +317,7 @@ namespace nvtt
NVTT_API void setOutputHandler(OutputHandler * outputHandler);
NVTT_API void setErrorHandler(ErrorHandler * errorHandler);
NVTT_API void setOutputHeader(bool outputHeader);
NVTT_API void setContainer(Container container);
};

Loading…
Cancel
Save