nvidia-texture-tools/wiki/ApiDocumentation.wiki

267 lines
8.7 KiB
Plaintext
Raw Normal View History

#summary API Documentation
#labels Documentation
== Introduction ==
The NVIDIA Texture Tools library (NVTT for short) is a C++ library that allows you to create textures compressed in any of the DX10 texture formats, and apply certain transformations to them such as mipmap generation, and normal map conversion.
== Usage ==
By default NVTT is compiled as a shared library. To use it in your application you only have to link against it. With gcc that's achieved using `-lnvtt`, and with Visual Studio you have to add `nvtt.lib` to the *TODO: put path to setting here*.
In order to access the API you only have to include the [http://nvidia-texture-tools.googlecode.com/svn/trunk/src/nvtt/nvtt.h nvtt.h] header file:
{{{
#include <nvtt/nvtt.h>
}}}
All the members of the API are in the `nvtt` namespace. Members outside of the `nvtt` namespace should not be considered public and are subject to change. You should not use them if you want your code to always stay compatible with the latest release of NVTT.
As new features are added to NVTT, binary compatibility will always be preserved. That should allow upgrading to new versions without even having to recompile the application code.
The most important function of the API is the following:
{{{
nvtt::compress(const InputOptions &, const OutputOptions &, const CompressionOptions &);
}}}
It takes the texture defined by `InputOptions`, compresses it according to the `CompressionOptions` and outputs it according to the `OutputOptions`. These classes are documented in detail in the following sections.
== Input Options ==
The input options class describe the images that compose the texture to be generated, and several preprocessing operations that could be applied to it.
=== Specifying Input Images ===
Before specifying image data the layout of the texture has to be defined. This is done with the following method:
{{{
void InputOptions::setTextureLayout(TextureType type, int width, int height, int depth=1);
}}}
where texture `type` is one of the following:
{{{
TextureType_2D
TextureType_Cube
}}}
Note that 3D textures are not supported yet. The `depth` argument should always be equal to 1.
Once the layout of the texture has been defined, the data for each of the images can be provided with the following method:
{{{
bool InputOptions::setMipmapData(const void * data, int w, int h, int d, int face, int mipmap);
}}}
NVTT internally allocates a copy of the provided data, that allows you to delete or reuse the memory.
If the width, height or depth of the provided mipmap does not match the one expected by the layout the function returns false, otherwise it returns true.
Again, since 3D textures are not supported, the depth argument should always be set to 1.
*TODO*: explain how the size of the mipmaps are computed, specially for non powers of two.
=== Mipmap Generation ===
downsample the input images...
{{{
inputOptions.setMipmapping(true, MipmapFilter_Box);
}}}
You can specify the number of mipmap levels you want with the third argument. For example, the following example will only generate the first 4 levels of the mipmap chain:
{{{
inputOptions.setMipmapping(true, MipmapFilter_Box, 4);
}}}
Mipmaps are generated using a convolution filter. When evaluating the color of texels that are near the border the convolution filter usually samples outside of the texture. By default, NVTT assumes the texture is mirrored, because that generally looks good, but better results can be achieved by explicitly specifying the wrapping mode. That can be done as follows:
{{{
inputOptions.setWrapMode(WrapMode_Repeat);
}}}
=== Gamma Correction ===
{{{
inputOptions.setGamma(inputGamma, outputGamma);
}}}
=== Generating Normal Maps ===
{{{
inputOptions.convertToNormalMap(true);
}}}
{{{
inputOptions.setHeightEvaluation(float r, float g, float b, float a);
}}}
{{{
inputOptions.setHeightEvaluation(0, 0, 0, 1);
}}}
{{{
inputOptions.setHeightEvaluation(1, 1, 1, 0);
}}}
{{{
inputOptions.setNormalFilter(float small, float medium, float big, float large);
}}}
Are the mipmaps generated from the heightmap or from the normal map?
=== Processing Normal Maps ===
{{{
inputOptions.setNormalMap(true);
}}}
{{{
inputOptions.setNormalizeMipmaps(true);
}}}
Is this the default when normalMap is true? What if convertToNormalMap is true?
=== Quantization ===
Should this be part of compression options instead?
== Compression Options ==
=== Compression Formats ===
* RGB, RGBA
* DXT1, BC1
* DXT1a, BC1a
* DXT3, BC2
* DXT5, BC3
* DXT5n, BC3n
* BC4
* BC5, LATC, RGTC
=== Compression Quality ===
It's possible to control the quality of the compressor using the following method:
{{{
compressionOptions.setQuality(quality);
}}}
Where `quality` is one of the following:
* !Quality_Fastest
* !Quality_Normal
* !Quality_Production
* !Quality_Highest
`Quality_Fastest` will select a quick compressor that produces reasonable results in a very short amount of time. Note that these compressors are not real-time compressors. The code is not highly optimized, but still are generally one order of magnitude faster than the normal compression mode. If you want real-time compression see: [RealTimeDXTCompression].
`Quality_Normal` is the default mode and the one you should use in most cases.
`Quality_Production` will generally produce similar results as `Quality_Normal`, but in some cases it will spend some extra time to try to improve the results further.
`Quality_Highest` is a brute force compressor. In some cases, depending on the size of the search space, this compressor will be extremely slow. Use this only for testing purposes, to determine how much room is left for improvement in the regular compressors.
|| || *Fastest* || *Normal* || *Production* || *Highest* ||
|| BC1 || Yes || Yes || || ||
|| BC1a || Yes || || || ||
|| BC2 || Yes || Yes || || ||
|| BC3 || Yes || Yes || || ||
|| BC3n || Yes || Yes || || ||
|| BC4 || Yes || Yes || Yes || ||
|| BC5 || Yes || Yes || Yes || ||
If `Quality_Production` is not available, `Quality_Normal` will be used instead, and if `Quality_Normal` is not available, `Quality_Fastest` will be used. `Quality_Highest` will never be used as a fallback.
=== GPU Acceleration ===
Not all compressors are GPU accelerated. Some formats can be compressed relatively fast, but others are much more expensive. Currently GPU acceleration is implemented only for the slowest compression modes:
|| || *GPU Accelerated* ||
|| BC1 || Yes ||
|| BC1a || ||
|| BC2 || Yes ||
|| BC3 || Yes ||
|| BC3n || ||
|| BC4 || ||
|| BC5 || ||
High quality texture compression is a complex problem that would be very hard to solve using traditional GPGPU approaches (that is using the graphics API, vertex and fragment shaders). For this reason GPU compression is implemented in CUDA. Note that currently, CUDA is only available on NVIDIA !GeForce 8 series.
When available, CUDA compression is enabled by default, but can be disabled as follows:
{{{
compressionOptions.enableHardwareCompression(false);
}}}
The GPU compressors do not provide exactly the same result as the CPU compressors. However, the difference between the two compressors is always very small and not noticeable to the eye.
=== Pixel Format Conversion ===
{{{
compressionOptions.setFormat(Format_RGB);
compressionOptions.setPixelFormat(bitcount, rmask, gmask, bmask, amask);
}}}
== Output Options ==
{{{
outputOptions.setOutputHandler(OutputHandler *);
outputOptions.setErrorHandler(ErrorHandler *);
}}}
=== Output Handler ===
The output handler is an interface that defines two methods:
{{{
virtual void mipmap(int size, int width, int height, int depth, int face, int miplevel) = 0;
virtual void writeData(const void * data, int size) = 0;
}}}
Applications need to implement this interface in order to receive compressed data from nvtt::compress.
Calls
In order to minimize memory allocations NVTT will call writeData as soon as compressed data is available. Some compressors output one block at a time, while others output many.
=== Producing DDS Files ===
nvtt::compress will call writeData before indicating the image that the data belong to.
{{{
outputOptions.setOutputHeader(false);
}}}
=== Handling Errors ===
=== Reporting Progress ===
Error Handler.
* !Error_InvalidInput
* !Error_UserInterruption
* !Error_UnsupportedFeature
* !Error_CudaError
* !Error_Unknown
{{{
const char * nvtt::errorString(Error e);
}}}
== A simple example ==
...