More work toward 2.1: Implement InputOptions using TexImage.
This commit is contained in:
parent
8838b5220a
commit
1e2567e4a3
@ -35,7 +35,7 @@
|
|||||||
# include <signal.h>
|
# include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if NV_OS_LINUX || NV_OS_DARWIN
|
#if NV_OS_LINUX || NV_OS_DARWIN || NV_OS_FREEBSD
|
||||||
# include <unistd.h> // getpid
|
# include <unistd.h> // getpid
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -294,13 +294,13 @@ namespace
|
|||||||
# if NV_CC_GNUC // defined(HAVE_CXXABI_H)
|
# if NV_CC_GNUC // defined(HAVE_CXXABI_H)
|
||||||
char * begin = strchr(string_array[i], '(');
|
char * begin = strchr(string_array[i], '(');
|
||||||
char * end = strchr(string_array[i], '+');
|
char * end = strchr(string_array[i], '+');
|
||||||
if( begin != 0 && begin < end ) {
|
if (begin != 0 && begin < end) {
|
||||||
int stat;
|
int stat;
|
||||||
*end = '\0';
|
*end = '\0';
|
||||||
*begin = '\0';
|
*begin = '\0';
|
||||||
char * module = string_array[i];
|
char * module = string_array[i];
|
||||||
char * name = abi::__cxa_demangle(begin+1, 0, 0, &stat);
|
char * name = abi::__cxa_demangle(begin+1, 0, 0, &stat);
|
||||||
if( name == NULL || begin[1] != '_' || begin[2] != 'Z' ) {
|
if (name == NULL || stat != 0) {
|
||||||
nvDebug( " In: [%s] '%s'\n", module, begin+1 );
|
nvDebug( " In: [%s] '%s'\n", module, begin+1 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -166,8 +166,8 @@ namespace nv
|
|||||||
inline float square(float f) { return f * f; }
|
inline float square(float f) { return f * f; }
|
||||||
inline int square(int i) { return i * i; }
|
inline int square(int i) { return i * i; }
|
||||||
|
|
||||||
inline float cube(float f) { return f * f; }
|
inline float cube(float f) { return f * f * f; }
|
||||||
inline int cube(int i) { return i * i; }
|
inline int cube(int i) { return i * i * i; }
|
||||||
|
|
||||||
// @@ Float to int conversions to be optimized at some point. See:
|
// @@ Float to int conversions to be optimized at some point. See:
|
||||||
// http://cbloomrants.blogspot.com/2009/01/01-17-09-float-to-int.html
|
// http://cbloomrants.blogspot.com/2009/01/01-17-09-float-to-int.html
|
||||||
@ -194,6 +194,33 @@ namespace nv
|
|||||||
return f - floor(f);
|
return f - floor(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline float fround(float f)
|
||||||
|
{
|
||||||
|
// @@ Do something better.
|
||||||
|
return float(iround(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float quantizeCeil(float f, int bits)
|
||||||
|
{
|
||||||
|
nvDebugCheck(f >= 0.0f && f <= 1.0f);
|
||||||
|
float scale = float(1 << bits);
|
||||||
|
return ceilf(f * scale) / scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float quantizeRound(float f, int bits)
|
||||||
|
{
|
||||||
|
nvDebugCheck(f >= 0.0f && f <= 1.0f);
|
||||||
|
float scale = float(1 << bits);
|
||||||
|
return fround(f * scale) / scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float quantizeFloor(float f, int bits)
|
||||||
|
{
|
||||||
|
nvDebugCheck(f >= 0.0f && f <= 1.0f);
|
||||||
|
float scale = float(1 << bits);
|
||||||
|
return floor(f * scale) / scale;
|
||||||
|
}
|
||||||
|
|
||||||
} // nv
|
} // nv
|
||||||
|
|
||||||
#endif // NV_MATH_H
|
#endif // NV_MATH_H
|
||||||
|
@ -32,7 +32,7 @@ namespace nv
|
|||||||
struct CompressorInterface
|
struct CompressorInterface
|
||||||
{
|
{
|
||||||
virtual ~CompressorInterface() {}
|
virtual ~CompressorInterface() {}
|
||||||
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) = 0;
|
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * rgba, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // nv namespace
|
} // nv namespace
|
||||||
|
@ -95,13 +95,6 @@ namespace nv
|
|||||||
|
|
||||||
|
|
||||||
// External compressors.
|
// External compressors.
|
||||||
#if defined(HAVE_S3QUANT)
|
|
||||||
struct S3CompressorDXT1 : public CompressorInterface
|
|
||||||
{
|
|
||||||
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_ATITC)
|
#if defined(HAVE_ATITC)
|
||||||
struct AtiCompressorDXT1 : public CompressorInterface
|
struct AtiCompressorDXT1 : public CompressorInterface
|
||||||
{
|
{
|
||||||
|
@ -44,7 +44,7 @@ using namespace nv;
|
|||||||
using namespace nvtt;
|
using namespace nvtt;
|
||||||
|
|
||||||
|
|
||||||
void FixedBlockCompressor::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
|
void FixedBlockCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
|
||||||
{
|
{
|
||||||
const uint bs = blockSize();
|
const uint bs = blockSize();
|
||||||
const uint bw = (w + 3) / 4;
|
const uint bw = (w + 3) / 4;
|
||||||
@ -68,13 +68,7 @@ void FixedBlockCompressor::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
|
|||||||
for (uint x = 0; x < w; x += 4) {
|
for (uint x = 0; x < w; x += 4) {
|
||||||
|
|
||||||
ColorBlock rgba;
|
ColorBlock rgba;
|
||||||
if (inputFormat == nvtt::InputFormat_BGRA_8UB) {
|
rgba.init(w, h, data, x, y);
|
||||||
rgba.init(w, h, (const uint *)data, x, y);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nvDebugCheck(inputFormat == nvtt::InputFormat_RGBA_32F);
|
|
||||||
rgba.init(w, h, (const float *)data, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
compressBlock(rgba, alphaMode, compressionOptions, mem);
|
compressBlock(rgba, alphaMode, compressionOptions, mem);
|
||||||
|
|
||||||
@ -99,13 +93,7 @@ void FixedBlockCompressor::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
|
|||||||
const uint y = i / bw;
|
const uint y = i / bw;
|
||||||
|
|
||||||
ColorBlock rgba;
|
ColorBlock rgba;
|
||||||
if (inputFormat == nvtt::InputFormat_BGRA_8UB) {
|
rgba.init(w, h, data, 4*x, 4*y);
|
||||||
rgba.init(w, h, (uint *)data, 4*x, 4*y);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nvDebugCheck(inputFormat == nvtt::InputFormat_RGBA_32F);
|
|
||||||
rgba.init(w, h, (float *)data, 4*x, 4*y);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8 * ptr = mem + (y * bw + x) * bs;
|
uint8 * ptr = mem + (y * bw + x) * bs;
|
||||||
compressBlock(rgba, alphaMode, compressionOptions, ptr);
|
compressBlock(rgba, alphaMode, compressionOptions, ptr);
|
||||||
@ -124,7 +112,7 @@ void FixedBlockCompressor::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
|
|||||||
|
|
||||||
#include "bc6h/tile.h"
|
#include "bc6h/tile.h"
|
||||||
|
|
||||||
void TileCompressor::compress(InputFormat inputFormat, AlphaMode alphaMode, uint w, uint h, const void * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions)
|
void TileCompressor::compress(AlphaMode alphaMode, uint w, uint h, const float * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions)
|
||||||
{
|
{
|
||||||
const uint bs = blockSize();
|
const uint bs = blockSize();
|
||||||
const uint bw = (w + 3) / 4;
|
const uint bw = (w + 3) / 4;
|
||||||
@ -141,13 +129,7 @@ void TileCompressor::compress(InputFormat inputFormat, AlphaMode alphaMode, uint
|
|||||||
for (uint x = 0; x < w; x += 4) {
|
for (uint x = 0; x < w; x += 4) {
|
||||||
|
|
||||||
Tile tile;
|
Tile tile;
|
||||||
if (inputFormat == nvtt::InputFormat_BGRA_8UB) {
|
|
||||||
//tile.init((const uint *)data, w, h, x, y);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nvDebugCheck(inputFormat == nvtt::InputFormat_RGBA_32F);
|
|
||||||
//tile.init((const float *)data, w, h, x, y);
|
//tile.init((const float *)data, w, h, x, y);
|
||||||
}
|
|
||||||
|
|
||||||
compressBlock(tile, alphaMode, compressionOptions, mem);
|
compressBlock(tile, alphaMode, compressionOptions, mem);
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ namespace nv
|
|||||||
|
|
||||||
struct FixedBlockCompressor : public CompressorInterface
|
struct FixedBlockCompressor : public CompressorInterface
|
||||||
{
|
{
|
||||||
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
|
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * rgba, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
|
||||||
|
|
||||||
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0;
|
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0;
|
||||||
virtual uint blockSize() const = 0;
|
virtual uint blockSize() const = 0;
|
||||||
@ -42,7 +42,7 @@ namespace nv
|
|||||||
|
|
||||||
struct TileCompressor : public CompressorInterface
|
struct TileCompressor : public CompressorInterface
|
||||||
{
|
{
|
||||||
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
|
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * rgba, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
|
||||||
|
|
||||||
virtual void compressBlock(Tile & tile, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0;
|
virtual void compressBlock(Tile & tile, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0;
|
||||||
virtual uint blockSize() const = 0;
|
virtual uint blockSize() const = 0;
|
||||||
|
@ -121,8 +121,10 @@ namespace
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
|
void PixelFormatConverter::compress(nvtt::AlphaMode /*alphaMode*/, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
|
||||||
{
|
{
|
||||||
|
nvDebugCheck (compressionOptions.format == nvtt::Format_RGBA);
|
||||||
|
|
||||||
uint bitCount;
|
uint bitCount;
|
||||||
uint rmask, rshift, rsize;
|
uint rmask, rshift, rsize;
|
||||||
uint gmask, gshift, gsize;
|
uint gmask, gshift, gsize;
|
||||||
@ -193,37 +195,14 @@ void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
|
|||||||
const uint * src = (const uint *)data + y * w;
|
const uint * src = (const uint *)data + y * w;
|
||||||
const float * fsrc = (const float *)data + y * w;
|
const float * fsrc = (const float *)data + y * w;
|
||||||
|
|
||||||
if (inputFormat == nvtt::InputFormat_BGRA_8UB && compressionOptions.pixelType == nvtt::PixelType_UnsignedNorm && bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0xFF000000)
|
|
||||||
{
|
|
||||||
convert_to_a8r8g8b8(src, dst, w);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BitStream stream(dst);
|
BitStream stream(dst);
|
||||||
|
|
||||||
for (uint x = 0; x < w; x++)
|
for (uint x = 0; x < w; x++)
|
||||||
{
|
{
|
||||||
float r, g, b, a;
|
float r = fsrc[x + 0 * wh];
|
||||||
|
float g = fsrc[x + 1 * wh];
|
||||||
if (inputFormat == nvtt::InputFormat_BGRA_8UB) {
|
float b = fsrc[x + 2 * wh];
|
||||||
Color32 c = Color32(src[x]);
|
float a = fsrc[x + 3 * wh];
|
||||||
r = float(c.r) / 255.0f;
|
|
||||||
g = float(c.g) / 255.0f;
|
|
||||||
b = float(c.b) / 255.0f;
|
|
||||||
a = float(c.a) / 255.0f;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nvDebugCheck (inputFormat == nvtt::InputFormat_RGBA_32F);
|
|
||||||
|
|
||||||
//r = ((float *)src)[4 * x + 0]; // Color components not interleaved.
|
|
||||||
//g = ((float *)src)[4 * x + 1];
|
|
||||||
//b = ((float *)src)[4 * x + 2];
|
|
||||||
//a = ((float *)src)[4 * x + 3];
|
|
||||||
r = fsrc[x + 0 * wh];
|
|
||||||
g = fsrc[x + 1 * wh];
|
|
||||||
b = fsrc[x + 2 * wh];
|
|
||||||
a = fsrc[x + 3 * wh];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (compressionOptions.pixelType == nvtt::PixelType_Float)
|
if (compressionOptions.pixelType == nvtt::PixelType_Float)
|
||||||
{
|
{
|
||||||
@ -274,7 +253,6 @@ void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
|
|||||||
{
|
{
|
||||||
*(dst + x) = 0;
|
*(dst + x) = 0;
|
||||||
}*/
|
}*/
|
||||||
}
|
|
||||||
|
|
||||||
outputOptions.writeData(dst, pitch);
|
outputOptions.writeData(dst, pitch);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ namespace nv
|
|||||||
{
|
{
|
||||||
struct PixelFormatConverter : public CompressorInterface
|
struct PixelFormatConverter : public CompressorInterface
|
||||||
{
|
{
|
||||||
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
|
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // nv namespace
|
} // nv namespace
|
||||||
|
@ -55,7 +55,7 @@ static Color32 toRgbe8(float r, float g, float b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CompressorRGBE::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
|
void CompressorRGBE::compress(nvtt::AlphaMode /*alphaMode*/, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
|
||||||
{
|
{
|
||||||
nvDebugCheck (compressionOptions.format == nvtt::Format_RGBE);
|
nvDebugCheck (compressionOptions.format == nvtt::Format_RGBE);
|
||||||
|
|
||||||
@ -67,27 +67,13 @@ void CompressorRGBE::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alp
|
|||||||
|
|
||||||
for (uint y = 0; y < h; y++)
|
for (uint y = 0; y < h; y++)
|
||||||
{
|
{
|
||||||
const uint * src = (const uint *)data + y * srcPitch;
|
const float * src = (const float *)data + y * srcPitch;
|
||||||
const float * fsrc = (const float *)data + y * srcPitch;
|
|
||||||
|
|
||||||
for (uint x = 0; x < w; x++)
|
for (uint x = 0; x < w; x++)
|
||||||
{
|
{
|
||||||
float r, g, b;
|
float r = src[x + 0 * srcPlane];
|
||||||
|
float g = src[x + 1 * srcPlane];
|
||||||
if (inputFormat == nvtt::InputFormat_BGRA_8UB) {
|
float b = src[x + 2 * srcPlane];
|
||||||
Color32 c = Color32(src[x]);
|
|
||||||
r = float(c.r) / 255.0f;
|
|
||||||
g = float(c.g) / 255.0f;
|
|
||||||
b = float(c.b) / 255.0f;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nvDebugCheck (inputFormat == nvtt::InputFormat_RGBA_32F);
|
|
||||||
|
|
||||||
// Color components not interleaved.
|
|
||||||
r = fsrc[x + 0 * srcPlane];
|
|
||||||
g = fsrc[x + 1 * srcPlane];
|
|
||||||
b = fsrc[x + 2 * srcPlane];
|
|
||||||
}
|
|
||||||
|
|
||||||
dst[x] = toRgbe8(r, g, b);
|
dst[x] = toRgbe8(r, g, b);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ namespace nv
|
|||||||
{
|
{
|
||||||
struct CompressorRGBE : public CompressorInterface
|
struct CompressorRGBE : public CompressorInterface
|
||||||
{
|
{
|
||||||
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
|
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // nv namespace
|
} // nv namespace
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -43,37 +43,32 @@ namespace nvtt
|
|||||||
{
|
{
|
||||||
Private() {}
|
Private() {}
|
||||||
|
|
||||||
|
bool compress(const TexImage & tex, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
||||||
bool compress(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
bool compress(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
||||||
|
bool compress(AlphaMode alphaMode, int w, int h, int d, const float * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
||||||
|
|
||||||
bool compress2D(InputFormat inputFormat, AlphaMode alphaMode, int w, int h, const void * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
//int estimateSize(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions) const;
|
||||||
|
|
||||||
int estimateSize(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions) const;
|
|
||||||
|
|
||||||
bool outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
|
bool outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
||||||
bool outputHeader(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
bool outputHeader(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
||||||
|
|
||||||
nv::CompressorInterface * chooseCpuCompressor(const CompressionOptions::Private & compressionOptions) const;
|
nv::CompressorInterface * chooseCpuCompressor(const CompressionOptions::Private & compressionOptions) const;
|
||||||
nv::CompressorInterface * chooseGpuCompressor(const CompressionOptions::Private & compressionOptions) const;
|
nv::CompressorInterface * chooseGpuCompressor(const CompressionOptions::Private & compressionOptions) const;
|
||||||
|
|
||||||
bool compressMipmaps(uint f, const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
//bool compressMipmaps(uint f, const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
||||||
|
|
||||||
bool initMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f, uint m) const;
|
//bool initMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f, uint m) const;
|
||||||
|
|
||||||
int findExactMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const;
|
//int findExactMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const;
|
||||||
int findClosestMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const;
|
//int findClosestMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const;
|
||||||
|
|
||||||
void downsampleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions) const;
|
//void downsampleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions) const;
|
||||||
void scaleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d) const;
|
//void scaleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d) const;
|
||||||
void premultiplyAlphaMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions) const;
|
//void premultiplyAlphaMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions) const;
|
||||||
void processInputImage(Mipmap & mipmap, const InputOptions::Private & inputOptions) const;
|
//void processInputImage(Mipmap & mipmap, const InputOptions::Private & inputOptions) const;
|
||||||
void quantizeMipmap(Mipmap & mipmap, const CompressionOptions::Private & compressionOptions) const;
|
//void quantizeMipmap(Mipmap & mipmap, const CompressionOptions::Private & compressionOptions) const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
bool cudaSupported;
|
bool cudaSupported;
|
||||||
bool cudaEnabled;
|
bool cudaEnabled;
|
||||||
|
|
||||||
|
@ -102,11 +102,6 @@ void InputOptions::reset()
|
|||||||
m.inputGamma = 2.2f;
|
m.inputGamma = 2.2f;
|
||||||
m.outputGamma = 2.2f;
|
m.outputGamma = 2.2f;
|
||||||
|
|
||||||
m.colorTransform = ColorTransform_None;
|
|
||||||
m.linearTransform = Matrix(identity);
|
|
||||||
for (int i = 0; i < 4; i++) m.colorOffsets[i] = 0;
|
|
||||||
for (int i = 0; i < 4; i++) m.swizzleTransform[i] = i;
|
|
||||||
|
|
||||||
m.generateMipmaps = true;
|
m.generateMipmaps = true;
|
||||||
m.maxLevel = -1;
|
m.maxLevel = -1;
|
||||||
m.mipmapFilter = MipmapFilter_Box;
|
m.mipmapFilter = MipmapFilter_Box;
|
||||||
@ -123,8 +118,6 @@ void InputOptions::reset()
|
|||||||
|
|
||||||
m.maxExtent = 0;
|
m.maxExtent = 0;
|
||||||
m.roundMode = RoundMode_None;
|
m.roundMode = RoundMode_None;
|
||||||
|
|
||||||
m.premultiplyAlpha = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -145,15 +138,19 @@ void InputOptions::setTextureLayout(TextureType type, int width, int height, int
|
|||||||
resetTextureLayout();
|
resetTextureLayout();
|
||||||
|
|
||||||
m.textureType = type;
|
m.textureType = type;
|
||||||
|
m.width = width;
|
||||||
|
m.height = height;
|
||||||
|
m.depth = depth;
|
||||||
|
|
||||||
// Allocate images.
|
// Allocate images.
|
||||||
|
m.faceCount = (type == TextureType_2D) ? 1 : 6;
|
||||||
m.mipmapCount = countMipmaps(width, height, depth);
|
m.mipmapCount = countMipmaps(width, height, depth);
|
||||||
m.faceCount = (type == TextureType_Cube) ? 6 : 1;
|
|
||||||
m.imageCount = m.mipmapCount * m.faceCount;
|
m.imageCount = m.mipmapCount * m.faceCount;
|
||||||
|
m.images = new void *[m.imageCount];
|
||||||
|
|
||||||
m.images = new Private::InputImage[m.imageCount];
|
memset(m.images, 0, sizeof(void *) * m.imageCount);
|
||||||
|
|
||||||
for(uint f = 0; f < m.faceCount; f++)
|
/*for (uint f = 0; f < m.faceCount; f++)
|
||||||
{
|
{
|
||||||
uint w = width;
|
uint w = width;
|
||||||
uint h = height;
|
uint h = height;
|
||||||
@ -175,7 +172,7 @@ void InputOptions::setTextureLayout(TextureType type, int width, int height, int
|
|||||||
h = max(1U, h / 2);
|
h = max(1U, h / 2);
|
||||||
d = max(1U, d / 2);
|
d = max(1U, d / 2);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -197,121 +194,59 @@ void InputOptions::resetTextureLayout()
|
|||||||
// Copies the data to our internal structures.
|
// Copies the data to our internal structures.
|
||||||
bool InputOptions::setMipmapData(const void * data, int width, int height, int depth /*= 1*/, int face /*= 0*/, int mipLevel /*= 0*/)
|
bool InputOptions::setMipmapData(const void * data, int width, int height, int depth /*= 1*/, int face /*= 0*/, int mipLevel /*= 0*/)
|
||||||
{
|
{
|
||||||
nvCheck(depth == 1);
|
if (depth != 1) {
|
||||||
|
return false;
|
||||||
const int idx = face * m.mipmapCount + mipLevel;
|
}
|
||||||
|
if (face >= m.faceCount) {
|
||||||
if (m.images[idx].width != width || m.images[idx].height != height || m.images[idx].depth != depth || m.images[idx].mipLevel != mipLevel || m.images[idx].face != face)
|
return false;
|
||||||
{
|
}
|
||||||
// Invalid dimension or index.
|
if (mipLevel >= m.mipmapCount) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(m.inputFormat)
|
const int idx = mipLevel * m.faceCount + face;
|
||||||
{
|
if (idx >= m.imageCount) {
|
||||||
case InputFormat_BGRA_8UB:
|
|
||||||
if (Image * image = new nv::Image())
|
|
||||||
{
|
|
||||||
image->allocate(width, height);
|
|
||||||
memcpy(image->pixels(), data, width * height * 4);
|
|
||||||
m.images[idx].uint8data = image;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// @@ Out of memory error.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputFormat_RGBA_32F:
|
|
||||||
if (FloatImage * image = new nv::FloatImage())
|
|
||||||
{
|
|
||||||
const float * floatData = (const float *)data;
|
|
||||||
image->allocate(4, width, height);
|
|
||||||
|
|
||||||
for (int c = 0; c < 4; c++)
|
|
||||||
{
|
|
||||||
float * channel = image->channel(c);
|
|
||||||
for (int i = 0; i < width * height; i++)
|
|
||||||
{
|
|
||||||
channel[i] = floatData[i*4 + c];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m.images[idx].floatdata = image;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// @@ Out of memory error.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
// Compute expected width, height and depth for this mipLevel. Return false if it doesn't match.
|
||||||
}
|
int w = m.width;
|
||||||
|
int h = m.height;
|
||||||
|
int d = m.depth;
|
||||||
// Copies data
|
for (int i = 0; i < mipLevel; i++) {
|
||||||
bool InputOptions::setMipmapChannelData(const void * data, int channel, int width, int height, int depth /*= 1*/, int face /*= 0*/, int mipLevel /*= 0*/)
|
w = max(1, w/2);
|
||||||
{
|
h = max(1, h/2);
|
||||||
nvCheck(depth == 1);
|
d = max(1, d/2);
|
||||||
nvCheck(channel >= 0 && channel < 4);
|
}
|
||||||
|
if (w != width || h != height || d != depth) {
|
||||||
const int idx = face * m.mipmapCount + mipLevel;
|
|
||||||
|
|
||||||
if (m.images[idx].width != width || m.images[idx].height != height || m.images[idx].depth != depth || m.images[idx].mipLevel != mipLevel || m.images[idx].face != face)
|
|
||||||
{
|
|
||||||
// Invalid dimension or index.
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate image if not allocated already.
|
int imageSize = width * height * depth * 4;
|
||||||
if (m.inputFormat == InputFormat_BGRA_8UB)
|
if (m.inputFormat == InputFormat_BGRA_8UB)
|
||||||
{
|
{
|
||||||
m.images[idx].floatdata = NULL;
|
imageSize *= sizeof(uint8);
|
||||||
if (m.images[idx].uint8data == NULL)
|
|
||||||
{
|
|
||||||
m.images[idx].uint8data = new Image();
|
|
||||||
m.images[idx].uint8data->allocate(width, height);
|
|
||||||
m.images[idx].uint8data->fill(Color32(0,0,0,0));
|
|
||||||
}
|
}
|
||||||
|
else if (m.inputFormat == InputFormat_RGBA_16F)
|
||||||
|
{
|
||||||
|
imageSize *= sizeof(uint16);
|
||||||
}
|
}
|
||||||
else if (m.inputFormat == InputFormat_RGBA_32F)
|
else if (m.inputFormat == InputFormat_RGBA_32F)
|
||||||
{
|
{
|
||||||
m.images[idx].uint8data = NULL;
|
imageSize *= sizeof(float);
|
||||||
if (m.images[idx].floatdata == NULL)
|
|
||||||
{
|
|
||||||
m.images[idx].floatdata = new FloatImage();
|
|
||||||
m.images[idx].floatdata->allocate(4, width, height);
|
|
||||||
m.images[idx].floatdata->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m.images[idx].floatdata = NULL;
|
|
||||||
m.images[idx].uint8data = NULL;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy channel data to image.
|
m.images[idx] = new uint8[imageSize];
|
||||||
if (m.inputFormat == InputFormat_BGRA_8UB)
|
if (m.images[idx] == NULL) {
|
||||||
{
|
// Out of memory.
|
||||||
// @@ TODO
|
return false;
|
||||||
}
|
}
|
||||||
else if (m.inputFormat == InputFormat_RGBA_32F)
|
|
||||||
{
|
|
||||||
const float * floatData = (const float *)data;
|
|
||||||
float * channelPtr = m.images[idx].floatdata->channel(channel);
|
|
||||||
|
|
||||||
for (int i = 0; i < width * height; i++)
|
memcpy(m.images[idx], data, imageSize);
|
||||||
{
|
|
||||||
channelPtr[i] = floatData[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -400,45 +335,6 @@ void InputOptions::setNormalizeMipmaps(bool normalize)
|
|||||||
m.normalizeMipmaps = normalize;
|
m.normalizeMipmaps = normalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set color transform.
|
|
||||||
void InputOptions::setColorTransform(ColorTransform t)
|
|
||||||
{
|
|
||||||
m.colorTransform = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set linear transform for the given channel.
|
|
||||||
void InputOptions::setLinearTransform(int channel, float w0, float w1, float w2, float w3)
|
|
||||||
{
|
|
||||||
nvCheck(channel >= 0 && channel < 4);
|
|
||||||
|
|
||||||
m.linearTransform(channel, 0) = w0;
|
|
||||||
m.linearTransform(channel, 1) = w1;
|
|
||||||
m.linearTransform(channel, 2) = w2;
|
|
||||||
m.linearTransform(channel, 3) = w3;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputOptions::setLinearTransform(int channel, float w0, float w1, float w2, float w3, float offset)
|
|
||||||
{
|
|
||||||
nvCheck(channel >= 0 && channel < 4);
|
|
||||||
|
|
||||||
setLinearTransform(channel, w0, w1, w2, w3);
|
|
||||||
|
|
||||||
m.colorOffsets[channel] = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputOptions::setSwizzleTransform(int x, int y, int z, int w)
|
|
||||||
{
|
|
||||||
nvCheck(x >= 0 && x <= 6);
|
|
||||||
nvCheck(y >= 0 && y <= 6);
|
|
||||||
nvCheck(z >= 0 && z <= 6);
|
|
||||||
nvCheck(w >= 0 && w <= 6);
|
|
||||||
|
|
||||||
m.swizzleTransform[0] = x;
|
|
||||||
m.swizzleTransform[1] = y;
|
|
||||||
m.swizzleTransform[2] = z;
|
|
||||||
m.swizzleTransform[3] = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputOptions::setMaxExtents(int e)
|
void InputOptions::setMaxExtents(int e)
|
||||||
{
|
{
|
||||||
nvDebugCheck(e > 0);
|
nvDebugCheck(e > 0);
|
||||||
@ -449,107 +345,3 @@ void InputOptions::setRoundMode(RoundMode mode)
|
|||||||
{
|
{
|
||||||
m.roundMode = mode;
|
m.roundMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputOptions::setPremultiplyAlpha(bool b)
|
|
||||||
{
|
|
||||||
m.premultiplyAlpha = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputOptions::Private::computeTargetExtents() const
|
|
||||||
{
|
|
||||||
nvCheck(images != NULL);
|
|
||||||
|
|
||||||
uint maxExtent = this->maxExtent;
|
|
||||||
if (roundMode != RoundMode_None)
|
|
||||||
{
|
|
||||||
// rounded max extent should never be higher than original max extent.
|
|
||||||
maxExtent = previousPowerOfTwo(maxExtent);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint w = images->width;
|
|
||||||
uint h = images->height;
|
|
||||||
uint d = images->depth;
|
|
||||||
|
|
||||||
nvDebugCheck(w > 0);
|
|
||||||
nvDebugCheck(h > 0);
|
|
||||||
nvDebugCheck(d > 0);
|
|
||||||
|
|
||||||
// Scale extents without changing aspect ratio.
|
|
||||||
uint maxwhd = max(max(w, h), d);
|
|
||||||
if (maxExtent != 0 && maxwhd > maxExtent)
|
|
||||||
{
|
|
||||||
w = max((w * maxExtent) / maxwhd, 1U);
|
|
||||||
h = max((h * maxExtent) / maxwhd, 1U);
|
|
||||||
d = max((d * maxExtent) / maxwhd, 1U);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Round to power of two.
|
|
||||||
if (roundMode == RoundMode_ToNextPowerOfTwo)
|
|
||||||
{
|
|
||||||
w = nextPowerOfTwo(w);
|
|
||||||
h = nextPowerOfTwo(h);
|
|
||||||
d = nextPowerOfTwo(d);
|
|
||||||
}
|
|
||||||
else if (roundMode == RoundMode_ToNearestPowerOfTwo)
|
|
||||||
{
|
|
||||||
w = nearestPowerOfTwo(w);
|
|
||||||
h = nearestPowerOfTwo(h);
|
|
||||||
d = nearestPowerOfTwo(d);
|
|
||||||
}
|
|
||||||
else if (roundMode == RoundMode_ToPreviousPowerOfTwo)
|
|
||||||
{
|
|
||||||
w = previousPowerOfTwo(w);
|
|
||||||
h = previousPowerOfTwo(h);
|
|
||||||
d = previousPowerOfTwo(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->targetWidth = w;
|
|
||||||
this->targetHeight = h;
|
|
||||||
this->targetDepth = d;
|
|
||||||
|
|
||||||
this->targetMipmapCount = countMipmaps(w, h, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Return real number of mipmaps, including first level.
|
|
||||||
// computeTargetExtents should have been called before.
|
|
||||||
int InputOptions::Private::realMipmapCount() const
|
|
||||||
{
|
|
||||||
int mipmapCount = targetMipmapCount;
|
|
||||||
|
|
||||||
if (!generateMipmaps) mipmapCount = 1;
|
|
||||||
else if (maxLevel != -1 && maxLevel < mipmapCount - 1) mipmapCount = maxLevel + 1;
|
|
||||||
|
|
||||||
return mipmapCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const Image * InputOptions::Private::image(uint face, uint mipmap) const
|
|
||||||
{
|
|
||||||
nvDebugCheck(face < faceCount);
|
|
||||||
nvDebugCheck(mipmap < mipmapCount);
|
|
||||||
|
|
||||||
const InputImage & image = this->images[face * mipmapCount + mipmap];
|
|
||||||
nvDebugCheck(image.face == face);
|
|
||||||
nvDebugCheck(image.mipLevel == mipmap);
|
|
||||||
|
|
||||||
return image.uint8data.ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
const Image * InputOptions::Private::image(uint idx) const
|
|
||||||
{
|
|
||||||
nvDebugCheck(idx < faceCount * mipmapCount);
|
|
||||||
|
|
||||||
const InputImage & image = this->images[idx];
|
|
||||||
|
|
||||||
return image.uint8data.ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
const FloatImage * InputOptions::Private::floatImage(uint idx) const
|
|
||||||
{
|
|
||||||
nvDebugCheck(idx < faceCount * mipmapCount);
|
|
||||||
|
|
||||||
const InputImage & image = this->images[idx];
|
|
||||||
|
|
||||||
return image.floatdata.ptr();
|
|
||||||
}
|
|
||||||
|
@ -43,23 +43,19 @@ namespace nvtt
|
|||||||
InputFormat inputFormat;
|
InputFormat inputFormat;
|
||||||
AlphaMode alphaMode;
|
AlphaMode alphaMode;
|
||||||
|
|
||||||
|
uint width;
|
||||||
|
uint height;
|
||||||
|
uint depth;
|
||||||
uint faceCount;
|
uint faceCount;
|
||||||
uint mipmapCount;
|
uint mipmapCount;
|
||||||
uint imageCount;
|
uint imageCount;
|
||||||
|
|
||||||
struct InputImage;
|
void ** images;
|
||||||
InputImage * images;
|
|
||||||
|
|
||||||
// Gamma conversion.
|
// Gamma conversion.
|
||||||
float inputGamma;
|
float inputGamma;
|
||||||
float outputGamma;
|
float outputGamma;
|
||||||
|
|
||||||
// Color transform.
|
|
||||||
ColorTransform colorTransform;
|
|
||||||
nv::Matrix linearTransform;
|
|
||||||
float colorOffsets[4];
|
|
||||||
uint swizzleTransform[4];
|
|
||||||
|
|
||||||
// Mipmap generation options.
|
// Mipmap generation options.
|
||||||
bool generateMipmaps;
|
bool generateMipmaps;
|
||||||
int maxLevel;
|
int maxLevel;
|
||||||
@ -80,42 +76,6 @@ namespace nvtt
|
|||||||
// Adjust extents.
|
// Adjust extents.
|
||||||
uint maxExtent;
|
uint maxExtent;
|
||||||
RoundMode roundMode;
|
RoundMode roundMode;
|
||||||
|
|
||||||
bool premultiplyAlpha;
|
|
||||||
|
|
||||||
// @@ These are computed in nvtt::compress, so they should be mutable or stored elsewhere...
|
|
||||||
mutable uint targetWidth;
|
|
||||||
mutable uint targetHeight;
|
|
||||||
mutable uint targetDepth;
|
|
||||||
mutable uint targetMipmapCount;
|
|
||||||
|
|
||||||
void computeTargetExtents() const;
|
|
||||||
|
|
||||||
int realMipmapCount() const;
|
|
||||||
|
|
||||||
const nv::Image * image(uint face, uint mipmap) const;
|
|
||||||
const nv::Image * image(uint idx) const;
|
|
||||||
|
|
||||||
const nv::FloatImage * floatImage(uint idx) const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// Internal image structure.
|
|
||||||
struct InputOptions::Private::InputImage
|
|
||||||
{
|
|
||||||
InputImage() {}
|
|
||||||
|
|
||||||
bool hasValidData() const { return uint8data != NULL || floatdata != NULL; }
|
|
||||||
|
|
||||||
int mipLevel;
|
|
||||||
int face;
|
|
||||||
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int depth;
|
|
||||||
|
|
||||||
nv::AutoPtr<nv::Image> uint8data;
|
|
||||||
nv::AutoPtr<nv::FloatImage> floatdata;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // nvtt namespace
|
} // nvtt namespace
|
||||||
|
@ -54,7 +54,7 @@ namespace
|
|||||||
return d * d;
|
return d * d;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint nearestGreen4(uint green, uint maxGreen, uint minGreen)
|
/*static uint nearestGreen4(uint green, uint maxGreen, uint minGreen)
|
||||||
{
|
{
|
||||||
uint bias = maxGreen + (maxGreen - minGreen) / 6;
|
uint bias = maxGreen + (maxGreen - minGreen) / 6;
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ namespace
|
|||||||
if (maxGreen - minGreen != 0) index = clamp(3 * (bias - green) / (maxGreen - minGreen), 0U, 3U);
|
if (maxGreen - minGreen != 0) index = clamp(3 * (bias - green) / (maxGreen - minGreen), 0U, 3U);
|
||||||
|
|
||||||
return (index * minGreen + (3 - index) * maxGreen) / 3;
|
return (index * minGreen + (3 - index) * maxGreen) / 3;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
static int computeGreenError(const ColorBlock & rgba, const BlockDXT1 * block, int bestError = INT_MAX)
|
static int computeGreenError(const ColorBlock & rgba, const BlockDXT1 * block, int bestError = INT_MAX)
|
||||||
{
|
{
|
||||||
@ -164,7 +164,7 @@ namespace
|
|||||||
return (index * minAlpha + (7 - index) * maxAlpha) / 7;
|
return (index * minAlpha + (7 - index) * maxAlpha) / 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint computeAlphaError8(const ColorBlock & rgba, const AlphaBlockDXT5 * block, int bestError = INT_MAX)
|
/*static uint computeAlphaError8(const ColorBlock & rgba, const AlphaBlockDXT5 * block, int bestError = INT_MAX)
|
||||||
{
|
{
|
||||||
int totalError = 0;
|
int totalError = 0;
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
return totalError;
|
return totalError;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
static uint computeAlphaError(const ColorBlock & rgba, const AlphaBlockDXT5 * block, int bestError = INT_MAX)
|
static uint computeAlphaError(const ColorBlock & rgba, const AlphaBlockDXT5 * block, int bestError = INT_MAX)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "nvmath/Vector.h"
|
#include "nvmath/Vector.h"
|
||||||
#include "nvmath/Matrix.h"
|
#include "nvmath/Matrix.h"
|
||||||
#include "nvmath/Color.h"
|
#include "nvmath/Color.h"
|
||||||
|
#include "nvmath/Half.h"
|
||||||
|
|
||||||
#include "nvimage/Filter.h"
|
#include "nvimage/Filter.h"
|
||||||
#include "nvimage/ImageIO.h"
|
#include "nvimage/ImageIO.h"
|
||||||
@ -104,6 +105,7 @@ namespace
|
|||||||
|
|
||||||
TexImage::TexImage() : m(new TexImage::Private())
|
TexImage::TexImage() : m(new TexImage::Private())
|
||||||
{
|
{
|
||||||
|
m->addRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
TexImage::TexImage(const TexImage & tex) : m(tex.m)
|
TexImage::TexImage(const TexImage & tex) : m(tex.m)
|
||||||
@ -300,7 +302,7 @@ bool TexImage::save(const char * fileName) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::setImage2D(nvtt::InputFormat format, int w, int h, int idx, const void * restrict data)
|
bool TexImage::setImage2D(nvtt::InputFormat format, int w, int h, int idx, const void * data)
|
||||||
{
|
{
|
||||||
if (idx < 0 || uint(idx) >= m->imageArray.count())
|
if (idx < 0 || uint(idx) >= m->imageArray.count())
|
||||||
{
|
{
|
||||||
@ -323,10 +325,10 @@ bool TexImage::setImage2D(nvtt::InputFormat format, int w, int h, int idx, const
|
|||||||
|
|
||||||
const int count = w * h;
|
const int count = w * h;
|
||||||
|
|
||||||
float * restrict rdst = img->channel(0);
|
float * rdst = img->channel(0);
|
||||||
float * restrict gdst = img->channel(1);
|
float * gdst = img->channel(1);
|
||||||
float * restrict bdst = img->channel(2);
|
float * bdst = img->channel(2);
|
||||||
float * restrict adst = img->channel(3);
|
float * adst = img->channel(3);
|
||||||
|
|
||||||
if (format == InputFormat_BGRA_8UB)
|
if (format == InputFormat_BGRA_8UB)
|
||||||
{
|
{
|
||||||
@ -345,6 +347,23 @@ bool TexImage::setImage2D(nvtt::InputFormat format, int w, int h, int idx, const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (format == InputFormat_RGBA_16F)
|
||||||
|
{
|
||||||
|
const uint16 * src = (const uint16 *)data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
((uint32 *)rdst)[i] = half_to_float(src[4*i+0]);
|
||||||
|
((uint32 *)gdst)[i] = half_to_float(src[4*i+1]);
|
||||||
|
((uint32 *)bdst)[i] = half_to_float(src[4*i+2]);
|
||||||
|
((uint32 *)adst)[i] = half_to_float(src[4*i+3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (format == InputFormat_RGBA_32F)
|
else if (format == InputFormat_RGBA_32F)
|
||||||
{
|
{
|
||||||
const float * src = (const float *)data;
|
const float * src = (const float *)data;
|
||||||
@ -366,7 +385,7 @@ bool TexImage::setImage2D(nvtt::InputFormat format, int w, int h, int idx, const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::setImage2D(InputFormat format, int w, int h, int idx, const void * restrict r, const void * restrict g, const void * restrict b, const void * restrict a)
|
bool TexImage::setImage2D(InputFormat format, int w, int h, int idx, const void * r, const void * g, const void * b, const void * a)
|
||||||
{
|
{
|
||||||
if (idx < 0 || uint(idx) >= m->imageArray.count())
|
if (idx < 0 || uint(idx) >= m->imageArray.count())
|
||||||
{
|
{
|
||||||
@ -383,17 +402,17 @@ bool TexImage::setImage2D(InputFormat format, int w, int h, int idx, const void
|
|||||||
|
|
||||||
const int count = w * h;
|
const int count = w * h;
|
||||||
|
|
||||||
float * restrict rdst = img->channel(0);
|
float * rdst = img->channel(0);
|
||||||
float * restrict gdst = img->channel(1);
|
float * gdst = img->channel(1);
|
||||||
float * restrict bdst = img->channel(2);
|
float * bdst = img->channel(2);
|
||||||
float * restrict adst = img->channel(3);
|
float * adst = img->channel(3);
|
||||||
|
|
||||||
if (format == InputFormat_BGRA_8UB)
|
if (format == InputFormat_BGRA_8UB)
|
||||||
{
|
{
|
||||||
const uint8 * restrict rsrc = (const uint8 *)r;
|
const uint8 * rsrc = (const uint8 *)r;
|
||||||
const uint8 * restrict gsrc = (const uint8 *)g;
|
const uint8 * gsrc = (const uint8 *)g;
|
||||||
const uint8 * restrict bsrc = (const uint8 *)b;
|
const uint8 * bsrc = (const uint8 *)b;
|
||||||
const uint8 * restrict asrc = (const uint8 *)a;
|
const uint8 * asrc = (const uint8 *)a;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < count; i++) rdst[i] = float(rsrc[i]) / 255.0f;
|
for (int i = 0; i < count; i++) rdst[i] = float(rsrc[i]) / 255.0f;
|
||||||
@ -405,6 +424,23 @@ bool TexImage::setImage2D(InputFormat format, int w, int h, int idx, const void
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (format == InputFormat_RGBA_16F)
|
||||||
|
{
|
||||||
|
const uint16 * rsrc = (const uint16 *)r;
|
||||||
|
const uint16 * gsrc = (const uint16 *)g;
|
||||||
|
const uint16 * bsrc = (const uint16 *)b;
|
||||||
|
const uint16 * asrc = (const uint16 *)a;
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < count; i++) ((uint32 *)rdst)[i] = half_to_float(rsrc[i]);
|
||||||
|
for (int i = 0; i < count; i++) ((uint32 *)gdst)[i] = half_to_float(gsrc[i]);
|
||||||
|
for (int i = 0; i < count; i++) ((uint32 *)bdst)[i] = half_to_float(bsrc[i]);
|
||||||
|
for (int i = 0; i < count; i++) ((uint32 *)adst)[i] = half_to_float(asrc[i]);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (format == InputFormat_RGBA_32F)
|
else if (format == InputFormat_RGBA_32F)
|
||||||
{
|
{
|
||||||
const float * rsrc = (const float *)r;
|
const float * rsrc = (const float *)r;
|
||||||
@ -526,9 +562,38 @@ bool TexImage::setImage2D(Format format, Decoder decoder, int w, int h, int idx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma NV_MESSAGE("TODO: provide a TexImage::resize that can override filter width and parameters.")
|
static void getDefaultFilterWidthAndParams(int filter, float * filterWidth, float params[2])
|
||||||
|
{
|
||||||
|
if (filter == ResizeFilter_Box) {
|
||||||
|
*filterWidth = 0.5f;
|
||||||
|
}
|
||||||
|
else if (filter == ResizeFilter_Triangle) {
|
||||||
|
*filterWidth = 1.0f;
|
||||||
|
}
|
||||||
|
else if (filter == ResizeFilter_Kaiser)
|
||||||
|
{
|
||||||
|
*filterWidth = 3.0f;
|
||||||
|
params[0] = 4.0f;
|
||||||
|
params[1] = 1.0f;
|
||||||
|
}
|
||||||
|
else //if (filter == ResizeFilter_Mitchell)
|
||||||
|
{
|
||||||
|
*filterWidth = 2.0f;
|
||||||
|
params[0] = 1.0f / 3.0f;
|
||||||
|
params[1] = 1.0f / 3.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TexImage::resize(int w, int h, ResizeFilter filter)
|
void TexImage::resize(int w, int h, ResizeFilter filter)
|
||||||
|
{
|
||||||
|
float filterWidth;
|
||||||
|
float params[2];
|
||||||
|
getDefaultFilterWidthAndParams(filter, &filterWidth, params);
|
||||||
|
|
||||||
|
resize(w, h, filter, filterWidth, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TexImage::resize(int w, int h, ResizeFilter filter, float filterWidth, const float * params)
|
||||||
{
|
{
|
||||||
if (m->imageArray.count() > 0)
|
if (m->imageArray.count() > 0)
|
||||||
{
|
{
|
||||||
@ -555,25 +620,25 @@ void TexImage::resize(int w, int h, ResizeFilter filter)
|
|||||||
{
|
{
|
||||||
if (filter == ResizeFilter_Box)
|
if (filter == ResizeFilter_Box)
|
||||||
{
|
{
|
||||||
BoxFilter filter;
|
BoxFilter filter(filterWidth);
|
||||||
img = img->resize(filter, w, h, wrapMode, 3);
|
img = img->resize(filter, w, h, wrapMode, 3);
|
||||||
}
|
}
|
||||||
else if (filter == ResizeFilter_Triangle)
|
else if (filter == ResizeFilter_Triangle)
|
||||||
{
|
{
|
||||||
TriangleFilter filter;
|
TriangleFilter filter(filterWidth);
|
||||||
img = img->resize(filter, w, h, wrapMode, 3);
|
img = img->resize(filter, w, h, wrapMode, 3);
|
||||||
}
|
}
|
||||||
else if (filter == ResizeFilter_Kaiser)
|
else if (filter == ResizeFilter_Kaiser)
|
||||||
{
|
{
|
||||||
//KaiserFilter filter(inputOptions.kaiserWidth);
|
KaiserFilter filter(filterWidth);
|
||||||
//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
|
if (params != NULL) filter.setParameters(params[0], params[1]);
|
||||||
KaiserFilter filter(3);
|
|
||||||
img = img->resize(filter, w, h, wrapMode, 3);
|
img = img->resize(filter, w, h, wrapMode, 3);
|
||||||
}
|
}
|
||||||
else //if (filter == ResizeFilter_Mitchell)
|
else //if (filter == ResizeFilter_Mitchell)
|
||||||
{
|
{
|
||||||
nvDebugCheck(filter == ResizeFilter_Mitchell);
|
nvDebugCheck(filter == ResizeFilter_Mitchell);
|
||||||
MitchellFilter filter;
|
MitchellFilter filter;
|
||||||
|
if (params != NULL) filter.setParameters(params[0], params[1]);
|
||||||
img = img->resize(filter, w, h, wrapMode, 3);
|
img = img->resize(filter, w, h, wrapMode, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -581,25 +646,25 @@ void TexImage::resize(int w, int h, ResizeFilter filter)
|
|||||||
{
|
{
|
||||||
if (filter == ResizeFilter_Box)
|
if (filter == ResizeFilter_Box)
|
||||||
{
|
{
|
||||||
BoxFilter filter;
|
BoxFilter filter(filterWidth);
|
||||||
img = img->resize(filter, w, h, wrapMode);
|
img = img->resize(filter, w, h, wrapMode);
|
||||||
}
|
}
|
||||||
else if (filter == ResizeFilter_Triangle)
|
else if (filter == ResizeFilter_Triangle)
|
||||||
{
|
{
|
||||||
TriangleFilter filter;
|
TriangleFilter filter(filterWidth);
|
||||||
img = img->resize(filter, w, h, wrapMode);
|
img = img->resize(filter, w, h, wrapMode);
|
||||||
}
|
}
|
||||||
else if (filter == ResizeFilter_Kaiser)
|
else if (filter == ResizeFilter_Kaiser)
|
||||||
{
|
{
|
||||||
//KaiserFilter filter(inputOptions.kaiserWidth);
|
KaiserFilter filter(filterWidth);
|
||||||
//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
|
if (params != NULL) filter.setParameters(params[0], params[1]);
|
||||||
KaiserFilter filter(3);
|
|
||||||
img = img->resize(filter, w, h, wrapMode);
|
img = img->resize(filter, w, h, wrapMode);
|
||||||
}
|
}
|
||||||
else //if (filter == ResizeFilter_Mitchell)
|
else //if (filter == ResizeFilter_Mitchell)
|
||||||
{
|
{
|
||||||
nvDebugCheck(filter == ResizeFilter_Mitchell);
|
nvDebugCheck(filter == ResizeFilter_Mitchell);
|
||||||
MitchellFilter filter;
|
MitchellFilter filter;
|
||||||
|
if (params != NULL) filter.setParameters(params[0], params[1]);
|
||||||
img = img->resize(filter, w, h, wrapMode);
|
img = img->resize(filter, w, h, wrapMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -610,6 +675,16 @@ void TexImage::resize(int w, int h, ResizeFilter filter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
|
void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
|
||||||
|
{
|
||||||
|
float filterWidth;
|
||||||
|
float params[2];
|
||||||
|
getDefaultFilterWidthAndParams(filter, &filterWidth, params);
|
||||||
|
|
||||||
|
resize(maxExtent, roundMode, filter, filterWidth, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter, float filterWidth, const float * params)
|
||||||
{
|
{
|
||||||
if (m->imageArray.count() > 0)
|
if (m->imageArray.count() > 0)
|
||||||
{
|
{
|
||||||
@ -619,7 +694,7 @@ void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
|
|||||||
nvDebugCheck(w > 0);
|
nvDebugCheck(w > 0);
|
||||||
nvDebugCheck(h > 0);
|
nvDebugCheck(h > 0);
|
||||||
|
|
||||||
if (roundMode != RoundMode_None)
|
if (roundMode != RoundMode_None && maxExtent > 0)
|
||||||
{
|
{
|
||||||
// rounded max extent should never be higher than original max extent.
|
// rounded max extent should never be higher than original max extent.
|
||||||
maxExtent = previousPowerOfTwo(maxExtent);
|
maxExtent = previousPowerOfTwo(maxExtent);
|
||||||
@ -627,7 +702,7 @@ void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
|
|||||||
|
|
||||||
// Scale extents without changing aspect ratio.
|
// Scale extents without changing aspect ratio.
|
||||||
int maxwh = max(w, h);
|
int maxwh = max(w, h);
|
||||||
if (maxExtent != 0 && maxwh > maxExtent)
|
if (maxExtent > 0 && maxwh > maxExtent)
|
||||||
{
|
{
|
||||||
w = max((w * maxExtent) / maxwh, 1);
|
w = max((w * maxExtent) / maxwh, 1);
|
||||||
h = max((h * maxExtent) / maxwh, 1);
|
h = max((h * maxExtent) / maxwh, 1);
|
||||||
@ -656,11 +731,20 @@ void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
|
|||||||
w = h = max(w, h);
|
w = h = max(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
resize(w, h, filter);
|
resize(w, h, filter, filterWidth, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::buildNextMipmap(MipmapFilter filter)
|
bool TexImage::buildNextMipmap(MipmapFilter filter)
|
||||||
|
{
|
||||||
|
float filterWidth;
|
||||||
|
float params[2];
|
||||||
|
getDefaultFilterWidthAndParams(filter, &filterWidth, params);
|
||||||
|
|
||||||
|
buildNextMipmap(filter, filterWidth, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TexImage::buildNextMipmap(MipmapFilter filter, float filterWidth, const float * params)
|
||||||
{
|
{
|
||||||
if (m->imageArray.count() > 0)
|
if (m->imageArray.count() > 0)
|
||||||
{
|
{
|
||||||
@ -690,20 +774,19 @@ bool TexImage::buildNextMipmap(MipmapFilter filter)
|
|||||||
{
|
{
|
||||||
if (filter == MipmapFilter_Box)
|
if (filter == MipmapFilter_Box)
|
||||||
{
|
{
|
||||||
BoxFilter filter;
|
BoxFilter filter(filterWidth);
|
||||||
img = img->downSample(filter, wrapMode, 3);
|
img = img->downSample(filter, wrapMode, 3);
|
||||||
}
|
}
|
||||||
else if (filter == MipmapFilter_Triangle)
|
else if (filter == MipmapFilter_Triangle)
|
||||||
{
|
{
|
||||||
TriangleFilter filter;
|
TriangleFilter filter(filterWidth);
|
||||||
img = img->downSample(filter, wrapMode, 3);
|
img = img->downSample(filter, wrapMode, 3);
|
||||||
}
|
}
|
||||||
else if (filter == MipmapFilter_Kaiser)
|
else if (filter == MipmapFilter_Kaiser)
|
||||||
{
|
{
|
||||||
nvDebugCheck(filter == MipmapFilter_Kaiser);
|
nvDebugCheck(filter == MipmapFilter_Kaiser);
|
||||||
//KaiserFilter filter(inputOptions.kaiserWidth);
|
KaiserFilter filter(filterWidth);
|
||||||
//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
|
if (params != NULL) filter.setParameters(params[0], params[1]);
|
||||||
KaiserFilter filter(3);
|
|
||||||
img = img->downSample(filter, wrapMode, 3);
|
img = img->downSample(filter, wrapMode, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -711,19 +794,24 @@ bool TexImage::buildNextMipmap(MipmapFilter filter)
|
|||||||
{
|
{
|
||||||
if (filter == MipmapFilter_Box)
|
if (filter == MipmapFilter_Box)
|
||||||
{
|
{
|
||||||
|
if (filterWidth == 0.5f) {
|
||||||
img = img->fastDownSample();
|
img = img->fastDownSample();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
BoxFilter filter(filterWidth);
|
||||||
|
img = img->downSample(filter, wrapMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (filter == MipmapFilter_Triangle)
|
else if (filter == MipmapFilter_Triangle)
|
||||||
{
|
{
|
||||||
TriangleFilter filter;
|
TriangleFilter filter(filterWidth);
|
||||||
img = img->downSample(filter, wrapMode);
|
img = img->downSample(filter, wrapMode);
|
||||||
}
|
}
|
||||||
else //if (filter == MipmapFilter_Kaiser)
|
else //if (filter == MipmapFilter_Kaiser)
|
||||||
{
|
{
|
||||||
nvDebugCheck(filter == MipmapFilter_Kaiser);
|
nvDebugCheck(filter == MipmapFilter_Kaiser);
|
||||||
//KaiserFilter filter(inputOptions.kaiserWidth);
|
KaiserFilter filter(filterWidth);
|
||||||
//filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
|
if (params != NULL) filter.setParameters(params[0], params[1]);
|
||||||
KaiserFilter filter(3);
|
|
||||||
img = img->downSample(filter, wrapMode);
|
img = img->downSample(filter, wrapMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -848,10 +936,10 @@ void TexImage::blend(float red, float green, float blue, float alpha, float t)
|
|||||||
FloatImage * img = m->imageArray[i];
|
FloatImage * img = m->imageArray[i];
|
||||||
if (img == NULL) continue;
|
if (img == NULL) continue;
|
||||||
|
|
||||||
float * restrict r = img->channel(0);
|
float * r = img->channel(0);
|
||||||
float * restrict g = img->channel(1);
|
float * g = img->channel(1);
|
||||||
float * restrict b = img->channel(2);
|
float * b = img->channel(2);
|
||||||
float * restrict a = img->channel(3);
|
float * a = img->channel(3);
|
||||||
|
|
||||||
const int count = img->width() * img->height();
|
const int count = img->width() * img->height();
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
@ -873,10 +961,10 @@ void TexImage::premultiplyAlpha()
|
|||||||
FloatImage * img = m->imageArray[i];
|
FloatImage * img = m->imageArray[i];
|
||||||
if (img == NULL) continue;
|
if (img == NULL) continue;
|
||||||
|
|
||||||
float * restrict r = img->channel(0);
|
float * r = img->channel(0);
|
||||||
float * restrict g = img->channel(1);
|
float * g = img->channel(1);
|
||||||
float * restrict b = img->channel(2);
|
float * b = img->channel(2);
|
||||||
float * restrict a = img->channel(3);
|
float * a = img->channel(3);
|
||||||
|
|
||||||
const int count = img->width() * img->height();
|
const int count = img->width() * img->height();
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
@ -904,10 +992,10 @@ void TexImage::toGreyScale(float redScale, float greenScale, float blueScale, fl
|
|||||||
blueScale /= sum;
|
blueScale /= sum;
|
||||||
alphaScale /= sum;
|
alphaScale /= sum;
|
||||||
|
|
||||||
float * restrict r = img->channel(0);
|
float * r = img->channel(0);
|
||||||
float * restrict g = img->channel(1);
|
float * g = img->channel(1);
|
||||||
float * restrict b = img->channel(2);
|
float * b = img->channel(2);
|
||||||
float * restrict a = img->channel(3);
|
float * a = img->channel(3);
|
||||||
|
|
||||||
const int count = img->width() * img->height();
|
const int count = img->width() * img->height();
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
@ -1047,6 +1135,139 @@ bool TexImage::normalizeRange(float * rangeMin, float * rangeMax)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ideally you should compress/quantize the RGB and M portions independently.
|
||||||
|
// Once you have M quantized, you would compute the corresponding RGB and quantize that.
|
||||||
|
void TexImage::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
|
||||||
|
{
|
||||||
|
detach();
|
||||||
|
|
||||||
|
float irange = 1.0f / range;
|
||||||
|
|
||||||
|
foreach (idx, m->imageArray) {
|
||||||
|
FloatImage * img = m->imageArray[idx];
|
||||||
|
if (img == NULL) continue;
|
||||||
|
|
||||||
|
float * r = img->channel(0);
|
||||||
|
float * g = img->channel(1);
|
||||||
|
float * b = img->channel(2);
|
||||||
|
float * a = img->channel(3);
|
||||||
|
|
||||||
|
const uint count = img->width() * img->height();
|
||||||
|
for (uint i = 0; i < count; i++) {
|
||||||
|
float ri = nv::clamp(r[i] * irange, 0.0f, 1.0f);
|
||||||
|
float gi = nv::clamp(g[i] * irange, 0.0f, 1.0f);
|
||||||
|
float bi = nv::clamp(b[i] * irange, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
float m = max(max(ri, gi), max(bi, 1e-6f)); // Avoid division by zero.
|
||||||
|
//m = quantizeCeil(m, 8);
|
||||||
|
float im = 1.0f / m;
|
||||||
|
|
||||||
|
r[i] = ri * im;
|
||||||
|
g[i] = gi * im;
|
||||||
|
b[i] = bi * im;
|
||||||
|
a[i] = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Y is in the [0, 1] range, while CoCg are in the [-1, 1] range.
|
||||||
|
void TexImage::toYCoCg()
|
||||||
|
{
|
||||||
|
detach();
|
||||||
|
|
||||||
|
foreach (idx, m->imageArray) {
|
||||||
|
FloatImage * img = m->imageArray[idx];
|
||||||
|
if (img == NULL) continue;
|
||||||
|
|
||||||
|
float * r = img->channel(0);
|
||||||
|
float * g = img->channel(1);
|
||||||
|
float * b = img->channel(2);
|
||||||
|
float * a = img->channel(3);
|
||||||
|
|
||||||
|
const uint count = img->width() * img->height();
|
||||||
|
for (uint i = 0; i < count; i++) {
|
||||||
|
float ri = r[i];
|
||||||
|
float gi = g[i];
|
||||||
|
float bi = b[i];
|
||||||
|
|
||||||
|
float Y = (2*gi + ri + bi) * 0.25f;
|
||||||
|
float Co = (ri - bi);
|
||||||
|
float Cg = (2*gi - ri - bi) * 0.5f;
|
||||||
|
|
||||||
|
r[i] = Co;
|
||||||
|
g[i] = Cg;
|
||||||
|
b[i] = 0.0f;
|
||||||
|
a[i] = Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// img.toYCoCg();
|
||||||
|
// img.blockScaleCoCg();
|
||||||
|
// img.scaleBias(0, 0.5, 0.5);
|
||||||
|
// img.scaleBias(1, 0.5, 0.5);
|
||||||
|
|
||||||
|
// @@ Add support for threshold.
|
||||||
|
// We could do something to prevent scale values from adjacent blocks from being too different to each other
|
||||||
|
// and minimize bilinear interpolation artifacts.
|
||||||
|
void TexImage::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
|
||||||
|
{
|
||||||
|
detach();
|
||||||
|
|
||||||
|
foreach (idx, m->imageArray) {
|
||||||
|
FloatImage * img = m->imageArray[idx];
|
||||||
|
if (img == NULL) continue;
|
||||||
|
|
||||||
|
const uint w = img->width();
|
||||||
|
const uint h = img->height();
|
||||||
|
const uint bw = max(1U, w/4);
|
||||||
|
const uint bh = max(1U, h/4);
|
||||||
|
|
||||||
|
for (uint bj = 0; bj < bh; bj++) {
|
||||||
|
for (uint bi = 0; bi < bw; bi++) {
|
||||||
|
|
||||||
|
// Compute per block scale.
|
||||||
|
float m = 1.0f / 256.0f;
|
||||||
|
for (uint j = 0; j < 4; j++) {
|
||||||
|
for (uint i = 0; i < 4; i++) {
|
||||||
|
uint x = min(bi*4 + i, w);
|
||||||
|
uint y = min(bj*4 + j, h);
|
||||||
|
|
||||||
|
float Co = img->pixel(x, y, 0);
|
||||||
|
float Cg = img->pixel(x, y, 1);
|
||||||
|
|
||||||
|
m = max(m, fabsf(Co));
|
||||||
|
m = max(m, fabsf(Cg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float scale = quantizeCeil(m, bits);
|
||||||
|
nvDebugCheck(scale >= m);
|
||||||
|
|
||||||
|
// Store block scale in blue channel and scale CoCg.
|
||||||
|
for (uint j = 0; j < 4; j++) {
|
||||||
|
for (uint i = 0; i < 4; i++) {
|
||||||
|
uint x = min(bi*4 + i, w);
|
||||||
|
uint y = min(bj*4 + j, h);
|
||||||
|
|
||||||
|
float & Co = img->pixel(x, y, 0);
|
||||||
|
float & Cg = img->pixel(x, y, 1);
|
||||||
|
|
||||||
|
Co /= scale;
|
||||||
|
nvDebugCheck(fabsf(Co) <= 1.0f);
|
||||||
|
|
||||||
|
Cg /= scale;
|
||||||
|
nvDebugCheck(fabsf(Cg) <= 1.0f);
|
||||||
|
|
||||||
|
img->pixel(x, y, 2) = scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Set normal map options.
|
// Set normal map options.
|
||||||
void TexImage::toNormalMap(float sm, float medium, float big, float large)
|
void TexImage::toNormalMap(float sm, float medium, float big, float large)
|
||||||
@ -1071,20 +1292,6 @@ void TexImage::toNormalMap(float sm, float medium, float big, float large)
|
|||||||
m->isNormalMap = true;
|
m->isNormalMap = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void TexImage::toHeightMap()
|
|
||||||
{
|
|
||||||
detach();
|
|
||||||
|
|
||||||
foreach (i, m->imageArray)
|
|
||||||
{
|
|
||||||
if (m->imageArray[i] == NULL) continue;
|
|
||||||
|
|
||||||
#pragma message(NV_FILE_LINE "TODO: Implement TexImage::toHeightMap")
|
|
||||||
}
|
|
||||||
|
|
||||||
m->isNormalMap = false;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
void TexImage::normalizeNormalMap()
|
void TexImage::normalizeNormalMap()
|
||||||
{
|
{
|
||||||
//nvCheck(m->isNormalMap);
|
//nvCheck(m->isNormalMap);
|
||||||
|
@ -42,6 +42,8 @@ namespace nvtt
|
|||||||
public:
|
public:
|
||||||
Private()
|
Private()
|
||||||
{
|
{
|
||||||
|
nvDebugCheck( refCount() == 0 );
|
||||||
|
|
||||||
type = TextureType_2D;
|
type = TextureType_2D;
|
||||||
wrapMode = WrapMode_Mirror;
|
wrapMode = WrapMode_Mirror;
|
||||||
alphaMode = AlphaMode_None;
|
alphaMode = AlphaMode_None;
|
||||||
@ -49,8 +51,10 @@ namespace nvtt
|
|||||||
|
|
||||||
imageArray.resize(1, NULL);
|
imageArray.resize(1, NULL);
|
||||||
}
|
}
|
||||||
Private(const Private & p) // Copy ctor. inits refcount to 0.
|
Private(const Private & p) : RefCounted() // Copy ctor. inits refcount to 0.
|
||||||
{
|
{
|
||||||
|
nvDebugCheck( refCount() == 0 );
|
||||||
|
|
||||||
type = p.type;
|
type = p.type;
|
||||||
wrapMode = p.wrapMode;
|
wrapMode = p.wrapMode;
|
||||||
alphaMode = p.alphaMode;
|
alphaMode = p.alphaMode;
|
||||||
|
@ -262,7 +262,7 @@ static int clamp(double r, double low, double high)
|
|||||||
|
|
||||||
|
|
||||||
// match the tonemapping function used by exrdisplay
|
// match the tonemapping function used by exrdisplay
|
||||||
static void tonemap(const Vector3 &in, double exposure, Vector3 &out)
|
/*static void tonemap(const Vector3 &in, double exposure, Vector3 &out)
|
||||||
{
|
{
|
||||||
double r,g,b;
|
double r,g,b;
|
||||||
unsigned short h;
|
unsigned short h;
|
||||||
@ -325,7 +325,7 @@ static void tonemap(const Vector3 &in, double exposure, Vector3 &out)
|
|||||||
out.x = clamp (r, 0, 255);
|
out.x = clamp (r, 0, 255);
|
||||||
out.y = clamp (g, 0, 255);
|
out.y = clamp (g, 0, 255);
|
||||||
out.z = clamp (b, 0, 255);
|
out.z = clamp (b, 0, 255);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
static void mpsnrmap(const Vector3 &in, int exposure, Vector3 &out)
|
static void mpsnrmap(const Vector3 &in, int exposure, Vector3 &out)
|
||||||
{
|
{
|
||||||
|
@ -124,38 +124,45 @@ CudaCompressor::CudaCompressor(CudaContext & ctx) : m_ctx(ctx)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CudaCompressor::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
|
void CudaCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
|
||||||
{
|
{
|
||||||
nvDebugCheck(cuda::isHardwarePresent());
|
nvDebugCheck(cuda::isHardwarePresent());
|
||||||
|
|
||||||
#if defined HAVE_CUDA
|
#if defined HAVE_CUDA
|
||||||
|
|
||||||
// Allocate image as a cuda array.
|
// Allocate image as a cuda array.
|
||||||
|
const uint count = w * h;
|
||||||
|
Color32 * tmp = malloc<Color32>(count);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
tmp[i].r = clamp(data[i + count*0], 0.0f, 1.0f) * 255;
|
||||||
|
tmp[i].g = clamp(data[i + count*1], 0.0f, 1.0f) * 255;
|
||||||
|
tmp[i].b = clamp(data[i + count*2], 0.0f, 1.0f) * 255;
|
||||||
|
tmp[i].a = clamp(data[i + count*3], 0.0f, 1.0f) * 255;
|
||||||
|
}
|
||||||
|
|
||||||
cudaArray * d_image;
|
cudaArray * d_image;
|
||||||
if (inputFormat == nvtt::InputFormat_BGRA_8UB)
|
|
||||||
{
|
|
||||||
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(8, 8, 8, 8, cudaChannelFormatKindUnsigned);
|
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(8, 8, 8, 8, cudaChannelFormatKindUnsigned);
|
||||||
cudaMallocArray(&d_image, &channelDesc, w, h);
|
cudaMallocArray(&d_image, &channelDesc, w, h);
|
||||||
|
|
||||||
const int imageSize = w * h * sizeof(uint);
|
cudaMemcpyToArray(d_image, 0, 0, tmp, count * sizeof(Color32), cudaMemcpyHostToDevice);
|
||||||
cudaMemcpyToArray(d_image, 0, 0, data, imageSize, cudaMemcpyHostToDevice);
|
|
||||||
}
|
free(tmp);
|
||||||
else
|
|
||||||
{
|
// To avoid the copy we could keep the data in floating point format, but the channels are not interleaved like the kernel expects.
|
||||||
#pragma NV_MESSAGE("FIXME: Floating point textures not really supported by CUDA compressors.") // @@ What's missing???
|
/*
|
||||||
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(32, 32, 32, 32, cudaChannelFormatKindFloat);
|
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(32, 32, 32, 32, cudaChannelFormatKindFloat);
|
||||||
cudaMallocArray(&d_image, &channelDesc, w, h);
|
cudaMallocArray(&d_image, &channelDesc, w, h);
|
||||||
|
|
||||||
const int imageSize = w * h * sizeof(uint);
|
const int imageSize = w * h * sizeof(float) * 4;
|
||||||
cudaMemcpyToArray(d_image, 0, 0, data, imageSize, cudaMemcpyHostToDevice);
|
cudaMemcpyToArray(d_image, 0, 0, data, imageSize, cudaMemcpyHostToDevice);
|
||||||
}
|
*/
|
||||||
|
|
||||||
// Image size in blocks.
|
// Image size in blocks.
|
||||||
const uint bw = (w + 3) / 4;
|
const uint bw = (w + 3) / 4;
|
||||||
const uint bh = (h + 3) / 4;
|
const uint bh = (h + 3) / 4;
|
||||||
const uint bs = blockSize();
|
const uint bs = blockSize();
|
||||||
const uint blockNum = bw * bh;
|
const uint blockNum = bw * bh;
|
||||||
const uint compressedSize = blockNum * bs;
|
//const uint compressedSize = blockNum * bs;
|
||||||
|
|
||||||
void * h_result = ::malloc(min(blockNum, MAX_BLOCKS) * bs);
|
void * h_result = ::malloc(min(blockNum, MAX_BLOCKS) * bs);
|
||||||
|
|
||||||
@ -194,7 +201,6 @@ void CudaCompressor::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alp
|
|||||||
#else
|
#else
|
||||||
outputOptions.error(Error_CudaError);
|
outputOptions.error(Error_CudaError);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined HAVE_CUDA
|
#if defined HAVE_CUDA
|
||||||
|
@ -53,7 +53,7 @@ namespace nv
|
|||||||
{
|
{
|
||||||
CudaCompressor(CudaContext & ctx);
|
CudaCompressor(CudaContext & ctx);
|
||||||
|
|
||||||
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
|
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
|
||||||
|
|
||||||
virtual void setup(cudaArray * image, const nvtt::CompressionOptions::Private & compressionOptions) = 0;
|
virtual void setup(cudaArray * image, const nvtt::CompressionOptions::Private & compressionOptions) = 0;
|
||||||
virtual void compressBlocks(uint first, uint count, uint w, uint h, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0;
|
virtual void compressBlocks(uint first, uint count, uint w, uint h, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0;
|
||||||
|
@ -91,9 +91,8 @@ namespace nvtt
|
|||||||
Format_BC4, // ATI1
|
Format_BC4, // ATI1
|
||||||
Format_BC5, // 3DC, ATI2
|
Format_BC5, // 3DC, ATI2
|
||||||
|
|
||||||
Format_DXT1n,// Not supported on CPU yet.
|
Format_DXT1n, // Not supported on CPU yet.
|
||||||
Format_CTX1, // Not supported on CPU yet.
|
Format_CTX1, // Not supported on CPU yet.
|
||||||
//Format_YCoCg_DXT5, // Not supported yet.
|
|
||||||
|
|
||||||
Format_BC6, // Not supported yet.
|
Format_BC6, // Not supported yet.
|
||||||
Format_BC7, // Not supported yet.
|
Format_BC7, // Not supported yet.
|
||||||
@ -104,12 +103,12 @@ namespace nvtt
|
|||||||
/// Pixel types. These basically indicate how the output should be interpreted, but do not have any influence over the input.
|
/// Pixel types. These basically indicate how the output should be interpreted, but do not have any influence over the input.
|
||||||
enum PixelType
|
enum PixelType
|
||||||
{
|
{
|
||||||
PixelType_UnsignedNorm,
|
PixelType_UnsignedNorm = 0,
|
||||||
PixelType_SignedNorm, // Not supported yet.
|
PixelType_SignedNorm = 1, // Not supported yet.
|
||||||
PixelType_UnsignedInt, // Not supported yet.
|
PixelType_UnsignedInt = 2, // Not supported yet.
|
||||||
PixelType_SignedInt, // Not supported yet.
|
PixelType_SignedInt = 3, // Not supported yet.
|
||||||
PixelType_Float,
|
PixelType_Float = 4,
|
||||||
PixelType_UnsignedFloat,
|
PixelType_UnsignedFloat = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Quality modes.
|
/// Quality modes.
|
||||||
@ -179,8 +178,9 @@ namespace nvtt
|
|||||||
/// Input formats.
|
/// Input formats.
|
||||||
enum InputFormat
|
enum InputFormat
|
||||||
{
|
{
|
||||||
InputFormat_BGRA_8UB,
|
InputFormat_BGRA_8UB, // Normalized [0, 1] 8 bit fixed point.
|
||||||
InputFormat_RGBA_32F,
|
InputFormat_RGBA_16F, // 16 bit floating point.
|
||||||
|
InputFormat_RGBA_32F, // 32 bit floating point.
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Mipmap downsampling filters.
|
/// Mipmap downsampling filters.
|
||||||
@ -200,16 +200,6 @@ namespace nvtt
|
|||||||
ResizeFilter_Mitchell,
|
ResizeFilter_Mitchell,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Color transformation.
|
|
||||||
enum ColorTransform
|
|
||||||
{
|
|
||||||
ColorTransform_None,
|
|
||||||
ColorTransform_Linear, ///< Not implemented.
|
|
||||||
ColorTransform_Swizzle, ///< Not implemented.
|
|
||||||
ColorTransform_YCoCg, ///< Transform into r=Co, g=Cg, b=0, a=Y
|
|
||||||
ColorTransform_ScaledYCoCg, ///< Not implemented.
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Extents rounding mode.
|
/// Extents rounding mode.
|
||||||
enum RoundMode
|
enum RoundMode
|
||||||
{
|
{
|
||||||
@ -245,7 +235,6 @@ namespace nvtt
|
|||||||
|
|
||||||
// Set mipmap data. Copies the data.
|
// Set mipmap data. Copies the data.
|
||||||
NVTT_API bool setMipmapData(const void * data, int w, int h, int d = 1, int face = 0, int mipmap = 0);
|
NVTT_API bool setMipmapData(const void * data, int w, int h, int d = 1, int face = 0, int mipmap = 0);
|
||||||
NVTT_API bool setMipmapChannelData(const void * data, int channel, int w, int h, int d = 1, int face = 0, int mipmap = 0);
|
|
||||||
|
|
||||||
// Describe the format of the input.
|
// Describe the format of the input.
|
||||||
NVTT_API void setFormat(InputFormat format);
|
NVTT_API void setFormat(InputFormat format);
|
||||||
@ -271,18 +260,9 @@ namespace nvtt
|
|||||||
NVTT_API void setNormalFilter(float sm, float medium, float big, float large);
|
NVTT_API void setNormalFilter(float sm, float medium, float big, float large);
|
||||||
NVTT_API void setNormalizeMipmaps(bool b);
|
NVTT_API void setNormalizeMipmaps(bool b);
|
||||||
|
|
||||||
// Set color transforms.
|
|
||||||
NVTT_API void setColorTransform(ColorTransform t);
|
|
||||||
NVTT_API void setLinearTransform(int channel, float w0, float w1, float w2, float w3);
|
|
||||||
NVTT_API void setLinearTransform(int channel, float w0, float w1, float w2, float w3, float offset);
|
|
||||||
NVTT_API void setSwizzleTransform(int x, int y, int z, int w);
|
|
||||||
|
|
||||||
// Set resizing options.
|
// Set resizing options.
|
||||||
NVTT_API void setMaxExtents(int d);
|
NVTT_API void setMaxExtents(int d);
|
||||||
NVTT_API void setRoundMode(RoundMode mode);
|
NVTT_API void setRoundMode(RoundMode mode);
|
||||||
|
|
||||||
// Set whether or not to premultiply color by alpha
|
|
||||||
NVTT_API void setPremultiplyAlpha(bool b);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -364,20 +344,18 @@ namespace nvtt
|
|||||||
NVTT_API void enableCudaAcceleration(bool enable);
|
NVTT_API void enableCudaAcceleration(bool enable);
|
||||||
NVTT_API bool isCudaAccelerationEnabled() const;
|
NVTT_API bool isCudaAccelerationEnabled() const;
|
||||||
|
|
||||||
// InputOptions api.
|
// InputOptions API.
|
||||||
NVTT_API bool process(const InputOptions & inputOptions, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
NVTT_API bool process(const InputOptions & inputOptions, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||||
NVTT_API int estimateSize(const InputOptions & inputOptions, const CompressionOptions & compressionOptions) const;
|
NVTT_API int estimateSize(const InputOptions & inputOptions, const CompressionOptions & compressionOptions) const;
|
||||||
|
|
||||||
// RAW api.
|
// TexImage API.
|
||||||
NVTT_API bool compress2D(InputFormat format, int w, int h, void * data, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
|
||||||
//ßNVTT_API bool compress3D(InputFormat format, int w, int h, int d, void * data, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
|
||||||
NVTT_API int estimateSize(int w, int h, int d, const CompressionOptions & compressionOptions) const;
|
|
||||||
|
|
||||||
// TexImage api.
|
|
||||||
NVTT_API TexImage createTexImage() const;
|
|
||||||
NVTT_API bool outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
NVTT_API bool outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||||
NVTT_API bool compress(const TexImage & tex, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
NVTT_API bool compress(const TexImage & tex, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||||
NVTT_API int estimateSize(const TexImage & tex, const CompressionOptions & compressionOptions) const;
|
NVTT_API int estimateSize(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
||||||
|
|
||||||
|
// Raw API.
|
||||||
|
NVTT_API bool compress(int w, int h, int d, const float * rgba, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||||
|
NVTT_API int estimateSize(int w, int h, int d, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// "Compressor" is deprecated. This should have been called "Context"
|
// "Compressor" is deprecated. This should have been called "Context"
|
||||||
@ -394,6 +372,7 @@ namespace nvtt
|
|||||||
/// A texture mipmap.
|
/// A texture mipmap.
|
||||||
struct TexImage
|
struct TexImage
|
||||||
{
|
{
|
||||||
|
NVTT_API TexImage();
|
||||||
NVTT_API TexImage(const TexImage & tex);
|
NVTT_API TexImage(const TexImage & tex);
|
||||||
NVTT_API ~TexImage();
|
NVTT_API ~TexImage();
|
||||||
|
|
||||||
@ -426,8 +405,11 @@ namespace nvtt
|
|||||||
|
|
||||||
// Resizing methods.
|
// Resizing methods.
|
||||||
NVTT_API void resize(int w, int h, ResizeFilter filter);
|
NVTT_API void resize(int w, int h, ResizeFilter filter);
|
||||||
|
NVTT_API void resize(int w, int h, ResizeFilter filter, float filterWidth, const float * params = 0);
|
||||||
NVTT_API void resize(int maxExtent, RoundMode mode, ResizeFilter filter);
|
NVTT_API void resize(int maxExtent, RoundMode mode, ResizeFilter filter);
|
||||||
|
NVTT_API void resize(int maxExtent, RoundMode mode, ResizeFilter filter, float filterWidth, const float * params = 0);
|
||||||
NVTT_API bool buildNextMipmap(MipmapFilter filter);
|
NVTT_API bool buildNextMipmap(MipmapFilter filter);
|
||||||
|
NVTT_API bool buildNextMipmap(MipmapFilter filter, float filterWidth, const float * params = 0);
|
||||||
|
|
||||||
// Color transforms.
|
// Color transforms.
|
||||||
NVTT_API void toLinear(float gamma);
|
NVTT_API void toLinear(float gamma);
|
||||||
@ -445,10 +427,14 @@ namespace nvtt
|
|||||||
NVTT_API void fill(float r, float g, float b, float a);
|
NVTT_API void fill(float r, float g, float b, float a);
|
||||||
NVTT_API void scaleAlphaToCoverage(float coverage, float alphaRef = 0.5f);
|
NVTT_API void scaleAlphaToCoverage(float coverage, float alphaRef = 0.5f);
|
||||||
NVTT_API bool normalizeRange(float * rangeMin, float * rangeMax);
|
NVTT_API bool normalizeRange(float * rangeMin, float * rangeMax);
|
||||||
|
NVTT_API void toRGBM(float range = 1.0f, float threshold = 0.0f);
|
||||||
|
NVTT_API void toYCoCg();
|
||||||
|
NVTT_API void blockScaleCoCg(int bits = 5, float threshold = 0.0f);
|
||||||
|
|
||||||
|
// @@ Add quantization methods.
|
||||||
|
|
||||||
// Set normal map options.
|
// Set normal map options.
|
||||||
NVTT_API void toNormalMap(float sm, float medium, float big, float large);
|
NVTT_API void toNormalMap(float sm, float medium, float big, float large);
|
||||||
//NVTT_API void toHeightMap();
|
|
||||||
NVTT_API void normalizeNormalMap();
|
NVTT_API void normalizeNormalMap();
|
||||||
|
|
||||||
// Error compare.
|
// Error compare.
|
||||||
@ -463,10 +449,9 @@ namespace nvtt
|
|||||||
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel);
|
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TexImage();
|
|
||||||
void detach();
|
void detach();
|
||||||
|
friend struct Compressor::Private;
|
||||||
|
|
||||||
friend struct Compressor;
|
|
||||||
struct Private;
|
struct Private;
|
||||||
Private * m;
|
Private * m;
|
||||||
};
|
};
|
||||||
@ -478,10 +463,6 @@ namespace nvtt
|
|||||||
// Return NVTT version.
|
// Return NVTT version.
|
||||||
NVTT_API unsigned int version();
|
NVTT_API unsigned int version();
|
||||||
|
|
||||||
// Set callbacks.
|
|
||||||
//NVTT_API void setErrorCallback(ErrorCallback callback);
|
|
||||||
//NVTT_API void setMemoryCallbacks(...);
|
|
||||||
|
|
||||||
} // nvtt namespace
|
} // nvtt namespace
|
||||||
|
|
||||||
#endif // NVTT_H
|
#endif // NVTT_H
|
||||||
|
@ -89,16 +89,6 @@ void nvttSetInputOptionsNormalizeMipmaps(NvttInputOptions * inputOptions, NvttBo
|
|||||||
inputOptions->setNormalizeMipmaps(b != NVTT_False);
|
inputOptions->setNormalizeMipmaps(b != NVTT_False);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nvttSetInputOptionsColorTransform(NvttInputOptions * inputOptions, NvttColorTransform t)
|
|
||||||
{
|
|
||||||
inputOptions->setColorTransform((nvtt::ColorTransform)t);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nvttSetInputOptionsLinearTransfrom(NvttInputOptions * inputOptions, int channel, float w0, float w1, float w2, float w3)
|
|
||||||
{
|
|
||||||
inputOptions->setLinearTransform(channel, w0, w1, w2, w3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nvttSetInputOptionsMaxExtents(NvttInputOptions * inputOptions, int dim)
|
void nvttSetInputOptionsMaxExtents(NvttInputOptions * inputOptions, int dim)
|
||||||
{
|
{
|
||||||
inputOptions->setMaxExtents(dim);
|
inputOptions->setMaxExtents(dim);
|
||||||
|
@ -123,13 +123,6 @@ typedef enum
|
|||||||
NVTT_MipmapFilter_Kaiser,
|
NVTT_MipmapFilter_Kaiser,
|
||||||
} NvttMipmapFilter;
|
} NvttMipmapFilter;
|
||||||
|
|
||||||
/// Color transformation.
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NVTT_ColorTransform_None,
|
|
||||||
NVTT_ColorTransform_Linear,
|
|
||||||
} NvttColorTransform;
|
|
||||||
|
|
||||||
/// Extents rounding mode.
|
/// Extents rounding mode.
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -195,8 +188,6 @@ NVTT_API void nvttSetInputOptionsConvertToNormalMap(NvttInputOptions * inputOpti
|
|||||||
NVTT_API void nvttSetInputOptionsHeightEvaluation(NvttInputOptions * inputOptions, float redScale, float greenScale, float blueScale, float alphaScale);
|
NVTT_API void nvttSetInputOptionsHeightEvaluation(NvttInputOptions * inputOptions, float redScale, float greenScale, float blueScale, float alphaScale);
|
||||||
NVTT_API void nvttSetInputOptionsNormalFilter(NvttInputOptions * inputOptions, float sm, float medium, float big, float large);
|
NVTT_API void nvttSetInputOptionsNormalFilter(NvttInputOptions * inputOptions, float sm, float medium, float big, float large);
|
||||||
NVTT_API void nvttSetInputOptionsNormalizeMipmaps(NvttInputOptions * inputOptions, NvttBoolean b);
|
NVTT_API void nvttSetInputOptionsNormalizeMipmaps(NvttInputOptions * inputOptions, NvttBoolean b);
|
||||||
NVTT_API void nvttSetInputOptionsColorTransform(NvttInputOptions * inputOptions, NvttColorTransform t);
|
|
||||||
NVTT_API void nvttSetInputOptionsLinearTransform(NvttInputOptions * inputOptions, int channel, float w0, float w1, float w2, float w3);
|
|
||||||
NVTT_API void nvttSetInputOptionsMaxExtents(NvttInputOptions * inputOptions, int dim);
|
NVTT_API void nvttSetInputOptionsMaxExtents(NvttInputOptions * inputOptions, int dim);
|
||||||
NVTT_API void nvttSetInputOptionsRoundMode(NvttInputOptions * inputOptions, NvttRoundMode mode);
|
NVTT_API void nvttSetInputOptionsRoundMode(NvttInputOptions * inputOptions, NvttRoundMode mode);
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ int main(int argc, char *argv[])
|
|||||||
context.enableCudaAcceleration(false);
|
context.enableCudaAcceleration(false);
|
||||||
|
|
||||||
// Load input image.
|
// Load input image.
|
||||||
nvtt::TexImage image = context.createTexImage();
|
nvtt::TexImage image;
|
||||||
if (!image.load(inputFileName)) {
|
if (!image.load(inputFileName)) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ int main(int argc, char *argv[])
|
|||||||
context.enableCudaAcceleration(false);
|
context.enableCudaAcceleration(false);
|
||||||
|
|
||||||
// Load color map.
|
// Load color map.
|
||||||
nvtt::TexImage colorMap = context.createTexImage();
|
nvtt::TexImage colorMap;
|
||||||
if (!colorMap.load(inputFileNameColor)) {
|
if (!colorMap.load(inputFileNameColor)) {
|
||||||
printf("Image '%s' could not be loaded.\n", inputFileNameColor);
|
printf("Image '%s' could not be loaded.\n", inputFileNameColor);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@ -63,9 +63,8 @@ int main(int argc, char *argv[])
|
|||||||
colorOutputOptions.setFileName(outputFileNameColor.str());
|
colorOutputOptions.setFileName(outputFileNameColor.str());
|
||||||
|
|
||||||
// Load normal map.
|
// Load normal map.
|
||||||
nvtt::TexImage normalMap = context.createTexImage();
|
nvtt::TexImage normalMap;
|
||||||
if (inputFileNameNormal != NULL) {
|
if (inputFileNameNormal != NULL) {
|
||||||
normalMap = context.createTexImage();
|
|
||||||
if (!normalMap.load(inputFileNameColor)) {
|
if (!normalMap.load(inputFileNameColor)) {
|
||||||
printf("Image '%s' could not be loaded.\n", inputFileNameNormal);
|
printf("Image '%s' could not be loaded.\n", inputFileNameNormal);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <stdlib.h> // free
|
#include <stdlib.h> // free
|
||||||
#include <string.h> // memcpy
|
#include <string.h> // memcpy
|
||||||
|
|
||||||
|
#include "../tools/cmdline.h"
|
||||||
|
|
||||||
using namespace nv;
|
using namespace nv;
|
||||||
|
|
||||||
@ -294,11 +295,15 @@ float rmsError(const Image * a, const Image * b)
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
const uint version = nvtt::version();
|
MyAssertHandler assertHandler;
|
||||||
const uint major = version / 100;
|
MyMessageHandler messageHandler;
|
||||||
const uint minor = version % 100;
|
|
||||||
|
|
||||||
printf("NVIDIA Texture Tools %u.%u - Copyright NVIDIA Corporation 2007 - 2008\n\n", major, minor);
|
const uint version = nvtt::version();
|
||||||
|
const uint major = version / 100 / 100;
|
||||||
|
const uint minor = (version / 100) % 100;
|
||||||
|
const uint rev = version % 100;
|
||||||
|
|
||||||
|
printf("NVIDIA Texture Tools %u.%u.%u - Copyright NVIDIA Corporation 2007\n\n", major, minor, rev);
|
||||||
|
|
||||||
int set = 0;
|
int set = 0;
|
||||||
bool fast = false;
|
bool fast = false;
|
||||||
|
@ -412,10 +412,10 @@ int main(int argc, char *argv[])
|
|||||||
inputOptions.setFormat(nvtt::InputFormat_RGBA_32F);
|
inputOptions.setFormat(nvtt::InputFormat_RGBA_32F);
|
||||||
inputOptions.setTextureLayout(nvtt::TextureType_2D, image->width(), image->height());
|
inputOptions.setTextureLayout(nvtt::TextureType_2D, image->width(), image->height());
|
||||||
|
|
||||||
for (uint i = 0; i < image->componentNum(); i++)
|
/*for (uint i = 0; i < image->componentNum(); i++)
|
||||||
{
|
{
|
||||||
inputOptions.setMipmapChannelData(image->channel(i), i, image->width(), image->height());
|
inputOptions.setMipmapChannelData(image->channel(i), i, image->width(), image->height());
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -450,8 +450,11 @@ int main(int argc, char *argv[])
|
|||||||
inputOptions.setAlphaMode(nvtt::AlphaMode_None);
|
inputOptions.setAlphaMode(nvtt::AlphaMode_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Block compressed textures with mipmaps must be powers of two.
|
||||||
|
//if (!noMipmaps && format != nvtt::Format_RGB)
|
||||||
|
{
|
||||||
inputOptions.setRoundMode(nvtt::RoundMode_ToNearestPowerOfTwo);
|
inputOptions.setRoundMode(nvtt::RoundMode_ToNearestPowerOfTwo);
|
||||||
|
}
|
||||||
|
|
||||||
if (normal)
|
if (normal)
|
||||||
{
|
{
|
||||||
@ -471,11 +474,11 @@ int main(int argc, char *argv[])
|
|||||||
inputOptions.setMipmapGeneration(false);
|
inputOptions.setMipmapGeneration(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (premultiplyAlpha)
|
/*if (premultiplyAlpha)
|
||||||
{
|
{
|
||||||
inputOptions.setPremultiplyAlpha(true);
|
inputOptions.setPremultiplyAlpha(true);
|
||||||
inputOptions.setAlphaMode(nvtt::AlphaMode_Premultiplied);
|
inputOptions.setAlphaMode(nvtt::AlphaMode_Premultiplied);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
inputOptions.setMipmapFilter(mipmapFilter);
|
inputOptions.setMipmapFilter(mipmapFilter);
|
||||||
|
|
||||||
|
@ -169,14 +169,14 @@ int main(int argc, char *argv[])
|
|||||||
nv::FloatImage fimage(&image);
|
nv::FloatImage fimage(&image);
|
||||||
fimage.toLinear(0, 3, gamma);
|
fimage.toLinear(0, 3, gamma);
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
nv::AutoPtr<nv::FloatImage> fresult(fimage.resize(*filter, uint(image.width() * scale), uint(image.height() * scale), wrapMode));
|
nv::AutoPtr<nv::FloatImage> fresult(fimage.resize(*filter, uint(image.width() * scale), uint(image.height() * scale), wrapMode));
|
||||||
|
|
||||||
nv::AutoPtr<nv::Image> result(fresult->createImageGammaCorrect(gamma));
|
nv::AutoPtr<nv::Image> result(fresult->createImageGammaCorrect(gamma));
|
||||||
result->setFormat(nv::Image::Format_ARGB);
|
result->setFormat(nv::Image::Format_ARGB);
|
||||||
|
|
||||||
nv::StdOutputStream stream(output);
|
nv::StdOutputStream stream(output.str());
|
||||||
nv::ImageIO::save(output, stream, result.ptr());
|
nv::ImageIO::save(output.str(), stream, result.ptr());
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user