Add support for input rescaling:
- round extents to power of two. - clamp max extents. Add output options pimpl. Other misc API changes.
This commit is contained in:
parent
817652c56c
commit
cfa4913ae6
@ -15,13 +15,17 @@ SET(NVTT_SRCS
|
||||
FastCompressDXT.cpp
|
||||
QuickCompressDXT.h
|
||||
QuickCompressDXT.cpp
|
||||
SingleColorLookup.h
|
||||
CompressionOptions.h
|
||||
CompressionOptions.cpp
|
||||
InputOptions.h
|
||||
InputOptions.cpp
|
||||
OutputOptions.h
|
||||
OutputOptions.cpp
|
||||
cuda/CudaUtils.h
|
||||
cuda/CudaUtils.cpp
|
||||
cuda/CudaMath.h
|
||||
cuda/Bitmaps.h
|
||||
cuda/CudaCompressDXT.h
|
||||
cuda/CudaCompressDXT.cpp)
|
||||
|
||||
@ -45,23 +49,62 @@ ENDIF(NVTT_SHARED)
|
||||
|
||||
TARGET_LINK_LIBRARIES(nvtt ${LIBS} nvcore nvmath nvimage squish)
|
||||
|
||||
INSTALL(TARGETS nvtt
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib/static)
|
||||
|
||||
INSTALL(FILES nvtt.h DESTINATION include/nvtt)
|
||||
|
||||
|
||||
|
||||
# test executables
|
||||
ADD_EXECUTABLE(nvcompress tools/compress.cpp)
|
||||
ADD_EXECUTABLE(nvcompress tools/compress.cpp tools/cmdline.h)
|
||||
TARGET_LINK_LIBRARIES(nvcompress nvcore nvmath nvimage nvtt)
|
||||
|
||||
ADD_EXECUTABLE(nvdecompress tools/decompress.cpp)
|
||||
ADD_EXECUTABLE(nvdecompress tools/decompress.cpp tools/cmdline.h)
|
||||
TARGET_LINK_LIBRARIES(nvdecompress nvcore nvmath nvimage)
|
||||
|
||||
ADD_EXECUTABLE(nvddsinfo tools/ddsinfo.cpp)
|
||||
ADD_EXECUTABLE(nvddsinfo tools/ddsinfo.cpp tools/cmdline.h)
|
||||
TARGET_LINK_LIBRARIES(nvddsinfo nvcore nvmath nvimage)
|
||||
|
||||
ADD_EXECUTABLE(nvimgdiff tools/imgdiff.cpp)
|
||||
ADD_EXECUTABLE(nvimgdiff tools/imgdiff.cpp tools/cmdline.h)
|
||||
TARGET_LINK_LIBRARIES(nvimgdiff nvcore nvmath nvimage)
|
||||
|
||||
ADD_EXECUTABLE(nvassemble tools/assemble.cpp)
|
||||
ADD_EXECUTABLE(nvassemble tools/assemble.cpp tools/cmdline.h)
|
||||
TARGET_LINK_LIBRARIES(nvassemble nvcore nvmath nvimage)
|
||||
|
||||
INSTALL(TARGETS nvcompress nvdecompress nvddsinfo nvimgdiff nvassemble DESTINATION bin)
|
||||
ADD_EXECUTABLE(filtertest tests/filtertest.cpp tools/cmdline.h)
|
||||
TARGET_LINK_LIBRARIES(filtertest nvcore nvmath nvimage)
|
||||
|
||||
ADD_EXECUTABLE(nvzoom tools/resize.cpp tools/cmdline.h)
|
||||
TARGET_LINK_LIBRARIES(nvzoom nvcore nvmath nvimage)
|
||||
|
||||
INSTALL(TARGETS nvcompress nvdecompress nvddsinfo nvimgdiff nvassemble nvzoom DESTINATION bin)
|
||||
|
||||
# UI tools
|
||||
IF(QT4_FOUND)
|
||||
SET(QT_USE_QTOPENGL TRUE)
|
||||
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
SET(SRCS
|
||||
tools/main.cpp
|
||||
tools/configdialog.h
|
||||
tools/configdialog.cpp)
|
||||
|
||||
SET(LIBS
|
||||
nvtt
|
||||
${QT_QTCORE_LIBRARY}
|
||||
${QT_QTGUI_LIBRARY}
|
||||
${QT_QTOPENGL_LIBRARY})
|
||||
|
||||
QT4_WRAP_UI(UICS tools/configdialog.ui)
|
||||
QT4_WRAP_CPP(MOCS tools/configdialog.h)
|
||||
#QT4_ADD_RESOURCES(RCCS tools/configdialog.rc)
|
||||
|
||||
ADD_EXECUTABLE(nvcompressui MACOSX_BUNDLE ${SRCS} ${UICS} ${MOCS})
|
||||
TARGET_LINK_LIBRARIES(nvcompressui ${LIBS})
|
||||
|
||||
ENDIF(QT4_FOUND)
|
||||
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "FastCompressDXT.h"
|
||||
#include "QuickCompressDXT.h"
|
||||
#include "CompressionOptions.h"
|
||||
#include "OutputOptions.h"
|
||||
|
||||
// squish
|
||||
#include "squish/colourset.h"
|
||||
@ -55,7 +56,7 @@ using namespace nv;
|
||||
using namespace nvtt;
|
||||
|
||||
|
||||
void nv::fastCompressDXT1(const Image * image, const OutputOptions & outputOptions)
|
||||
void nv::fastCompressDXT1(const Image * image, const OutputOptions::Private & outputOptions)
|
||||
{
|
||||
const uint w = image->width();
|
||||
const uint h = image->height();
|
||||
@ -77,7 +78,7 @@ void nv::fastCompressDXT1(const Image * image, const OutputOptions & outputOptio
|
||||
}
|
||||
|
||||
|
||||
void nv::fastCompressDXT1a(const Image * image, const OutputOptions & outputOptions)
|
||||
void nv::fastCompressDXT1a(const Image * image, const OutputOptions::Private & outputOptions)
|
||||
{
|
||||
const uint w = image->width();
|
||||
const uint h = image->height();
|
||||
@ -99,7 +100,7 @@ void nv::fastCompressDXT1a(const Image * image, const OutputOptions & outputOpti
|
||||
}
|
||||
|
||||
|
||||
void nv::fastCompressDXT3(const Image * image, const nvtt::OutputOptions & outputOptions)
|
||||
void nv::fastCompressDXT3(const Image * image, const nvtt::OutputOptions::Private & outputOptions)
|
||||
{
|
||||
const uint w = image->width();
|
||||
const uint h = image->height();
|
||||
@ -120,7 +121,7 @@ void nv::fastCompressDXT3(const Image * image, const nvtt::OutputOptions & outpu
|
||||
}
|
||||
|
||||
|
||||
void nv::fastCompressDXT5(const Image * image, const nvtt::OutputOptions & outputOptions)
|
||||
void nv::fastCompressDXT5(const Image * image, const nvtt::OutputOptions::Private & outputOptions)
|
||||
{
|
||||
const uint w = image->width();
|
||||
const uint h = image->height();
|
||||
@ -141,7 +142,7 @@ void nv::fastCompressDXT5(const Image * image, const nvtt::OutputOptions & outpu
|
||||
}
|
||||
|
||||
|
||||
void nv::fastCompressDXT5n(const Image * image, const nvtt::OutputOptions & outputOptions)
|
||||
void nv::fastCompressDXT5n(const Image * image, const nvtt::OutputOptions::Private & outputOptions)
|
||||
{
|
||||
const uint w = image->width();
|
||||
const uint h = image->height();
|
||||
@ -166,14 +167,14 @@ void nv::fastCompressDXT5n(const Image * image, const nvtt::OutputOptions & outp
|
||||
}
|
||||
|
||||
|
||||
void nv::fastCompressBC4(const Image * image, const nvtt::OutputOptions & outputOptions)
|
||||
void nv::fastCompressBC4(const Image * image, const nvtt::OutputOptions::Private & outputOptions)
|
||||
{
|
||||
// @@ TODO
|
||||
// compress red channel (X)
|
||||
}
|
||||
|
||||
|
||||
void nv::fastCompressBC5(const Image * image, const nvtt::OutputOptions & outputOptions)
|
||||
void nv::fastCompressBC5(const Image * image, const nvtt::OutputOptions::Private & outputOptions)
|
||||
{
|
||||
// @@ TODO
|
||||
// compress red, green channels (X,Y)
|
||||
@ -192,7 +193,7 @@ void nv::doPrecomputation()
|
||||
}
|
||||
|
||||
|
||||
void nv::compressDXT1(const Image * image, const OutputOptions & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
void nv::compressDXT1(const Image * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
{
|
||||
const uint w = image->width();
|
||||
const uint h = image->height();
|
||||
@ -225,7 +226,7 @@ void nv::compressDXT1(const Image * image, const OutputOptions & outputOptions,
|
||||
}
|
||||
|
||||
|
||||
void nv::compressDXT3(const Image * image, const OutputOptions & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
void nv::compressDXT3(const Image * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
{
|
||||
const uint w = image->width();
|
||||
const uint h = image->height();
|
||||
@ -254,7 +255,7 @@ void nv::compressDXT3(const Image * image, const OutputOptions & outputOptions,
|
||||
}
|
||||
}
|
||||
|
||||
void nv::compressDXT5(const Image * image, const OutputOptions & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
void nv::compressDXT5(const Image * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
{
|
||||
const uint w = image->width();
|
||||
const uint h = image->height();
|
||||
@ -292,7 +293,7 @@ void nv::compressDXT5(const Image * image, const OutputOptions & outputOptions,
|
||||
}
|
||||
|
||||
|
||||
void nv::compressDXT5n(const Image * image, const OutputOptions & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
void nv::compressDXT5n(const Image * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
{
|
||||
const uint w = image->width();
|
||||
const uint h = image->height();
|
||||
@ -328,7 +329,7 @@ void nv::compressDXT5n(const Image * image, const OutputOptions & outputOptions,
|
||||
}
|
||||
|
||||
|
||||
void nv::compressBC4(const Image * image, const nvtt::OutputOptions & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
void nv::compressBC4(const Image * image, const nvtt::OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
{
|
||||
const uint w = image->width();
|
||||
const uint h = image->height();
|
||||
@ -380,7 +381,7 @@ void nv::compressBC4(const Image * image, const nvtt::OutputOptions & outputOpti
|
||||
}
|
||||
|
||||
|
||||
void nv::compressBC5(const Image * image, const nvtt::OutputOptions & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
void nv::compressBC5(const Image * image, const nvtt::OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
{
|
||||
const uint w = image->width();
|
||||
const uint h = image->height();
|
||||
@ -423,7 +424,7 @@ void nv::compressBC5(const Image * image, const nvtt::OutputOptions & outputOpti
|
||||
|
||||
#if defined(HAVE_S3QUANT)
|
||||
|
||||
void nv::s3CompressDXT1(const Image * image, const nvtt::OutputOptions & outputOptions)
|
||||
void nv::s3CompressDXT1(const Image * image, const nvtt::OutputOptions::Private & outputOptions)
|
||||
{
|
||||
const uint w = image->width();
|
||||
const uint h = image->height();
|
||||
@ -518,7 +519,7 @@ void nv::s3CompressDXT1(const Image * image, const nvtt::OutputOptions & outputO
|
||||
|
||||
#if defined(HAVE_ATITC)
|
||||
|
||||
void nv::atiCompressDXT1(const Image * image, const OutputOptions & outputOptions)
|
||||
void nv::atiCompressDXT1(const Image * image, const OutputOptions::Private & outputOptions)
|
||||
{
|
||||
// Init source texture
|
||||
ATI_TC_Texture srcTexture;
|
||||
|
@ -35,29 +35,29 @@ namespace nv
|
||||
void doPrecomputation();
|
||||
|
||||
// Fast compressors.
|
||||
void fastCompressDXT1(const Image * image, const nvtt::OutputOptions & outputOptions);
|
||||
void fastCompressDXT1a(const Image * image, const nvtt::OutputOptions & outputOptions);
|
||||
void fastCompressDXT3(const Image * image, const nvtt::OutputOptions & outputOptions);
|
||||
void fastCompressDXT5(const Image * image, const nvtt::OutputOptions & outputOptions);
|
||||
void fastCompressDXT5n(const Image * image, const nvtt::OutputOptions & outputOptions);
|
||||
void fastCompressBC4(const Image * image, const nvtt::OutputOptions & outputOptions);
|
||||
void fastCompressBC5(const Image * image, const nvtt::OutputOptions & outputOptions);
|
||||
void fastCompressDXT1(const Image * image, const nvtt::OutputOptions::Private & outputOptions);
|
||||
void fastCompressDXT1a(const Image * image, const nvtt::OutputOptions::Private & outputOptions);
|
||||
void fastCompressDXT3(const Image * image, const nvtt::OutputOptions::Private & outputOptions);
|
||||
void fastCompressDXT5(const Image * image, const nvtt::OutputOptions::Private & outputOptions);
|
||||
void fastCompressDXT5n(const Image * image, const nvtt::OutputOptions::Private & outputOptions);
|
||||
void fastCompressBC4(const Image * image, const nvtt::OutputOptions::Private & outputOptions);
|
||||
void fastCompressBC5(const Image * image, const nvtt::OutputOptions::Private & outputOptions);
|
||||
|
||||
// Normal compressors.
|
||||
void compressDXT1(const Image * image, const nvtt::OutputOptions & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
void compressDXT3(const Image * image, const nvtt::OutputOptions & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
void compressDXT5(const Image * image, const nvtt::OutputOptions & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
void compressDXT5n(const Image * image, const nvtt::OutputOptions & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
void compressBC4(const Image * image, const nvtt::OutputOptions & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
void compressBC5(const Image * image, const nvtt::OutputOptions & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
void compressDXT1(const Image * image, const nvtt::OutputOptions::Private & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
void compressDXT3(const Image * image, const nvtt::OutputOptions::Private & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
void compressDXT5(const Image * image, const nvtt::OutputOptions::Private & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
void compressDXT5n(const Image * image, const nvtt::OutputOptions::Private & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
void compressBC4(const Image * image, const nvtt::OutputOptions::Private & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
void compressBC5(const Image * image, const nvtt::OutputOptions::Private & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
|
||||
// External compressors.
|
||||
#if defined(HAVE_S3QUANT)
|
||||
void s3CompressDXT1(const Image * image, const nvtt::OutputOptions & outputOptions);
|
||||
void s3CompressDXT1(const Image * image, const nvtt::OutputOptions::Private & outputOptions);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ATITC)
|
||||
void atiCompressDXT1(const Image * image, const nvtt::OutputOptions & outputOptions);
|
||||
void atiCompressDXT1(const Image * image, const nvtt::OutputOptions::Private & outputOptions);
|
||||
#endif
|
||||
|
||||
} // nv namespace
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#include "CompressRGB.h"
|
||||
#include "CompressionOptions.h"
|
||||
|
||||
#include "OutputOptions.h"
|
||||
|
||||
using namespace nv;
|
||||
using namespace nvtt;
|
||||
@ -59,7 +59,7 @@ namespace
|
||||
|
||||
|
||||
// Pixel format converter.
|
||||
void nv::compressRGB(const Image * image, const OutputOptions & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
void nv::compressRGB(const Image * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
{
|
||||
nvCheck(image != NULL);
|
||||
|
||||
|
@ -19,21 +19,21 @@
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef NV_TT_COMPRESSRGB_H
|
||||
#define NV_TT_COMPRESSRGB_H
|
||||
|
||||
#include "nvtt.h"
|
||||
|
||||
namespace nv
|
||||
{
|
||||
class Image;
|
||||
|
||||
// Pixel format converter.
|
||||
void compressRGB(const Image * image, const nvtt::OutputOptions & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
|
||||
} // nv namespace
|
||||
|
||||
|
||||
#endif // NV_TT_COMPRESSDXT_H
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef NV_TT_COMPRESSRGB_H
|
||||
#define NV_TT_COMPRESSRGB_H
|
||||
|
||||
#include "nvtt.h"
|
||||
|
||||
namespace nv
|
||||
{
|
||||
class Image;
|
||||
|
||||
// Pixel format converter.
|
||||
void compressRGB(const Image * image, const nvtt::OutputOptions::Private & outputOptions, const nvtt::CompressionOptions::Private & compressionOptions);
|
||||
|
||||
} // nv namespace
|
||||
|
||||
|
||||
#endif // NV_TT_COMPRESSDXT_H
|
||||
|
@ -87,12 +87,18 @@ void CompressionOptions::setColorWeights(float red, float green, float blue)
|
||||
}
|
||||
|
||||
|
||||
/// Enable or disable hardware compression.
|
||||
/// Enable or disable CUDA compression.
|
||||
void CompressionOptions::enableHardwareCompression(bool enable)
|
||||
{
|
||||
m.useCuda = enable;
|
||||
}
|
||||
|
||||
/// Enable or disable CUDA compression.
|
||||
void CompressionOptions::enableCudaCompression(bool enable)
|
||||
{
|
||||
m.useCuda = enable;
|
||||
}
|
||||
|
||||
|
||||
/// Set color mask to describe the RGB/RGBA format.
|
||||
void CompressionOptions::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
|
||||
|
@ -34,9 +34,9 @@ using namespace nvtt;
|
||||
namespace
|
||||
{
|
||||
|
||||
static int countMipmaps(int w, int h, int d)
|
||||
static uint countMipmaps(int w, int h, int d)
|
||||
{
|
||||
int mipmap = 0;
|
||||
uint mipmap = 0;
|
||||
|
||||
while (w != 1 || h != 1 || d != 1) {
|
||||
w = max(1, w / 2);
|
||||
@ -48,6 +48,27 @@ namespace
|
||||
return mipmap + 1;
|
||||
}
|
||||
|
||||
// 1 -> 1, 2 -> 2, 3 -> 2, 4 -> 4, 5 -> 4, ...
|
||||
static uint previousPowerOfTwo(const uint v)
|
||||
{
|
||||
return nextPowerOfTwo(v + 1) / 2;
|
||||
}
|
||||
|
||||
static uint nearestPowerOfTwo(const uint v)
|
||||
{
|
||||
const uint np2 = nextPowerOfTwo(v);
|
||||
const uint pp2 = previousPowerOfTwo(v);
|
||||
|
||||
if (np2 - v <= v - pp2)
|
||||
{
|
||||
return np2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pp2;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@ -69,7 +90,7 @@ InputOptions::~InputOptions()
|
||||
// Reset input options.
|
||||
void InputOptions::reset()
|
||||
{
|
||||
m.wrapMode = WrapMode_Repeat;
|
||||
m.wrapMode = WrapMode_Mirror;
|
||||
m.textureType = TextureType_2D;
|
||||
m.inputFormat = InputFormat_BGRA_8UB;
|
||||
|
||||
@ -78,26 +99,30 @@ void InputOptions::reset()
|
||||
m.binaryAlpha = false;
|
||||
m.alphaThreshold = 127;
|
||||
|
||||
m.alphaTransparency = true;
|
||||
m.alphaMode = AlphaMode_Transparency;
|
||||
|
||||
m.inputGamma = 2.2f;
|
||||
m.outputGamma = 2.2f;
|
||||
|
||||
m.colorTransform = ColorTransform_None;
|
||||
m.linearTransform = Matrix(identity);
|
||||
m.colorTransform = ColorTransform_None;
|
||||
m.linearTransform = Matrix(identity);
|
||||
|
||||
m.generateMipmaps = false;
|
||||
m.maxLevel = -1;
|
||||
m.mipmapFilter = MipmapFilter_Box;
|
||||
|
||||
m.kaiserWidth = 10;
|
||||
m.kaiserAlpha = 8.0f;
|
||||
m.kaiserStretch = 0.75f;
|
||||
m.kaiserWidth = 3;
|
||||
m.kaiserAlpha = 4.0f;
|
||||
m.kaiserStretch = 1.0f;
|
||||
|
||||
m.normalizeMipmaps = false;
|
||||
m.isNormalMap = false;
|
||||
m.normalizeMipmaps = true;
|
||||
m.convertToNormalMap = false;
|
||||
m.heightFactors.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
m.bumpFrequencyScale = Vector4(1.0f, 0.5f, 0.25f, 0.125f) / (1.0f + 0.5f + 0.25f + 0.125f);
|
||||
|
||||
m.maxExtent = 0;
|
||||
m.roundMode = RoundMode_None;
|
||||
}
|
||||
|
||||
|
||||
@ -126,13 +151,13 @@ void InputOptions::setTextureLayout(TextureType type, int width, int height, int
|
||||
|
||||
m.images = new Private::Image[m.imageCount];
|
||||
|
||||
for(int f = 0; f < m.faceCount; f++)
|
||||
for(uint f = 0; f < m.faceCount; f++)
|
||||
{
|
||||
int w = width;
|
||||
int h = height;
|
||||
int d = depth;
|
||||
uint w = width;
|
||||
uint h = height;
|
||||
uint d = depth;
|
||||
|
||||
for (int mipLevel = 0; mipLevel < m.mipmapCount; mipLevel++)
|
||||
for (uint mipLevel = 0; mipLevel < m.mipmapCount; mipLevel++)
|
||||
{
|
||||
Private::Image & img = m.images[f * m.mipmapCount + mipLevel];
|
||||
img.width = w;
|
||||
@ -143,9 +168,9 @@ void InputOptions::setTextureLayout(TextureType type, int width, int height, int
|
||||
|
||||
img.data = NULL;
|
||||
|
||||
w = max(1, w / 2);
|
||||
h = max(1, h / 2);
|
||||
d = max(1, d / 2);
|
||||
w = max(1U, w / 2);
|
||||
h = max(1U, h / 2);
|
||||
d = max(1U, d / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -188,10 +213,21 @@ bool InputOptions::setMipmapData(const void * data, int width, int height, int d
|
||||
|
||||
|
||||
/// Describe the format of the input.
|
||||
void InputOptions::setFormat(InputFormat format, bool alphaTransparency)
|
||||
void InputOptions::setFormat(InputFormat format, /*deprecated*/bool alphaTransparency)
|
||||
{
|
||||
m.inputFormat = format;
|
||||
m.alphaTransparency = alphaTransparency;
|
||||
//m.alphaTransparency = alphaTransparency;
|
||||
}
|
||||
void InputOptions::setFormat(InputFormat format)
|
||||
{
|
||||
m.inputFormat = format;
|
||||
}
|
||||
|
||||
|
||||
/// Set the way the input alpha channel is interpreted.
|
||||
void InputOptions::setAlphaMode(AlphaMode alphaMode)
|
||||
{
|
||||
m.alphaMode = alphaMode;
|
||||
}
|
||||
|
||||
|
||||
@ -219,7 +255,7 @@ void InputOptions::setMipmapping(bool generateMipmaps, MipmapFilter filter/*= Mi
|
||||
}
|
||||
|
||||
/// Set Kaiser filter parameters.
|
||||
void InputOptions::setKaiserParameters(int width, float alpha, float stretch)
|
||||
void InputOptions::setKaiserParameters(float width, float alpha, float stretch)
|
||||
{
|
||||
m.kaiserWidth = width;
|
||||
m.kaiserAlpha = alpha;
|
||||
@ -233,6 +269,7 @@ void InputOptions::setKaiserParameters(int width, float alpha, float stretch)
|
||||
/// the compressor.
|
||||
void InputOptions::setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold/*= 127*/)
|
||||
{
|
||||
nvCheck(alphaThreshold >= 0 && alphaThreshold < 256);
|
||||
m.enableColorDithering = colorDithering;
|
||||
m.enableAlphaDithering = alphaDithering;
|
||||
m.binaryAlpha = binaryAlpha;
|
||||
@ -243,7 +280,7 @@ void InputOptions::setQuantization(bool colorDithering, bool alphaDithering, boo
|
||||
/// Indicate whether input is a normal map or not.
|
||||
void InputOptions::setNormalMap(bool b)
|
||||
{
|
||||
m.normalMap = b;
|
||||
m.isNormalMap = b;
|
||||
}
|
||||
|
||||
/// Enable normal map conversion.
|
||||
@ -287,3 +324,103 @@ void InputOptions::setLinearTransfrom(int channel, float w0, float w1, float w2,
|
||||
Vector4 w(w0, w1, w2, w3);
|
||||
//m.linearTransform.setRow(channel, w);
|
||||
}
|
||||
|
||||
void InputOptions::setMaxExtents(int e)
|
||||
{
|
||||
nvDebugCheck(e > 0);
|
||||
m.maxExtent = e;
|
||||
}
|
||||
|
||||
void InputOptions::setRoundMode(RoundMode mode)
|
||||
{
|
||||
m.roundMode = mode;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// Called everytime max extents or rounding mode changes.
|
||||
int InputOptions::Private::firstMipmap(int face) const
|
||||
{
|
||||
nvCheck(images != NULL);
|
||||
|
||||
// @@ Find the last image that's not NULL and is greater than target extents.
|
||||
|
||||
uint first = 0;
|
||||
for (uint f = 0; f < mipmapCount; f++)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -36,54 +36,65 @@ namespace nvtt
|
||||
struct InputOptions::Private
|
||||
{
|
||||
Private() : images(NULL) {}
|
||||
|
||||
|
||||
WrapMode wrapMode;
|
||||
TextureType textureType;
|
||||
InputFormat inputFormat;
|
||||
AlphaMode alphaMode;
|
||||
|
||||
int faceCount;
|
||||
int mipmapCount;
|
||||
int imageCount;
|
||||
uint faceCount;
|
||||
uint mipmapCount;
|
||||
uint imageCount;
|
||||
|
||||
struct Image;
|
||||
Image * images;
|
||||
|
||||
|
||||
// Quantization.
|
||||
bool enableColorDithering;
|
||||
bool enableAlphaDithering;
|
||||
bool binaryAlpha;
|
||||
int alphaThreshold; // reference value used for binary alpha quantization.
|
||||
|
||||
bool alphaTransparency; // set to true if alpha is used for transparency.
|
||||
|
||||
// Gamma conversion.
|
||||
float inputGamma;
|
||||
float outputGamma;
|
||||
|
||||
|
||||
// Color transform.
|
||||
ColorTransform colorTransform;
|
||||
nv::Matrix linearTransform;
|
||||
|
||||
|
||||
// Mipmap generation options.
|
||||
bool generateMipmaps;
|
||||
int maxLevel;
|
||||
MipmapFilter mipmapFilter;
|
||||
|
||||
// Kaiser filter parameters.
|
||||
uint kaiserWidth;
|
||||
float kaiserAlpha;
|
||||
float kaiserStretch;
|
||||
|
||||
|
||||
// Kaiser filter parameters.
|
||||
float kaiserWidth;
|
||||
float kaiserAlpha;
|
||||
float kaiserStretch;
|
||||
|
||||
// Normal map options.
|
||||
bool normalMap;
|
||||
bool isNormalMap;
|
||||
bool normalizeMipmaps;
|
||||
bool convertToNormalMap;
|
||||
nv::Vector4 heightFactors; // Used for cone mapping too.
|
||||
nv::Vector4 heightFactors;
|
||||
nv::Vector4 bumpFrequencyScale;
|
||||
|
||||
// Cone map options.
|
||||
bool convertToConeMap;
|
||||
|
||||
|
||||
// Adjust extents.
|
||||
uint maxExtent;
|
||||
RoundMode roundMode;
|
||||
|
||||
// @@ 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;
|
||||
int firstMipmap(int face) const;
|
||||
|
||||
};
|
||||
|
||||
// Internal image structure.
|
||||
|
@ -21,12 +21,105 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include "nvtt.h"
|
||||
#include "OutputOptions.h"
|
||||
|
||||
using namespace nvtt;
|
||||
|
||||
|
||||
OutputOptions::OutputOptions() : m(*new OutputOptions::Private())
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
OutputOptions::OutputOptions(OutputHandler * oh, ErrorHandler * eh) : m(*new OutputOptions::Private())
|
||||
{
|
||||
reset();
|
||||
outputHandler = oh;
|
||||
errorHandler = eh;
|
||||
}
|
||||
|
||||
OutputOptions::~OutputOptions()
|
||||
{
|
||||
delete &m;
|
||||
}
|
||||
|
||||
/// Set default output options.
|
||||
void OutputOptions::reset()
|
||||
{
|
||||
// endiannes = native...
|
||||
m.fileName.reset();
|
||||
m.outputHandler = NULL;
|
||||
m.errorHandler = NULL;
|
||||
m.outputHeader = true;
|
||||
|
||||
outputHandler = NULL;
|
||||
errorHandler = NULL;
|
||||
outputHeader = true;
|
||||
}
|
||||
|
||||
|
||||
/// Set output file name.
|
||||
void OutputOptions::setFileName(const char * fileName)
|
||||
{
|
||||
m.fileName = fileName;
|
||||
outputHandler = NULL;
|
||||
}
|
||||
|
||||
/// Set output handler.
|
||||
void OutputOptions::setOutputHandler(OutputHandler * outputHandler)
|
||||
{
|
||||
m.fileName.reset();
|
||||
this->outputHandler = outputHandler;
|
||||
}
|
||||
|
||||
/// Set error handler.
|
||||
void OutputOptions::setErrorHandler(ErrorHandler * errorHandler)
|
||||
{
|
||||
this->errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
/// Set output header.
|
||||
void OutputOptions::setOutputHeader(bool outputHeader)
|
||||
{
|
||||
this->outputHeader = outputHeader;
|
||||
}
|
||||
|
||||
|
||||
bool OutputOptions::Private::openFile() const
|
||||
{
|
||||
if (!fileName.isNull())
|
||||
{
|
||||
nvCheck(outputHandler == NULL);
|
||||
|
||||
DefaultOutputHandler * oh = new DefaultOutputHandler(fileName.str());
|
||||
if (oh->stream.isError())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
outputHandler = oh;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OutputOptions::Private::closeFile() const
|
||||
{
|
||||
if (!fileName.isNull())
|
||||
{
|
||||
delete outputHandler;
|
||||
outputHandler = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nvtt::initOptions(OutputOptions * outputOptions)
|
||||
{
|
||||
nvDebugCheck(outputOptions != NULL);
|
||||
|
||||
OutputOptions::Private & pimpl = outputOptions->m;
|
||||
|
||||
pimpl.outputHandler = outputOptions->outputHandler;
|
||||
pimpl.errorHandler = outputOptions->errorHandler;
|
||||
pimpl.outputHeader = outputOptions->outputHeader;
|
||||
}
|
||||
|
||||
|
76
src/nvtt/OutputOptions.h
Normal file
76
src/nvtt/OutputOptions.h
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef NV_TT_OUTPUTOPTIONS_H
|
||||
#define NV_TT_OUTPUTOPTIONS_H
|
||||
|
||||
#include <nvcore/StrLib.h>
|
||||
#include <nvcore/StdStream.h>
|
||||
#include "nvtt.h"
|
||||
|
||||
namespace nvtt
|
||||
{
|
||||
|
||||
struct DefaultOutputHandler : public nvtt::OutputHandler
|
||||
{
|
||||
DefaultOutputHandler(const char * fileName) : stream(fileName) {}
|
||||
|
||||
virtual ~DefaultOutputHandler()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void mipmap(int size, int width, int height, int depth, int face, int miplevel)
|
||||
{
|
||||
// ignore.
|
||||
}
|
||||
|
||||
// Output data.
|
||||
virtual void writeData(const void * data, int size)
|
||||
{
|
||||
stream.serialize(const_cast<void *>(data), size);
|
||||
}
|
||||
|
||||
nv::StdOutputStream stream;
|
||||
};
|
||||
|
||||
|
||||
struct OutputOptions::Private
|
||||
{
|
||||
nv::Path fileName;
|
||||
|
||||
mutable OutputHandler * outputHandler;
|
||||
mutable ErrorHandler * errorHandler;
|
||||
mutable bool outputHeader;
|
||||
|
||||
bool openFile() const;
|
||||
void closeFile() const;
|
||||
};
|
||||
|
||||
// @@ temporary hack to copy public attributes to pimpl.
|
||||
void initOptions(OutputOptions * outputOptions);
|
||||
|
||||
|
||||
} // nvtt namespace
|
||||
|
||||
|
||||
#endif // NV_TT_OUTPUTOPTIONS_H
|
@ -38,6 +38,7 @@
|
||||
#include "CompressRGB.h"
|
||||
#include "InputOptions.h"
|
||||
#include "CompressionOptions.h"
|
||||
#include "OutputOptions.h"
|
||||
#include "cuda/CudaUtils.h"
|
||||
#include "cuda/CudaCompressDXT.h"
|
||||
|
||||
@ -96,24 +97,21 @@ namespace
|
||||
// compress
|
||||
//
|
||||
|
||||
static void outputHeader(const InputOptions::Private & inputOptions, const OutputOptions & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
static void outputHeader(const InputOptions::Private & inputOptions, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
{
|
||||
// Output DDS header.
|
||||
if (outputOptions.outputHandler != NULL && outputOptions.outputHeader)
|
||||
{
|
||||
DDSHeader header;
|
||||
|
||||
InputOptions::Private::Image * img = inputOptions.images;
|
||||
nvCheck(img != NULL);
|
||||
header.setWidth(inputOptions.targetWidth);
|
||||
header.setHeight(inputOptions.targetHeight);
|
||||
|
||||
header.setWidth(img->width);
|
||||
header.setHeight(img->height);
|
||||
int mipmapCount = inputOptions.realMipmapCount();
|
||||
nvDebugCheck(mipmapCount > 0);
|
||||
|
||||
header.setMipmapCount(mipmapCount - 1);
|
||||
|
||||
int mipmapCount = inputOptions.mipmapCount;
|
||||
if (!inputOptions.generateMipmaps) mipmapCount = 0;
|
||||
else if (inputOptions.maxLevel != -1 && inputOptions.maxLevel < mipmapCount) mipmapCount = inputOptions.maxLevel;
|
||||
header.setMipmapCount(mipmapCount);
|
||||
|
||||
if (inputOptions.textureType == TextureType_2D) {
|
||||
header.setTexture2D();
|
||||
}
|
||||
@ -122,17 +120,17 @@ static void outputHeader(const InputOptions::Private & inputOptions, const Outpu
|
||||
}
|
||||
/*else if (inputOptions.textureType == TextureType_3D) {
|
||||
header.setTexture3D();
|
||||
header.setDepth(img->depth);
|
||||
header.setDepth(inputOptions.targetDepth);
|
||||
}*/
|
||||
|
||||
if (compressionOptions.format == Format_RGBA)
|
||||
{
|
||||
header.setPitch(4 * img->width);
|
||||
header.setPitch(4 * inputOptions.targetWidth);
|
||||
header.setPixelFormat(compressionOptions.bitcount, compressionOptions.rmask, compressionOptions.gmask, compressionOptions.bmask, compressionOptions.amask);
|
||||
}
|
||||
else
|
||||
{
|
||||
header.setLinearSize(computeImageSize(img->width, img->height, compressionOptions.bitcount, compressionOptions.format));
|
||||
header.setLinearSize(computeImageSize(inputOptions.targetWidth, inputOptions.targetHeight, compressionOptions.bitcount, compressionOptions.format));
|
||||
|
||||
if (compressionOptions.format == Format_DXT1 || compressionOptions.format == Format_DXT1a) {
|
||||
header.setFourCC('D', 'X', 'T', '1');
|
||||
@ -145,14 +143,14 @@ static void outputHeader(const InputOptions::Private & inputOptions, const Outpu
|
||||
}
|
||||
else if (compressionOptions.format == Format_DXT5n) {
|
||||
header.setFourCC('D', 'X', 'T', '5');
|
||||
header.setNormalFlag(true);
|
||||
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');
|
||||
header.setNormalFlag(true);
|
||||
if (inputOptions.isNormalMap) header.setNormalFlag(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,7 +173,7 @@ static void outputHeader(const InputOptions::Private & inputOptions, const Outpu
|
||||
}
|
||||
|
||||
|
||||
static bool compressMipmap(const Image * image, const OutputOptions & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
static bool compressMipmap(const Image * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
{
|
||||
nvDebugCheck(image != NULL);
|
||||
|
||||
@ -196,7 +194,6 @@ static bool compressMipmap(const Image * image, const OutputOptions & outputOpti
|
||||
#if defined(HAVE_ATITC)
|
||||
if (compressionOptions.externalCompressor == "ati")
|
||||
{
|
||||
printf("ATI\n");
|
||||
atiCompressDXT1(image, outputOptions);
|
||||
}
|
||||
else
|
||||
@ -289,7 +286,7 @@ static FloatImage * toFloatImage(const Image * image, const InputOptions::Privat
|
||||
|
||||
FloatImage * floatImage = new FloatImage(image);
|
||||
|
||||
if (inputOptions.normalMap)
|
||||
if (inputOptions.isNormalMap)
|
||||
{
|
||||
// Expand normals. to [-1, 1] range.
|
||||
// floatImage->expandNormals(0);
|
||||
@ -309,7 +306,14 @@ static Image * toFixedImage(const FloatImage * floatImage, const InputOptions::P
|
||||
{
|
||||
nvDebugCheck(floatImage != NULL);
|
||||
|
||||
return floatImage->createImageGammaCorrect(inputOptions.outputGamma);
|
||||
if (inputOptions.isNormalMap || inputOptions.outputGamma == 1.0f)
|
||||
{
|
||||
return floatImage->createImage();
|
||||
}
|
||||
else
|
||||
{
|
||||
return floatImage->createImageGammaCorrect(inputOptions.outputGamma);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -331,13 +335,13 @@ static FloatImage * createMipmap(const FloatImage * floatImage, const InputOptio
|
||||
else /*if (inputOptions.mipmapFilter == MipmapFilter_Kaiser)*/
|
||||
{
|
||||
nvDebugCheck(inputOptions.mipmapFilter == MipmapFilter_Kaiser);
|
||||
KaiserFilter filter(float(inputOptions.kaiserWidth));
|
||||
KaiserFilter filter(inputOptions.kaiserWidth);
|
||||
filter.setParameters(inputOptions.kaiserAlpha, inputOptions.kaiserStretch);
|
||||
result = floatImage->downSample(filter, (FloatImage::WrapMode)inputOptions.wrapMode);
|
||||
}
|
||||
|
||||
// Normalize mipmap.
|
||||
if (inputOptions.normalizeMipmaps)
|
||||
if ((inputOptions.isNormalMap || inputOptions.convertToNormalMap) && inputOptions.normalizeMipmaps)
|
||||
{
|
||||
normalizeNormalMap(result);
|
||||
}
|
||||
@ -383,50 +387,297 @@ static void quantize(Image * img, const InputOptions::Private & inputOptions, Fo
|
||||
}
|
||||
}
|
||||
|
||||
// Process the input, convert to normal map, normalize or convert to linear space.
|
||||
static FloatImage * processInput(const InputOptions::Private & inputOptions, int idx)
|
||||
{
|
||||
const InputOptions::Private::Image & mipmap = inputOptions.images[idx];
|
||||
|
||||
if (inputOptions.convertToNormalMap)
|
||||
{
|
||||
// Scale height factor by 1 / 2 ^ m // @@ Compute scale factor exactly...
|
||||
Vector4 heightScale = inputOptions.heightFactors / float(1 << idx);
|
||||
return createNormalMap(mipmap.data.ptr(), (FloatImage::WrapMode)inputOptions.wrapMode, heightScale, inputOptions.bumpFrequencyScale);
|
||||
}
|
||||
else if (inputOptions.isNormalMap)
|
||||
{
|
||||
if (inputOptions.normalizeMipmaps)
|
||||
{
|
||||
FloatImage * img = new FloatImage(mipmap.data.ptr());
|
||||
img->normalize(0);
|
||||
return img;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inputOptions.inputGamma != inputOptions.outputGamma)
|
||||
{
|
||||
FloatImage * img = new FloatImage(mipmap.data.ptr());
|
||||
img->toLinear(0, 3, inputOptions.inputGamma);
|
||||
return img;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Compress the input texture with the given compression options.
|
||||
bool nvtt::compress(const InputOptions & inputOptions, const OutputOptions & outputOptions, const CompressionOptions & compressionOptions)
|
||||
|
||||
|
||||
|
||||
struct ImagePair
|
||||
{
|
||||
ImagePair() : m_floatImage(NULL), m_fixedImage(NULL), m_deleteFixedImage(false) {}
|
||||
~ImagePair()
|
||||
{
|
||||
if (m_deleteFixedImage) {
|
||||
delete m_fixedImage;
|
||||
}
|
||||
}
|
||||
|
||||
void setFloatImage(FloatImage * image)
|
||||
{
|
||||
m_floatImage = image;
|
||||
if (m_deleteFixedImage) delete m_fixedImage;
|
||||
m_fixedImage = NULL;
|
||||
}
|
||||
|
||||
void setFixedImage(Image * image, bool deleteImage)
|
||||
{
|
||||
m_floatImage = NULL;
|
||||
if (m_deleteFixedImage) delete m_fixedImage;
|
||||
m_fixedImage = image;
|
||||
m_deleteFixedImage = deleteImage;
|
||||
}
|
||||
|
||||
FloatImage * floatImage() const { return m_floatImage.ptr(); }
|
||||
Image * fixedImage() const { return m_fixedImage; }
|
||||
|
||||
void toFixed(const InputOptions::Private & inputOptions)
|
||||
{
|
||||
if (m_floatImage != NULL)
|
||||
{
|
||||
// Convert to fixed.
|
||||
m_fixedImage = toFixedImage(m_floatImage.ptr(), inputOptions);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
AutoPtr<FloatImage> m_floatImage;
|
||||
Image * m_fixedImage;
|
||||
bool m_deleteFixedImage;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// Find the first mipmap provided that is greater or equal to the target image size.
|
||||
static int findMipmap(const InputOptions::Private & inputOptions, uint f, int firstMipmap, uint w, uint h, uint d)
|
||||
{
|
||||
int bestIdx = -1;
|
||||
|
||||
for (int m = firstMipmap; m < inputOptions.mipmapCount; m++)
|
||||
{
|
||||
int idx = f * inputOptions.mipmapCount + m;
|
||||
const InputOptions::Private::Image & mipmap = inputOptions.images[idx];
|
||||
|
||||
if (mipmap.width >= w && mipmap.height >= h && mipmap.depth >= d)
|
||||
{
|
||||
if (mipmap.data != NULL)
|
||||
{
|
||||
bestIdx = idx;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do not look further down.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return bestIdx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int findImage(const InputOptions::Private & inputOptions, uint f, uint w, uint h, uint d, int inputImageIdx, ImagePair * pair)
|
||||
{
|
||||
nvDebugCheck(w > 0 && h > 0);
|
||||
nvDebugCheck(inputImageIdx >= 0 && inputImageIdx < inputOptions.mipmapCount);
|
||||
nvDebugCheck(pair != NULL);
|
||||
|
||||
int bestIdx = findMipmap(inputOptions, f, inputImageIdx, w, h, d);
|
||||
const InputOptions::Private::Image & mipmap = inputOptions.images[bestIdx];
|
||||
|
||||
if (mipmap.width == w && mipmap.height == h && mipmap.depth == d)
|
||||
{
|
||||
// Generate from input image.
|
||||
AutoPtr<FloatImage> processedImage( processInput(inputOptions, bestIdx) );
|
||||
|
||||
if (processedImage != NULL)
|
||||
{
|
||||
pair->setFloatImage(processedImage.release());
|
||||
}
|
||||
else
|
||||
{
|
||||
pair->setFixedImage(mipmap.data.ptr(), false);
|
||||
}
|
||||
|
||||
return bestIdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pair->floatImage() == NULL && pair->fixedImage() == NULL)
|
||||
{
|
||||
// Generate from input image and resize.
|
||||
AutoPtr<FloatImage> processedImage( processInput(inputOptions, bestIdx) );
|
||||
|
||||
if (processedImage == NULL)
|
||||
{
|
||||
processedImage = new FloatImage(mipmap.data.ptr());
|
||||
}
|
||||
|
||||
// Resize image. @@ Add more filters. @@ Distinguish between downscaling and reconstruction filters.
|
||||
BoxFilter boxFilter;
|
||||
pair->setFloatImage(processedImage->downSample(boxFilter, w, h, (FloatImage::WrapMode)inputOptions.wrapMode));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Generate from previous mipmap.
|
||||
if (pair->floatImage() == NULL)
|
||||
{
|
||||
nvDebugCheck(pair->fixedImage() != NULL);
|
||||
pair->setFloatImage(toFloatImage(pair->fixedImage(), inputOptions));
|
||||
}
|
||||
|
||||
// Create mipmap.
|
||||
pair->setFloatImage(createMipmap(pair->floatImage(), inputOptions));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool compressMipmaps(uint f, const InputOptions::Private & inputOptions, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
{
|
||||
uint w = inputOptions.targetWidth;
|
||||
uint h = inputOptions.targetHeight;
|
||||
uint d = inputOptions.targetDepth;
|
||||
|
||||
int inputImageIdx = findMipmap(inputOptions, f, 0, w, h, d);
|
||||
if (inputImageIdx == -1)
|
||||
{
|
||||
// First mipmap missing.
|
||||
if (outputOptions.errorHandler != NULL) outputOptions.errorHandler->error(Error_InvalidInput);
|
||||
return false;
|
||||
}
|
||||
|
||||
ImagePair pair;
|
||||
|
||||
for (uint m = 0; m < inputOptions.mipmapCount; m++)
|
||||
{
|
||||
if (outputOptions.outputHandler)
|
||||
{
|
||||
int size = computeImageSize(w, h, compressionOptions.bitcount, compressionOptions.format);
|
||||
outputOptions.outputHandler->mipmap(size, w, h, d, f, m);
|
||||
}
|
||||
|
||||
inputImageIdx = findImage(inputOptions, f, w, h, d, inputImageIdx, &pair);
|
||||
|
||||
// @@ Where to do the color transform?
|
||||
// - Color transform may not be linear, so we cannot do before computing mipmaps.
|
||||
// - Should be done in linear space, that is, after gamma correction.
|
||||
|
||||
|
||||
pair.toFixed(inputOptions);
|
||||
|
||||
// @@ Quantization should be done in compressMipmap! @@ It should not modify the input image!!!
|
||||
quantize(pair.fixedImage(), inputOptions, compressionOptions.format);
|
||||
|
||||
compressMipmap(pair.fixedImage(), outputOptions, compressionOptions);
|
||||
|
||||
// Compute extents of next mipmap:
|
||||
w = max(1U, w / 2);
|
||||
h = max(1U, h / 2);
|
||||
d = max(1U, d / 2);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static bool compress(const InputOptions::Private & inputOptions, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
|
||||
{
|
||||
// Make sure enums match.
|
||||
nvStaticCheck(FloatImage::WrapMode_Clamp == (FloatImage::WrapMode)WrapMode_Clamp);
|
||||
nvStaticCheck(FloatImage::WrapMode_Mirror == (FloatImage::WrapMode)WrapMode_Mirror);
|
||||
nvStaticCheck(FloatImage::WrapMode_Repeat == (FloatImage::WrapMode)WrapMode_Repeat);
|
||||
|
||||
// Output DDS header.
|
||||
outputHeader(inputOptions.m, outputOptions, compressionOptions.m);
|
||||
|
||||
Format format = compressionOptions.m.format;
|
||||
const uint bitCount = compressionOptions.m.bitcount;
|
||||
|
||||
for (int f = 0; f < inputOptions.m.faceCount; f++)
|
||||
// Get output handler.
|
||||
if (!outputOptions.openFile())
|
||||
{
|
||||
if (outputOptions.errorHandler) outputOptions.errorHandler->error(Error_FileOpen);
|
||||
// @@ Should return here?
|
||||
}
|
||||
|
||||
inputOptions.computeTargetExtents();
|
||||
|
||||
uint mipmapCount = inputOptions.realMipmapCount();
|
||||
nvDebugCheck(mipmapCount > 0);
|
||||
|
||||
// Output DDS header.
|
||||
outputHeader(inputOptions, outputOptions, compressionOptions);
|
||||
|
||||
for (uint f = 0; f < inputOptions.faceCount; f++)
|
||||
{
|
||||
if (!compressMipmaps(f, inputOptions, outputOptions, compressionOptions))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Image * lastImage = NULL;
|
||||
AutoPtr<FloatImage> floatImage(NULL);
|
||||
|
||||
for (int m = 0; m < inputOptions.m.mipmapCount; m++)
|
||||
uint w = inputOptions.targetWidth;
|
||||
uint h = inputOptions.targetHeight;
|
||||
uint d = inputOptions.targetDepth;
|
||||
|
||||
for (uint m = 0; m < mipmapCount; m++)
|
||||
{
|
||||
int idx = f * inputOptions.m.mipmapCount + m;
|
||||
InputOptions::Private::Image & mipmap = inputOptions.m.images[idx];
|
||||
|
||||
if (outputOptions.outputHandler)
|
||||
{
|
||||
int size = computeImageSize(mipmap.width, mipmap.height, bitCount, format);
|
||||
outputOptions.outputHandler->mipmap(size, mipmap.width, mipmap.height, mipmap.depth, mipmap.face, mipmap.mipLevel);
|
||||
int size = computeImageSize(w, h, bitCount, format);
|
||||
outputOptions.outputHandler->mipmap(size, w, h, d, f, m);
|
||||
}
|
||||
|
||||
Image * img; // Image to compress.
|
||||
// @@ Write a more sofisticated get input image, that:
|
||||
// - looks for the nearest image in the input mipmap chain, resizes it to desired extents.
|
||||
// - uses previous floating point image, if available.
|
||||
// - uses previous byte image if available.
|
||||
|
||||
|
||||
int idx = f * inputOptions.mipmapCount + m;
|
||||
InputOptions::Private::Image & mipmap = inputOptions.images[idx];
|
||||
|
||||
// @@ Prescale not implemented yet.
|
||||
nvCheck(w == mipmap.width);
|
||||
nvCheck(h == mipmap.height);
|
||||
nvCheck(d == mipmap.depth);
|
||||
|
||||
Image * img = NULL; // Image to compress.
|
||||
|
||||
if (mipmap.data != NULL) // Mipmap provided.
|
||||
{
|
||||
// Convert to normal map.
|
||||
if (inputOptions.m.convertToNormalMap)
|
||||
if (inputOptions.convertToNormalMap)
|
||||
{
|
||||
floatImage = createNormalMap(mipmap.data.ptr(), (FloatImage::WrapMode)inputOptions.m.wrapMode, inputOptions.m.heightFactors, inputOptions.m.bumpFrequencyScale);
|
||||
// Scale height factor by 1 / 2 ^ m
|
||||
Vector4 heightScale = inputOptions.heightFactors / float(1 << m);
|
||||
floatImage = createNormalMap(mipmap.data.ptr(), (FloatImage::WrapMode)inputOptions.wrapMode, heightScale, inputOptions.bumpFrequencyScale);
|
||||
}
|
||||
/*else if (inputOptions.m.convertToConeMap)
|
||||
{
|
||||
floatImage = createConeMap(mipmap.data, inputOptions.m.heightFactors);
|
||||
}*/
|
||||
else
|
||||
{
|
||||
lastImage = img = mipmap.data.ptr();
|
||||
@ -446,70 +697,88 @@ bool nvtt::compress(const InputOptions & inputOptions, const OutputOptions & out
|
||||
if (floatImage == NULL)
|
||||
{
|
||||
nvDebugCheck(lastImage != NULL);
|
||||
floatImage = toFloatImage(lastImage, inputOptions.m);
|
||||
floatImage = toFloatImage(lastImage, inputOptions);
|
||||
}
|
||||
|
||||
// Create mipmap.
|
||||
floatImage = createMipmap(floatImage.ptr(), inputOptions.m);
|
||||
floatImage = createMipmap(floatImage.ptr(), inputOptions);
|
||||
}
|
||||
|
||||
if (floatImage != NULL)
|
||||
{
|
||||
// Convert to fixed.
|
||||
img = toFixedImage(floatImage.ptr(), inputOptions.m);
|
||||
img = toFixedImage(floatImage.ptr(), inputOptions);
|
||||
}
|
||||
|
||||
// @@ Where to do the color transform?
|
||||
// - Color transform may not be linear, so we cannot do before computing mipmaps.
|
||||
// - Should be done in linear space, that is, after gamma correction.
|
||||
|
||||
// @@ Error! gamma correction is not performed when mipmap data provied.
|
||||
// @@ Error! gamma correction is not performed when mipmap data provided. (only if inputGamma != outputGamma)
|
||||
|
||||
// @@ This code is too complicated, too prone to erros, and hard to understand. Must be simplified!
|
||||
|
||||
quantize(img, inputOptions.m, format);
|
||||
|
||||
compressMipmap(img, outputOptions, compressionOptions.m);
|
||||
|
||||
// @@ Quantization should be done in compressMipmap!
|
||||
quantize(img, inputOptions, format);
|
||||
|
||||
compressMipmap(img, outputOptions, compressionOptions);
|
||||
|
||||
if (img != mipmap.data)
|
||||
{
|
||||
delete img;
|
||||
}
|
||||
|
||||
if (!inputOptions.m.generateMipmaps || (inputOptions.m.maxLevel >= 0 && m >= inputOptions.m.maxLevel)) {
|
||||
// continue with next face.
|
||||
break;
|
||||
}
|
||||
// Compute extents of next mipmap:
|
||||
w = max(1U, w / 2);
|
||||
h = max(1U, h / 2);
|
||||
d = max(1U, d / 2);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
outputOptions.closeFile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// Compress the input texture with the given compression options.
|
||||
bool nvtt::compress(const InputOptions & inputOptions, const OutputOptions & outputOptions, const CompressionOptions & compressionOptions)
|
||||
{
|
||||
// @@ Hack this is necessary because of the pimpl transition.
|
||||
initOptions(const_cast<OutputOptions *>(&outputOptions));
|
||||
|
||||
return ::compress(inputOptions.m, outputOptions.m, compressionOptions.m);
|
||||
}
|
||||
|
||||
|
||||
/// Estimate the size of compressing the input with the given options.
|
||||
int nvtt::estimateSize(const InputOptions & inputOptions, const CompressionOptions & compressionOptions)
|
||||
{
|
||||
Format format = compressionOptions.m.format;
|
||||
const Format format = compressionOptions.m.format;
|
||||
const uint bitCount = compressionOptions.m.bitcount;
|
||||
|
||||
inputOptions.m.computeTargetExtents();
|
||||
|
||||
uint mipmapCount = inputOptions.m.realMipmapCount();
|
||||
|
||||
int size = 0;
|
||||
|
||||
for (int f = 0; f < inputOptions.m.faceCount; f++)
|
||||
for (uint f = 0; f < inputOptions.m.faceCount; f++)
|
||||
{
|
||||
for (int m = 0; m < inputOptions.m.mipmapCount; m++)
|
||||
uint w = inputOptions.m.targetWidth;
|
||||
uint h = inputOptions.m.targetHeight;
|
||||
uint d = inputOptions.m.targetDepth;
|
||||
|
||||
for (uint m = 0; m < mipmapCount; m++)
|
||||
{
|
||||
int idx = f * inputOptions.m.mipmapCount + m;
|
||||
const InputOptions::Private::Image & img = inputOptions.m.images[idx];
|
||||
size += computeImageSize(w, h, bitCount, format);
|
||||
|
||||
size += computeImageSize(img.width, img.height, bitCount, format);
|
||||
|
||||
if (!inputOptions.m.generateMipmaps || (inputOptions.m.maxLevel >= 0 && m >= inputOptions.m.maxLevel)) {
|
||||
// continue with next face.
|
||||
break;
|
||||
}
|
||||
// Compute extents of next mipmap:
|
||||
w = max(1U, w / 2);
|
||||
h = max(1U, h / 2);
|
||||
d = max(1U, d / 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,9 +799,15 @@ const char * nvtt::errorString(Error e)
|
||||
return "Unsupported feature";
|
||||
case Error_CudaError:
|
||||
return "CUDA error";
|
||||
case Error_FileOpen:
|
||||
return "Error opening file";
|
||||
case Error_FileWrite:
|
||||
return "Error writing through output handler";
|
||||
case Error_Unknown:
|
||||
default:
|
||||
//default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
||||
return "Invalid error";
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,9 @@
|
||||
#define NVTT_CLASS
|
||||
#endif
|
||||
|
||||
#define NVTT_DEPRECATED NVTT_API NV_DEPRECATED
|
||||
|
||||
|
||||
// Public interface.
|
||||
namespace nvtt
|
||||
{
|
||||
@ -49,7 +52,7 @@ namespace nvtt
|
||||
// No compression.
|
||||
Format_RGB,
|
||||
Format_RGBA = Format_RGB,
|
||||
|
||||
|
||||
// DX9 formats.
|
||||
Format_DXT1,
|
||||
Format_DXT1a, // DXT1 with binary alpha.
|
||||
@ -65,9 +68,6 @@ namespace nvtt
|
||||
Format_BC3n = Format_DXT5n,
|
||||
Format_BC4, // ATI1
|
||||
Format_BC5, // 3DC, ATI2
|
||||
|
||||
// OpenGL formats.
|
||||
Format_LATC = Format_BC5,
|
||||
};
|
||||
|
||||
/// Quality modes.
|
||||
@ -91,7 +91,9 @@ namespace nvtt
|
||||
NVTT_API void setFormat(Format format);
|
||||
NVTT_API void setQuality(Quality quality, float errorThreshold = 0.5f);
|
||||
NVTT_API void setColorWeights(float red, float green, float blue);
|
||||
NVTT_API void enableHardwareCompression(bool enable);
|
||||
|
||||
NVTT_DEPRECATED void enableHardwareCompression(bool enable);
|
||||
NVTT_API void enableCudaCompression(bool enable);
|
||||
|
||||
NVTT_API void setExternalCompressor(const char * name);
|
||||
|
||||
@ -136,12 +138,28 @@ namespace nvtt
|
||||
MipmapFilter_Kaiser, ///< Kaiser-windowed Sinc filter is the best downsampling filter.
|
||||
};
|
||||
|
||||
/// Color transformation.
|
||||
enum ColorTransform
|
||||
{
|
||||
ColorTransform_None,
|
||||
ColorTransform_Linear,
|
||||
ColorTransform_CoYCg,
|
||||
ColorTransform_CoSCgY,
|
||||
};
|
||||
|
||||
/// Extents rounding mode.
|
||||
enum RoundMode
|
||||
{
|
||||
RoundMode_None,
|
||||
RoundMode_ToNextPowerOfTwo,
|
||||
RoundMode_ToNearestPowerOfTwo,
|
||||
RoundMode_ToPreviousPowerOfTwo,
|
||||
};
|
||||
|
||||
/// Alpha mode.
|
||||
enum AlphaMode
|
||||
{
|
||||
AlphaMode_None,
|
||||
AlphaMode_Transparency,
|
||||
AlphaMode_Premultiplied,
|
||||
};
|
||||
|
||||
/// Input options. Specify format and layout of the input texture.
|
||||
@ -156,37 +174,45 @@ namespace nvtt
|
||||
// Setup input layout.
|
||||
NVTT_API void setTextureLayout(TextureType type, int w, int h, int d = 1);
|
||||
NVTT_API void resetTextureLayout();
|
||||
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
// Describe the format of the input.
|
||||
NVTT_API void setFormat(InputFormat fmt, bool alphaTransparency);
|
||||
|
||||
NVTT_DEPRECATED void setFormat(InputFormat format, bool alphaTransparency);
|
||||
NVTT_API void setFormat(InputFormat format);
|
||||
|
||||
// Set the way the input alpha channel is interpreted.
|
||||
NVTT_API void setAlphaMode(AlphaMode alphaMode);
|
||||
|
||||
// Set gamma settings.
|
||||
NVTT_API void setGamma(float inputGamma, float outputGamma);
|
||||
|
||||
|
||||
// Set texture wrappign mode.
|
||||
NVTT_API void setWrapMode(WrapMode mode);
|
||||
|
||||
|
||||
// Set mipmapping options.
|
||||
NVTT_API void setMipmapping(bool generateMipmaps, MipmapFilter filter = MipmapFilter_Box, int maxLevel = -1);
|
||||
NVTT_API void setKaiserParameters(int width, float alpha, float stretch);
|
||||
NVTT_API void setKaiserParameters(float width, float alpha, float stretch);
|
||||
|
||||
// Set quantization options.
|
||||
NVTT_API void setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold = 127);
|
||||
|
||||
NVTT_DEPRECATED void setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold = 127);
|
||||
|
||||
// Set normal map options.
|
||||
NVTT_API void setNormalMap(bool b);
|
||||
NVTT_API void setConvertToNormalMap(bool convert);
|
||||
NVTT_API void setHeightEvaluation(float redScale, float greenScale, float blueScale, float alphaScale);
|
||||
NVTT_API void setNormalFilter(float small, float medium, float big, float large);
|
||||
NVTT_API void setNormalizeMipmaps(bool b);
|
||||
|
||||
|
||||
// Set color transforms.
|
||||
NVTT_API void setColorTransform(ColorTransform t);
|
||||
NVTT_API void setLinearTransfrom(int channel, float w0, float w1, float w2, float w3);
|
||||
|
||||
|
||||
// Set resizing options.
|
||||
NVTT_API void setMaxExtents(int d);
|
||||
NVTT_API void setRoundMode(RoundMode mode);
|
||||
|
||||
//private:
|
||||
struct Private;
|
||||
Private & m;
|
||||
@ -213,6 +239,8 @@ namespace nvtt
|
||||
Error_UnsupportedFeature,
|
||||
Error_CudaError,
|
||||
Error_Unknown,
|
||||
Error_FileOpen,
|
||||
Error_FileWrite,
|
||||
};
|
||||
|
||||
/// Error handler.
|
||||
@ -229,15 +257,26 @@ namespace nvtt
|
||||
/// the compressor to the user.
|
||||
struct OutputOptions
|
||||
{
|
||||
OutputOptions() : outputHandler(NULL), outputHeader(true) { reset(); }
|
||||
OutputOptions(OutputHandler * oh, ErrorHandler * eh) : outputHandler(oh), errorHandler(eh), outputHeader(true) { reset(); }
|
||||
NVTT_API OutputOptions();
|
||||
NVTT_DEPRECATED OutputOptions(OutputHandler * oh, ErrorHandler * eh);
|
||||
NVTT_API ~OutputOptions();
|
||||
|
||||
// Set default options.
|
||||
NVTT_API void reset();
|
||||
|
||||
OutputHandler * outputHandler;
|
||||
ErrorHandler * errorHandler;
|
||||
bool outputHeader;
|
||||
NVTT_API void setFileName(const char * fileName);
|
||||
|
||||
NVTT_API void setOutputHandler(OutputHandler * outputHandler);
|
||||
NVTT_API void setErrorHandler(ErrorHandler * errorHandler);
|
||||
NVTT_API void setOutputHeader(bool outputHeader);
|
||||
|
||||
NVTT_DEPRECATED OutputHandler * outputHandler;
|
||||
NVTT_DEPRECATED ErrorHandler * errorHandler;
|
||||
NVTT_DEPRECATED bool outputHeader;
|
||||
|
||||
//private:
|
||||
struct Private;
|
||||
Private & m;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user