Cosine power filter. A bit of renaming.
This commit is contained in:
parent
dbdf9b6398
commit
03c3fa42a8
@ -132,18 +132,18 @@ int Compressor::estimateSize(const InputOptions & inputOptions, const Compressio
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TexImage API.
|
// Surface API.
|
||||||
bool Compressor::outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
bool Compressor::outputHeader(const Surface & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||||
{
|
{
|
||||||
return m.outputHeader(tex.type(), tex.width(), tex.height(), tex.depth(), mipmapCount, tex.isNormalMap(), compressionOptions.m, outputOptions.m);
|
return m.outputHeader(tex.type(), tex.width(), tex.height(), tex.depth(), mipmapCount, tex.isNormalMap(), compressionOptions.m, outputOptions.m);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compressor::compress(const TexImage & tex, int face, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
bool Compressor::compress(const Surface & tex, int face, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||||
{
|
{
|
||||||
return m.compress(tex, face, mipmap, compressionOptions.m, outputOptions.m);
|
return m.compress(tex, face, mipmap, compressionOptions.m, outputOptions.m);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Compressor::estimateSize(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions) const
|
int Compressor::estimateSize(const Surface & tex, int mipmapCount, const CompressionOptions & compressionOptions) const
|
||||||
{
|
{
|
||||||
const int w = tex.width();
|
const int w = tex.width();
|
||||||
const int h = tex.height();
|
const int h = tex.height();
|
||||||
@ -152,12 +152,12 @@ int Compressor::estimateSize(const TexImage & tex, int mipmapCount, const Compre
|
|||||||
return estimateSize(w, h, d, mipmapCount, compressionOptions);
|
return estimateSize(w, h, d, mipmapCount, compressionOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compressor::outputHeader(const CubeImage & cube, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
bool Compressor::outputHeader(const CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||||
{
|
{
|
||||||
return m.outputHeader(TextureType_Cube, cube.size(), cube.size(), 1, mipmapCount, false, compressionOptions.m, outputOptions.m);
|
return m.outputHeader(TextureType_Cube, cube.size(), cube.size(), 1, mipmapCount, false, compressionOptions.m, outputOptions.m);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compressor::compress(const CubeImage & cube, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
bool Compressor::compress(const CubeSurface & cube, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
if(!m.compress(cube.face(i), i, mipmap, compressionOptions.m, outputOptions.m)) {
|
if(!m.compress(cube.face(i), i, mipmap, compressionOptions.m, outputOptions.m)) {
|
||||||
@ -167,7 +167,7 @@ bool Compressor::compress(const CubeImage & cube, int mipmap, const CompressionO
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Compressor::estimateSize(const CubeImage & cube, int mipmapCount, const CompressionOptions & compressionOptions) const
|
int Compressor::estimateSize(const CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions) const
|
||||||
{
|
{
|
||||||
return 6 * estimateSize(cube.size(), cube.size(), 1, mipmapCount, compressionOptions);
|
return 6 * estimateSize(cube.size(), cube.size(), 1, mipmapCount, compressionOptions);
|
||||||
}
|
}
|
||||||
@ -223,7 +223,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nvtt::TexImage img;
|
nvtt::Surface img;
|
||||||
img.setWrapMode(inputOptions.wrapMode);
|
img.setWrapMode(inputOptions.wrapMode);
|
||||||
img.setAlphaMode(inputOptions.alphaMode);
|
img.setAlphaMode(inputOptions.alphaMode);
|
||||||
img.setNormalMap(inputOptions.isNormalMap);
|
img.setNormalMap(inputOptions.isNormalMap);
|
||||||
@ -269,7 +269,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
|
|||||||
// Resize input.
|
// Resize input.
|
||||||
img.resize(w, h, d, ResizeFilter_Box);
|
img.resize(w, h, d, ResizeFilter_Box);
|
||||||
|
|
||||||
nvtt::TexImage tmp = img;
|
nvtt::Surface tmp = img;
|
||||||
if (!img.isNormalMap()) {
|
if (!img.isNormalMap()) {
|
||||||
tmp.toGamma(inputOptions.outputGamma);
|
tmp.toGamma(inputOptions.outputGamma);
|
||||||
}
|
}
|
||||||
@ -333,7 +333,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compressor::Private::compress(const TexImage & tex, int face, int mipmap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const
|
bool Compressor::Private::compress(const Surface & tex, int face, int mipmap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const
|
||||||
{
|
{
|
||||||
if (!compress(tex.alphaMode(), tex.width(), tex.height(), tex.depth(), face, mipmap, tex.data(), compressionOptions, outputOptions)) {
|
if (!compress(tex.alphaMode(), tex.width(), tex.height(), tex.depth(), face, mipmap, tex.data(), compressionOptions, outputOptions)) {
|
||||||
return false;
|
return false;
|
||||||
@ -375,7 +375,7 @@ bool Compressor::Private::compress(AlphaMode alphaMode, int w, int h, int d, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Compressor::Private::quantize(TexImage & img, const CompressionOptions::Private & compressionOptions) const
|
void Compressor::Private::quantize(Surface & img, const CompressionOptions::Private & compressionOptions) const
|
||||||
{
|
{
|
||||||
if (compressionOptions.enableColorDithering) {
|
if (compressionOptions.enableColorDithering) {
|
||||||
if (compressionOptions.format >= Format_BC1 && compressionOptions.format <= Format_BC3) {
|
if (compressionOptions.format >= Format_BC1 && compressionOptions.format <= Format_BC3) {
|
||||||
|
@ -46,10 +46,10 @@ namespace nvtt
|
|||||||
Private() {}
|
Private() {}
|
||||||
|
|
||||||
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(const TexImage & tex, int face, int mipmap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
bool compress(const Surface & tex, int face, int mipmap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
||||||
bool compress(AlphaMode alphaMode, int w, int h, int d, int face, int mipmap, const float * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
bool compress(AlphaMode alphaMode, int w, int h, int d, int face, int mipmap, const float * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
||||||
|
|
||||||
void quantize(TexImage & tex, const CompressionOptions::Private & compressionOptions) const;
|
void quantize(Surface & tex, const CompressionOptions::Private & compressionOptions) const;
|
||||||
|
|
||||||
bool outputHeader(nvtt::TextureType textureType, int w, int h, int d, int mipmapCount, bool isNormalMap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
bool outputHeader(nvtt::TextureType textureType, int w, int h, int d, int mipmapCount, bool isNormalMap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
|
||||||
|
|
||||||
|
@ -24,41 +24,46 @@
|
|||||||
#include "CubeImage.h"
|
#include "CubeImage.h"
|
||||||
#include "TexImage.h"
|
#include "TexImage.h"
|
||||||
|
|
||||||
|
#include "nvmath/Vector.h"
|
||||||
|
|
||||||
|
#include "nvcore/Array.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace nv;
|
using namespace nv;
|
||||||
using namespace nvtt;
|
using namespace nvtt;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CubeImage::CubeImage() : m(new CubeImage::Private())
|
CubeSurface::CubeSurface() : m(new CubeSurface::Private())
|
||||||
{
|
{
|
||||||
m->addRef();
|
m->addRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
CubeImage::CubeImage(const CubeImage & cube) : m(cube.m)
|
CubeSurface::CubeSurface(const CubeSurface & cube) : m(cube.m)
|
||||||
{
|
{
|
||||||
if (m != NULL) m->addRef();
|
if (m != NULL) m->addRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
CubeImage::~CubeImage()
|
CubeSurface::~CubeSurface()
|
||||||
{
|
{
|
||||||
if (m != NULL) m->release();
|
if (m != NULL) m->release();
|
||||||
m = NULL;
|
m = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeImage::operator=(const CubeImage & cube)
|
void CubeSurface::operator=(const CubeSurface & cube)
|
||||||
{
|
{
|
||||||
if (cube.m != NULL) cube.m->addRef();
|
if (cube.m != NULL) cube.m->addRef();
|
||||||
if (m != NULL) m->release();
|
if (m != NULL) m->release();
|
||||||
m = cube.m;
|
m = cube.m;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeImage::detach()
|
void CubeSurface::detach()
|
||||||
{
|
{
|
||||||
if (m->refCount() > 1)
|
if (m->refCount() > 1)
|
||||||
{
|
{
|
||||||
m->release();
|
m->release();
|
||||||
m = new CubeImage::Private(*m);
|
m = new CubeSurface::Private(*m);
|
||||||
m->addRef();
|
m->addRef();
|
||||||
nvDebugCheck(m->refCount() == 1);
|
nvDebugCheck(m->refCount() == 1);
|
||||||
}
|
}
|
||||||
@ -66,73 +71,301 @@ void CubeImage::detach()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool CubeImage::isNull() const
|
bool CubeSurface::isNull() const
|
||||||
{
|
{
|
||||||
return m->size == 0;
|
return m->size == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CubeImage::size() const
|
int CubeSurface::size() const
|
||||||
{
|
{
|
||||||
return m->size;
|
return m->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CubeImage::countMipmaps() const
|
int CubeSurface::countMipmaps() const
|
||||||
{
|
{
|
||||||
return nv::countMipmaps(m->size);
|
return nv::countMipmaps(m->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
TexImage & CubeImage::face(int f)
|
Surface & CubeSurface::face(int f)
|
||||||
{
|
{
|
||||||
nvDebugCheck(f >= 0 && f < 6);
|
nvDebugCheck(f >= 0 && f < 6);
|
||||||
return m->face[f];
|
return m->face[f];
|
||||||
}
|
}
|
||||||
|
|
||||||
const TexImage & CubeImage::face(int f) const
|
const Surface & CubeSurface::face(int f) const
|
||||||
{
|
{
|
||||||
nvDebugCheck(f >= 0 && f < 6);
|
nvDebugCheck(f >= 0 && f < 6);
|
||||||
return m->face[f];
|
return m->face[f];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CubeImage::load(const char * fileName)
|
bool CubeSurface::load(const char * fileName)
|
||||||
{
|
{
|
||||||
// @@ TODO
|
// @@ TODO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CubeImage::save(const char * fileName) const
|
bool CubeSurface::save(const char * fileName) const
|
||||||
{
|
{
|
||||||
// @@ TODO
|
// @@ TODO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CubeImage::fold(const TexImage & tex, CubeLayout layout)
|
void CubeSurface::fold(const Surface & tex, CubeLayout layout)
|
||||||
{
|
{
|
||||||
// @@ TODO
|
// @@ TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
TexImage CubeImage::unfold(CubeLayout layout) const
|
Surface CubeSurface::unfold(CubeLayout layout) const
|
||||||
{
|
{
|
||||||
// @@ TODO
|
// @@ TODO
|
||||||
return TexImage();
|
return Surface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CubeImage CubeImage::irradianceFilter(int size) const
|
CubeSurface CubeSurface::irradianceFilter(int size) const
|
||||||
{
|
{
|
||||||
// @@ TODO
|
// @@ TODO
|
||||||
return CubeImage();
|
return CubeSurface();
|
||||||
}
|
|
||||||
|
|
||||||
CubeImage CubeImage::cosinePowerFilter(int size, float cosinePower) const
|
|
||||||
{
|
|
||||||
// @@ TODO
|
|
||||||
return CubeImage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CubeImage::toLinear(float gamma)
|
// Small solid angle table that takes into account cube map symmetry.
|
||||||
|
struct SolidAngleTable {
|
||||||
|
|
||||||
|
SolidAngleTable(int edgeLength) : size(edgeLength/2) {
|
||||||
|
// Allocate table.
|
||||||
|
data.resize(size * size);
|
||||||
|
|
||||||
|
// @@ Init table.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
float lookup(int x, int y) const {
|
||||||
|
if (x >= size) x -= size;
|
||||||
|
else if (x < size) x = size - x - 1;
|
||||||
|
if (y >= size) y -= size;
|
||||||
|
else if (y < size) y = size - y - 1;
|
||||||
|
|
||||||
|
return data[y * size + x];
|
||||||
|
}
|
||||||
|
|
||||||
|
int size;
|
||||||
|
nv::Array<float> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ilen = inverse edge length.
|
||||||
|
Vector3 texelDirection(uint face, uint x, uint y, float ilen)
|
||||||
|
{
|
||||||
|
float u = (float(x) + 0.5f) * (2 * ilen) - 1.0f;
|
||||||
|
float v = (float(y) + 0.5f) * (2 * ilen) - 1.0f;
|
||||||
|
nvDebugCheck(u >= 0.0f && u <= 1.0f);
|
||||||
|
nvDebugCheck(v >= 0.0f && v <= 1.0f);
|
||||||
|
|
||||||
|
Vector3 n;
|
||||||
|
|
||||||
|
if (face == 0) {
|
||||||
|
n.x = 1;
|
||||||
|
n.y = -v;
|
||||||
|
n.z = -u;
|
||||||
|
}
|
||||||
|
if (face == 1) {
|
||||||
|
n.x = -1;
|
||||||
|
n.y = -v;
|
||||||
|
n.z = u;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (face == 2) {
|
||||||
|
n.x = u;
|
||||||
|
n.y = 1;
|
||||||
|
n.z = v;
|
||||||
|
}
|
||||||
|
if (face == 3) {
|
||||||
|
n.x = u;
|
||||||
|
n.y = -1;
|
||||||
|
n.z = -v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (face == 4) {
|
||||||
|
n.x = u;
|
||||||
|
n.y = -v;
|
||||||
|
n.z = 1;
|
||||||
|
}
|
||||||
|
if (face == 5) {
|
||||||
|
n.x = -u;
|
||||||
|
n.y = -v;
|
||||||
|
n.z = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalizeFast(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VectorTable {
|
||||||
|
VectorTable(int edgeLength) : size(edgeLength) {
|
||||||
|
float invEdgeLength = 1.0f / edgeLength;
|
||||||
|
|
||||||
|
for (uint f = 0; f < 6; f++) {
|
||||||
|
for (uint y = 0; y < size; y++) {
|
||||||
|
for (uint x = 0; x < size; x++) {
|
||||||
|
data[(f * size + y) * size + x] = texelDirection(f, x, y, invEdgeLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vector3 & lookup(uint f, uint x, uint y) {
|
||||||
|
nvDebugCheck(f < 6 && x < size && y < size);
|
||||||
|
return data[(f * size + y) * size + x];
|
||||||
|
}
|
||||||
|
|
||||||
|
int size;
|
||||||
|
nv::Array<Vector3> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CubeSurface CubeSurface::cosinePowerFilter(int size, float cosinePower) const
|
||||||
|
{
|
||||||
|
const uint edgeLength = m->size;
|
||||||
|
|
||||||
|
// Allocate output cube.
|
||||||
|
CubeSurface filteredCube;
|
||||||
|
filteredCube.m->allocate(size);
|
||||||
|
|
||||||
|
SolidAngleTable solidAngleTable(edgeLength);
|
||||||
|
VectorTable vectorTable(edgeLength);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// Scatter approach.
|
||||||
|
|
||||||
|
// For each texel of the input cube.
|
||||||
|
// - Lookup our solid angle.
|
||||||
|
// - Determine to what texels of the output cube we contribute.
|
||||||
|
// - Add our contribution to the texels whose power is above threshold.
|
||||||
|
|
||||||
|
for (uint f = 0; f < 6; f++) {
|
||||||
|
const Surface & face = m->face[f];
|
||||||
|
|
||||||
|
for (uint y = 0; y < edgeLength; y++) {
|
||||||
|
for (uint x = 0; x < edgeLength; x++) {
|
||||||
|
float solidAngle = solidAngleTable.lookup(x, y);
|
||||||
|
float r = face.m->image->pixel(0, x, y, 0) * solidAngle;;
|
||||||
|
float g = face.m->image->pixel(1, x, y, 0) * solidAngle;;
|
||||||
|
float b = face.m->image->pixel(2, x, y, 0) * solidAngle;;
|
||||||
|
|
||||||
|
Vector3 texelDir = texelDirection(f, x, y, edgeLength);
|
||||||
|
|
||||||
|
for (uint ff = 0; ff < 6; ff++) {
|
||||||
|
FloatImage * filteredFace = filteredCube.m->face[ff].m->image;
|
||||||
|
|
||||||
|
for (uint yy = 0; yy < size; yy++) {
|
||||||
|
for (uint xx = 0; xx < size; xx++) {
|
||||||
|
|
||||||
|
Vector3 filterDir = texelDirection(ff, xx, yy, size);
|
||||||
|
|
||||||
|
float power = powf(saturate(dot(texelDir, filterDir)), cosinePower);
|
||||||
|
|
||||||
|
if (power > 0.01) {
|
||||||
|
filteredFace->pixel(0, xx, yy, 0) += r * power;
|
||||||
|
filteredFace->pixel(1, xx, yy, 0) += g * power;
|
||||||
|
filteredFace->pixel(2, xx, yy, 0) += b * power;
|
||||||
|
filteredFace->pixel(3, xx, yy, 0) += solidAngle * power;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize contributions.
|
||||||
|
for (uint f = 0; f < 6; f++) {
|
||||||
|
FloatImage * filteredFace = filteredCube.m->face[f].m->image;
|
||||||
|
|
||||||
|
for (int i = 0; i < size*size; i++) {
|
||||||
|
float & r = filteredFace->pixel(0, i);
|
||||||
|
float & g = filteredFace->pixel(1, i);
|
||||||
|
float & b = filteredFace->pixel(2, i);
|
||||||
|
float & sum = filteredFace->pixel(3, i);
|
||||||
|
float isum = 1.0f / sum;
|
||||||
|
r *= isum;
|
||||||
|
g *= isum;
|
||||||
|
b *= isum;
|
||||||
|
sum = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Gather approach. This should be easier to parallelize, because there's no contention in the filtered output.
|
||||||
|
|
||||||
|
// For each texel of the output cube.
|
||||||
|
// - Determine what texels of the input cube contribute to it.
|
||||||
|
// - Add weighted contributions. Normalize.
|
||||||
|
|
||||||
|
// For each texel of the output cube. @@ Parallelize this loop.
|
||||||
|
for (uint f = 0; f < 6; f++) {
|
||||||
|
nvtt::Surface filteredFace = filteredCube.m->face[f];
|
||||||
|
FloatImage * filteredImage = filteredFace.m->image;
|
||||||
|
|
||||||
|
for (uint y = 0; y < size; y++) {
|
||||||
|
for (uint x = 0; x < size; x++) {
|
||||||
|
|
||||||
|
const Vector3 filterDir = texelDirection(f, x, y, size);
|
||||||
|
|
||||||
|
Vector3 color(0);
|
||||||
|
float sum = 0;
|
||||||
|
|
||||||
|
// For each texel of the input cube.
|
||||||
|
for (uint ff = 0; ff < 6; ff++) {
|
||||||
|
const Surface & inputFace = m->face[ff];
|
||||||
|
const FloatImage * inputImage = inputFace.m->image;
|
||||||
|
|
||||||
|
for (uint yy = 0; yy < edgeLength; yy++) {
|
||||||
|
for (uint xx = 0; xx < edgeLength; xx++) {
|
||||||
|
|
||||||
|
// @@ We should probably store solid angle and direction together.
|
||||||
|
Vector3 inputDir = vectorTable.lookup(ff, xx, yy);
|
||||||
|
|
||||||
|
float power = powf(saturate(dot(inputDir, filterDir)), cosinePower);
|
||||||
|
|
||||||
|
if (power > 0.01f) { // @@ Adjustable threshold.
|
||||||
|
float solidAngle = solidAngleTable.lookup(xx, yy);
|
||||||
|
float contribution = solidAngle * power;
|
||||||
|
|
||||||
|
sum += contribution;
|
||||||
|
|
||||||
|
float r = inputImage->pixel(0, xx, yy, 0);
|
||||||
|
float g = inputImage->pixel(1, xx, yy, 0);
|
||||||
|
float b = inputImage->pixel(2, xx, yy, 0);
|
||||||
|
|
||||||
|
color.r += r * contribution;
|
||||||
|
color.g += g * contribution;
|
||||||
|
color.b += b * contribution;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
color *= (1.0f / sum);
|
||||||
|
|
||||||
|
filteredImage->pixel(0, x, y, 0) = color.x;
|
||||||
|
filteredImage->pixel(1, x, y, 0) = color.y;
|
||||||
|
filteredImage->pixel(2, x, y, 0) = color.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return filteredCube;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CubeSurface::toLinear(float gamma)
|
||||||
{
|
{
|
||||||
if (isNull()) return;
|
if (isNull()) return;
|
||||||
|
|
||||||
@ -143,7 +376,7 @@ void CubeImage::toLinear(float gamma)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeImage::toGamma(float gamma)
|
void CubeSurface::toGamma(float gamma)
|
||||||
{
|
{
|
||||||
if (isNull()) return;
|
if (isNull()) return;
|
||||||
|
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
#define NVTT_CUBEIMAGE_H
|
#define NVTT_CUBEIMAGE_H
|
||||||
|
|
||||||
#include "nvtt.h"
|
#include "nvtt.h"
|
||||||
|
#include "TexImage.h"
|
||||||
|
|
||||||
|
#include "nvimage/FloatImage.h"
|
||||||
|
|
||||||
#include "nvcore/RefCounted.h"
|
#include "nvcore/RefCounted.h"
|
||||||
#include "nvcore/Ptr.h"
|
#include "nvcore/Ptr.h"
|
||||||
@ -33,7 +36,7 @@
|
|||||||
namespace nvtt
|
namespace nvtt
|
||||||
{
|
{
|
||||||
|
|
||||||
struct CubeImage::Private : public nv::RefCounted
|
struct CubeSurface::Private : public nv::RefCounted
|
||||||
{
|
{
|
||||||
void operator=(const Private &);
|
void operator=(const Private &);
|
||||||
public:
|
public:
|
||||||
@ -56,8 +59,18 @@ namespace nvtt
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void allocate(int size)
|
||||||
|
{
|
||||||
|
this->size = size;
|
||||||
|
for (uint i = 0; i < 6; i++) {
|
||||||
|
face[i].detach();
|
||||||
|
face[i].m->image = new nv::FloatImage;
|
||||||
|
face[i].m->image->allocate(size, size, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int size;
|
int size;
|
||||||
TexImage face[6];
|
Surface face[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
} // nvtt namespace
|
} // nvtt namespace
|
||||||
|
@ -184,41 +184,41 @@ void nv::getTargetExtent(int & w, int & h, int & d, int maxExtent, RoundMode rou
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
TexImage::TexImage() : m(new TexImage::Private())
|
Surface::Surface() : m(new Surface::Private())
|
||||||
{
|
{
|
||||||
m->addRef();
|
m->addRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
TexImage::TexImage(const TexImage & tex) : m(tex.m)
|
Surface::Surface(const Surface & tex) : m(tex.m)
|
||||||
{
|
{
|
||||||
if (m != NULL) m->addRef();
|
if (m != NULL) m->addRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
TexImage::~TexImage()
|
Surface::~Surface()
|
||||||
{
|
{
|
||||||
if (m != NULL) m->release();
|
if (m != NULL) m->release();
|
||||||
m = NULL;
|
m = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::operator=(const TexImage & tex)
|
void Surface::operator=(const Surface & tex)
|
||||||
{
|
{
|
||||||
if (tex.m != NULL) tex.m->addRef();
|
if (tex.m != NULL) tex.m->addRef();
|
||||||
if (m != NULL) m->release();
|
if (m != NULL) m->release();
|
||||||
m = tex.m;
|
m = tex.m;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::detach()
|
void Surface::detach()
|
||||||
{
|
{
|
||||||
if (m->refCount() > 1)
|
if (m->refCount() > 1)
|
||||||
{
|
{
|
||||||
m->release();
|
m->release();
|
||||||
m = new TexImage::Private(*m);
|
m = new Surface::Private(*m);
|
||||||
m->addRef();
|
m->addRef();
|
||||||
nvDebugCheck(m->refCount() == 1);
|
nvDebugCheck(m->refCount() == 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::setWrapMode(WrapMode wrapMode)
|
void Surface::setWrapMode(WrapMode wrapMode)
|
||||||
{
|
{
|
||||||
if (m->wrapMode != wrapMode)
|
if (m->wrapMode != wrapMode)
|
||||||
{
|
{
|
||||||
@ -227,7 +227,7 @@ void TexImage::setWrapMode(WrapMode wrapMode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::setAlphaMode(AlphaMode alphaMode)
|
void Surface::setAlphaMode(AlphaMode alphaMode)
|
||||||
{
|
{
|
||||||
if (m->alphaMode != alphaMode)
|
if (m->alphaMode != alphaMode)
|
||||||
{
|
{
|
||||||
@ -236,7 +236,7 @@ void TexImage::setAlphaMode(AlphaMode alphaMode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::setNormalMap(bool isNormalMap)
|
void Surface::setNormalMap(bool isNormalMap)
|
||||||
{
|
{
|
||||||
if (m->isNormalMap != isNormalMap)
|
if (m->isNormalMap != isNormalMap)
|
||||||
{
|
{
|
||||||
@ -245,63 +245,63 @@ void TexImage::setNormalMap(bool isNormalMap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::isNull() const
|
bool Surface::isNull() const
|
||||||
{
|
{
|
||||||
return m->image == NULL;
|
return m->image == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TexImage::width() const
|
int Surface::width() const
|
||||||
{
|
{
|
||||||
if (m->image != NULL) return m->image->width();
|
if (m->image != NULL) return m->image->width();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TexImage::height() const
|
int Surface::height() const
|
||||||
{
|
{
|
||||||
if (m->image != NULL) return m->image->height();
|
if (m->image != NULL) return m->image->height();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TexImage::depth() const
|
int Surface::depth() const
|
||||||
{
|
{
|
||||||
if (m->image != NULL) return m->image->depth();
|
if (m->image != NULL) return m->image->depth();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
WrapMode TexImage::wrapMode() const
|
WrapMode Surface::wrapMode() const
|
||||||
{
|
{
|
||||||
return m->wrapMode;
|
return m->wrapMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
AlphaMode TexImage::alphaMode() const
|
AlphaMode Surface::alphaMode() const
|
||||||
{
|
{
|
||||||
return m->alphaMode;
|
return m->alphaMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::isNormalMap() const
|
bool Surface::isNormalMap() const
|
||||||
{
|
{
|
||||||
return m->isNormalMap;
|
return m->isNormalMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureType TexImage::type() const
|
TextureType Surface::type() const
|
||||||
{
|
{
|
||||||
return m->type;
|
return m->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TexImage::countMipmaps() const
|
int Surface::countMipmaps() const
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return 0;
|
if (m->image == NULL) return 0;
|
||||||
return ::countMipmaps(m->image->width(), m->image->height(), 1);
|
return ::countMipmaps(m->image->width(), m->image->height(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
float TexImage::alphaTestCoverage(float alphaRef/*= 0.5*/) const
|
float Surface::alphaTestCoverage(float alphaRef/*= 0.5*/) const
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return 0.0f;
|
if (m->image == NULL) return 0.0f;
|
||||||
|
|
||||||
return m->image->alphaTestCoverage(alphaRef, 3);
|
return m->image->alphaTestCoverage(alphaRef, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
float TexImage::average(int channel, int alpha_channel/*= -1*/, float gamma /*= 2.2f*/) const
|
float Surface::average(int channel, int alpha_channel/*= -1*/, float gamma /*= 2.2f*/) const
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return 0.0f;
|
if (m->image == NULL) return 0.0f;
|
||||||
|
|
||||||
@ -337,12 +337,12 @@ float TexImage::average(int channel, int alpha_channel/*= -1*/, float gamma /*=
|
|||||||
return sum / denom;
|
return sum / denom;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float * TexImage::data() const
|
const float * Surface::data() const
|
||||||
{
|
{
|
||||||
return m->image->channel(0);
|
return m->image->channel(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::histogram(int channel, float rangeMin, float rangeMax, int binCount, int * binPtr) const
|
void Surface::histogram(int channel, float rangeMin, float rangeMax, int binCount, int * binPtr) const
|
||||||
{
|
{
|
||||||
// We assume it's clear in case we want to accumulate multiple histograms.
|
// We assume it's clear in case we want to accumulate multiple histograms.
|
||||||
//memset(bins, 0, sizeof(int)*count);
|
//memset(bins, 0, sizeof(int)*count);
|
||||||
@ -364,7 +364,7 @@ void TexImage::histogram(int channel, float rangeMin, float rangeMax, int binCou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::range(int channel, float * rangeMin, float * rangeMax)
|
void Surface::range(int channel, float * rangeMin, float * rangeMax)
|
||||||
{
|
{
|
||||||
Vector2 range(FLT_MAX, -FLT_MAX);
|
Vector2 range(FLT_MAX, -FLT_MAX);
|
||||||
|
|
||||||
@ -384,7 +384,7 @@ void TexImage::range(int channel, float * rangeMin, float * rangeMax)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool TexImage::load(const char * fileName, bool * hasAlpha/*= NULL*/)
|
bool Surface::load(const char * fileName, bool * hasAlpha/*= NULL*/)
|
||||||
{
|
{
|
||||||
AutoPtr<FloatImage> img(ImageIO::loadFloat(fileName));
|
AutoPtr<FloatImage> img(ImageIO::loadFloat(fileName));
|
||||||
if (img == NULL) {
|
if (img == NULL) {
|
||||||
@ -406,7 +406,7 @@ bool TexImage::load(const char * fileName, bool * hasAlpha/*= NULL*/)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::save(const char * fileName) const
|
bool Surface::save(const char * fileName) const
|
||||||
{
|
{
|
||||||
if (m->image != NULL)
|
if (m->image != NULL)
|
||||||
{
|
{
|
||||||
@ -416,7 +416,7 @@ bool TexImage::save(const char * fileName) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::setImage(nvtt::InputFormat format, int w, int h, int d, const void * data)
|
bool Surface::setImage(nvtt::InputFormat format, int w, int h, int d, const void * data)
|
||||||
{
|
{
|
||||||
detach();
|
detach();
|
||||||
|
|
||||||
@ -488,7 +488,7 @@ bool TexImage::setImage(nvtt::InputFormat format, int w, int h, int d, const voi
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::setImage(InputFormat format, int w, int h, int d, const void * r, const void * g, const void * b, const void * a)
|
bool Surface::setImage(InputFormat format, int w, int h, int d, const void * r, const void * g, const void * b, const void * a)
|
||||||
{
|
{
|
||||||
detach();
|
detach();
|
||||||
|
|
||||||
@ -561,7 +561,7 @@ bool TexImage::setImage(InputFormat format, int w, int h, int d, const void * r,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @@ Add support for compressed 3D textures.
|
// @@ Add support for compressed 3D textures.
|
||||||
bool TexImage::setImage2D(Format format, Decoder decoder, int w, int h, const void * data)
|
bool Surface::setImage2D(Format format, Decoder decoder, int w, int h, const void * data)
|
||||||
{
|
{
|
||||||
if (format != nvtt::Format_BC1 && format != nvtt::Format_BC2 && format != nvtt::Format_BC3 && format != nvtt::Format_BC4 && format != nvtt::Format_BC5)
|
if (format != nvtt::Format_BC1 && format != nvtt::Format_BC2 && format != nvtt::Format_BC3 && format != nvtt::Format_BC4 && format != nvtt::Format_BC5)
|
||||||
{
|
{
|
||||||
@ -693,7 +693,7 @@ static void getDefaultFilterWidthAndParams(int filter, float * filterWidth, floa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::resize(int w, int h, int d, ResizeFilter filter)
|
void Surface::resize(int w, int h, int d, ResizeFilter filter)
|
||||||
{
|
{
|
||||||
float filterWidth;
|
float filterWidth;
|
||||||
float params[2];
|
float params[2];
|
||||||
@ -702,7 +702,7 @@ void TexImage::resize(int w, int h, int d, ResizeFilter filter)
|
|||||||
resize(w, h, d, filter, filterWidth, params);
|
resize(w, h, d, filter, filterWidth, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::resize(int w, int h, int d, ResizeFilter filter, float filterWidth, const float * params)
|
void Surface::resize(int w, int h, int d, ResizeFilter filter, float filterWidth, const float * params)
|
||||||
{
|
{
|
||||||
FloatImage * img = m->image;
|
FloatImage * img = m->image;
|
||||||
if (img == NULL || (w == img->width() && h == img->height() && d == img->depth())) {
|
if (img == NULL || (w == img->width() && h == img->height() && d == img->depth())) {
|
||||||
@ -770,7 +770,7 @@ void TexImage::resize(int w, int h, int d, ResizeFilter filter, float filterWidt
|
|||||||
m->image = img;
|
m->image = img;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
|
void Surface::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
|
||||||
{
|
{
|
||||||
float filterWidth;
|
float filterWidth;
|
||||||
float params[2];
|
float params[2];
|
||||||
@ -779,7 +779,7 @@ void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
|
|||||||
resize(maxExtent, roundMode, filter, filterWidth, params);
|
resize(maxExtent, roundMode, filter, filterWidth, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter, float filterWidth, const float * params)
|
void Surface::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter, float filterWidth, const float * params)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -792,7 +792,7 @@ void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter, f
|
|||||||
resize(w, h, d, filter, filterWidth, params);
|
resize(w, h, d, filter, filterWidth, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::buildNextMipmap(MipmapFilter filter)
|
bool Surface::buildNextMipmap(MipmapFilter filter)
|
||||||
{
|
{
|
||||||
float filterWidth;
|
float filterWidth;
|
||||||
float params[2];
|
float params[2];
|
||||||
@ -801,7 +801,7 @@ bool TexImage::buildNextMipmap(MipmapFilter filter)
|
|||||||
return buildNextMipmap(filter, filterWidth, params);
|
return buildNextMipmap(filter, filterWidth, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::buildNextMipmap(MipmapFilter filter, float filterWidth, const float * params)
|
bool Surface::buildNextMipmap(MipmapFilter filter, float filterWidth, const float * params)
|
||||||
{
|
{
|
||||||
FloatImage * img = m->image;
|
FloatImage * img = m->image;
|
||||||
if (img == NULL || (img->width() == 1 && img->height() == 1 && img->depth() == 1)) {
|
if (img == NULL || (img->width() == 1 && img->height() == 1 && img->depth() == 1)) {
|
||||||
@ -864,7 +864,7 @@ bool TexImage::buildNextMipmap(MipmapFilter filter, float filterWidth, const flo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::canvasSize(int w, int h, int d)
|
void Surface::canvasSize(int w, int h, int d)
|
||||||
{
|
{
|
||||||
nvDebugCheck(w > 0 && h > 0 && d > 0);
|
nvDebugCheck(w > 0 && h > 0 && d > 0);
|
||||||
|
|
||||||
@ -901,7 +901,7 @@ void TexImage::canvasSize(int w, int h, int d)
|
|||||||
|
|
||||||
|
|
||||||
// Color transforms.
|
// Color transforms.
|
||||||
void TexImage::toLinear(float gamma)
|
void Surface::toLinear(float gamma)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
if (equal(gamma, 1.0f)) return;
|
if (equal(gamma, 1.0f)) return;
|
||||||
@ -911,7 +911,7 @@ void TexImage::toLinear(float gamma)
|
|||||||
m->image->toLinear(0, 3, gamma);
|
m->image->toLinear(0, 3, gamma);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::toGamma(float gamma)
|
void Surface::toGamma(float gamma)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
if (equal(gamma, 1.0f)) return;
|
if (equal(gamma, 1.0f)) return;
|
||||||
@ -930,7 +930,7 @@ static float toSrgb(float f) {
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::toSrgb()
|
void Surface::toSrgb()
|
||||||
{
|
{
|
||||||
FloatImage * img = m->image;
|
FloatImage * img = m->image;
|
||||||
if (img == NULL) return;
|
if (img == NULL) return;
|
||||||
@ -960,7 +960,7 @@ static float toXenonSrgb(float f) {
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::toXenonSrgb()
|
void Surface::toXenonSrgb()
|
||||||
{
|
{
|
||||||
FloatImage * img = m->image;
|
FloatImage * img = m->image;
|
||||||
if (img == NULL) return;
|
if (img == NULL) return;
|
||||||
@ -981,7 +981,7 @@ void TexImage::toXenonSrgb()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TexImage::transform(const float w0[4], const float w1[4], const float w2[4], const float w3[4], const float offset[4])
|
void Surface::transform(const float w0[4], const float w1[4], const float w2[4], const float w3[4], const float offset[4])
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -998,7 +998,7 @@ void TexImage::transform(const float w0[4], const float w1[4], const float w2[4]
|
|||||||
m->image->transform(0, xform, voffset);
|
m->image->transform(0, xform, voffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::swizzle(int r, int g, int b, int a)
|
void Surface::swizzle(int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
if (r == 0 && g == 1 && b == 2 && a == 3) return;
|
if (r == 0 && g == 1 && b == 2 && a == 3) return;
|
||||||
@ -1009,7 +1009,7 @@ void TexImage::swizzle(int r, int g, int b, int a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// color * scale + bias
|
// color * scale + bias
|
||||||
void TexImage::scaleBias(int channel, float scale, float bias)
|
void Surface::scaleBias(int channel, float scale, float bias)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
if (equal(scale, 1.0f) && equal(bias, 0.0f)) return;
|
if (equal(scale, 1.0f) && equal(bias, 0.0f)) return;
|
||||||
@ -1019,7 +1019,7 @@ void TexImage::scaleBias(int channel, float scale, float bias)
|
|||||||
m->image->scaleBias(channel, 1, scale, bias);
|
m->image->scaleBias(channel, 1, scale, bias);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::clamp(int channel, float low, float high)
|
void Surface::clamp(int channel, float low, float high)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1028,14 +1028,14 @@ void TexImage::clamp(int channel, float low, float high)
|
|||||||
m->image->clamp(channel, 1, low, high);
|
m->image->clamp(channel, 1, low, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::packNormal()
|
void Surface::packNormal()
|
||||||
{
|
{
|
||||||
scaleBias(0, 0.5f, 0.5f);
|
scaleBias(0, 0.5f, 0.5f);
|
||||||
scaleBias(1, 0.5f, 0.5f);
|
scaleBias(1, 0.5f, 0.5f);
|
||||||
scaleBias(2, 0.5f, 0.5f);
|
scaleBias(2, 0.5f, 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::expandNormal()
|
void Surface::expandNormal()
|
||||||
{
|
{
|
||||||
scaleBias(0, 2.0f, -1.0f);
|
scaleBias(0, 2.0f, -1.0f);
|
||||||
scaleBias(1, 2.0f, -1.0f);
|
scaleBias(1, 2.0f, -1.0f);
|
||||||
@ -1043,7 +1043,7 @@ void TexImage::expandNormal()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TexImage::blend(float red, float green, float blue, float alpha, float t)
|
void Surface::blend(float red, float green, float blue, float alpha, float t)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1065,7 +1065,7 @@ void TexImage::blend(float red, float green, float blue, float alpha, float t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::premultiplyAlpha()
|
void Surface::premultiplyAlpha()
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1087,7 +1087,7 @@ void TexImage::premultiplyAlpha()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TexImage::toGreyScale(float redScale, float greenScale, float blueScale, float alphaScale)
|
void Surface::toGreyScale(float redScale, float greenScale, float blueScale, float alphaScale)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1114,7 +1114,7 @@ void TexImage::toGreyScale(float redScale, float greenScale, float blueScale, fl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw colored border.
|
// Draw colored border.
|
||||||
void TexImage::setBorder(float r, float g, float b, float a)
|
void Surface::setBorder(float r, float g, float b, float a)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1156,7 +1156,7 @@ void TexImage::setBorder(float r, float g, float b, float a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fill image with the given color.
|
// Fill image with the given color.
|
||||||
void TexImage::fill(float red, float green, float blue, float alpha)
|
void Surface::fill(float red, float green, float blue, float alpha)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1179,7 +1179,7 @@ void TexImage::fill(float red, float green, float blue, float alpha)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TexImage::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
|
void Surface::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1188,7 +1188,7 @@ void TexImage::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
|
|||||||
m->image->scaleAlphaToCoverage(coverage, alphaRef, 3);
|
m->image->scaleAlphaToCoverage(coverage, alphaRef, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*bool TexImage::normalizeRange(float * rangeMin, float * rangeMax)
|
/*bool Surface::normalizeRange(float * rangeMin, float * rangeMax)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return false;
|
if (m->image == NULL) return false;
|
||||||
|
|
||||||
@ -1218,7 +1218,7 @@ void TexImage::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
|
|||||||
|
|
||||||
// Ideally you should compress/quantize the RGB and M portions independently.
|
// 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.
|
// Once you have M quantized, you would compute the corresponding RGB and quantize that.
|
||||||
void TexImage::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
|
void Surface::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1286,7 +1286,7 @@ void TexImage::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::fromRGBM(float range/*= 1*/)
|
void Surface::fromRGBM(float range/*= 1*/)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1311,7 +1311,7 @@ void TexImage::fromRGBM(float range/*= 1*/)
|
|||||||
|
|
||||||
|
|
||||||
// Y is in the [0, 1] range, while CoCg are in the [-1, 1] range.
|
// Y is in the [0, 1] range, while CoCg are in the [-1, 1] range.
|
||||||
void TexImage::toYCoCg()
|
void Surface::toYCoCg()
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1348,7 +1348,7 @@ void TexImage::toYCoCg()
|
|||||||
// @@ Add support for threshold.
|
// @@ Add support for threshold.
|
||||||
// We could do something to prevent scale values from adjacent blocks from being too different to each other
|
// We could do something to prevent scale values from adjacent blocks from being too different to each other
|
||||||
// and minimize bilinear interpolation artifacts.
|
// and minimize bilinear interpolation artifacts.
|
||||||
void TexImage::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
|
void Surface::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
|
||||||
{
|
{
|
||||||
if (m->image == NULL || m->image->depth() != 1) return;
|
if (m->image == NULL || m->image->depth() != 1) return;
|
||||||
|
|
||||||
@ -1406,7 +1406,7 @@ void TexImage::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::fromYCoCg()
|
void Surface::fromYCoCg()
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1439,7 +1439,7 @@ void TexImage::fromYCoCg()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::toLUVW(float range/*= 1.0f*/)
|
void Surface::toLUVW(float range/*= 1.0f*/)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1468,13 +1468,13 @@ void TexImage::toLUVW(float range/*= 1.0f*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::fromLUVW(float range/*= 1.0f*/)
|
void Surface::fromLUVW(float range/*= 1.0f*/)
|
||||||
{
|
{
|
||||||
// Decompression is the same as in RGBM.
|
// Decompression is the same as in RGBM.
|
||||||
fromRGBM(range * sqrtf(3));
|
fromRGBM(range * sqrtf(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::abs(int channel)
|
void Surface::abs(int channel)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1489,7 +1489,7 @@ void TexImage::abs(int channel)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::convolve(int channel, int kernelSize, float * kernelData)
|
void Surface::convolve(int channel, int kernelSize, float * kernelData)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1500,7 +1500,7 @@ void TexImage::convolve(int channel, int kernelSize, float * kernelData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void TexImage::blockLuminanceScale(float scale)
|
void Surface::blockLuminanceScale(float scale)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1575,7 +1575,7 @@ void TexImage::blockLuminanceScale(float scale)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void TexImage::toJPEGLS()
|
void Surface::toJPEGLS()
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1598,7 +1598,7 @@ void TexImage::toJPEGLS()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::fromJPEGLS()
|
void Surface::fromJPEGLS()
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1624,7 +1624,7 @@ void TexImage::fromJPEGLS()
|
|||||||
|
|
||||||
|
|
||||||
// If dither is true, this uses Floyd-Steinberg dithering method.
|
// If dither is true, this uses Floyd-Steinberg dithering method.
|
||||||
void TexImage::binarize(int channel, float threshold, bool dither)
|
void Surface::binarize(int channel, float threshold, bool dither)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1687,7 +1687,7 @@ void TexImage::binarize(int channel, float threshold, bool dither)
|
|||||||
// Assumes input is in [0, 1] range. Output is in the [0, 1] range, but rounded to the middle of each bin.
|
// Assumes input is in [0, 1] range. Output is in the [0, 1] range, but rounded to the middle of each bin.
|
||||||
// If exactEndPoints is true, [0, 1] are represented exactly, and the correponding bins are half the size, so quantization is not truly uniform.
|
// If exactEndPoints is true, [0, 1] are represented exactly, and the correponding bins are half the size, so quantization is not truly uniform.
|
||||||
// When dither is true, this uses Floyd-Steinberg dithering.
|
// When dither is true, this uses Floyd-Steinberg dithering.
|
||||||
void TexImage::quantize(int channel, int bits, bool exactEndPoints, bool dither)
|
void Surface::quantize(int channel, int bits, bool exactEndPoints, bool dither)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1758,7 +1758,7 @@ void TexImage::quantize(int channel, int bits, bool exactEndPoints, bool dither)
|
|||||||
|
|
||||||
|
|
||||||
// Set normal map options.
|
// Set normal map options.
|
||||||
void TexImage::toNormalMap(float sm, float medium, float big, float large)
|
void Surface::toNormalMap(float sm, float medium, float big, float large)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1777,7 +1777,7 @@ void TexImage::toNormalMap(float sm, float medium, float big, float large)
|
|||||||
m->isNormalMap = true;
|
m->isNormalMap = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::normalizeNormalMap()
|
void Surface::normalizeNormalMap()
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
if (!m->isNormalMap) return;
|
if (!m->isNormalMap) return;
|
||||||
@ -1787,7 +1787,7 @@ void TexImage::normalizeNormalMap()
|
|||||||
nv::normalizeNormalMap(m->image);
|
nv::normalizeNormalMap(m->image);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::transformNormals(NormalTransform xform)
|
void Surface::transformNormals(NormalTransform xform)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1860,7 +1860,7 @@ void TexImage::transformNormals(NormalTransform xform)
|
|||||||
img->packNormals(0);
|
img->packNormals(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::reconstructNormals(NormalTransform xform)
|
void Surface::reconstructNormals(NormalTransform xform)
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1909,7 +1909,7 @@ void TexImage::reconstructNormals(NormalTransform xform)
|
|||||||
img->packNormals(0);
|
img->packNormals(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::toCleanNormalMap()
|
void Surface::toCleanNormalMap()
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1929,21 +1929,21 @@ void TexImage::toCleanNormalMap()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// [-1,1] -> [ 0,1]
|
// [-1,1] -> [ 0,1]
|
||||||
void TexImage::packNormals() {
|
void Surface::packNormals() {
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
detach();
|
detach();
|
||||||
m->image->packNormals(0);
|
m->image->packNormals(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// [ 0,1] -> [-1,1]
|
// [ 0,1] -> [-1,1]
|
||||||
void TexImage::expandNormals() {
|
void Surface::expandNormals() {
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
detach();
|
detach();
|
||||||
m->image->expandNormals(0);
|
m->image->expandNormals(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TexImage::flipX()
|
void Surface::flipX()
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1952,7 +1952,7 @@ void TexImage::flipX()
|
|||||||
m->image->flipX();
|
m->image->flipX();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::flipY()
|
void Surface::flipY()
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1961,7 +1961,7 @@ void TexImage::flipY()
|
|||||||
m->image->flipY();
|
m->image->flipY();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexImage::flipZ()
|
void Surface::flipZ()
|
||||||
{
|
{
|
||||||
if (m->image == NULL) return;
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
@ -1970,12 +1970,12 @@ void TexImage::flipZ()
|
|||||||
m->image->flipZ();
|
m->image->flipZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::copyChannel(const TexImage & srcImage, int srcChannel)
|
bool Surface::copyChannel(const Surface & srcImage, int srcChannel)
|
||||||
{
|
{
|
||||||
return copyChannel(srcImage, srcChannel, srcChannel);
|
return copyChannel(srcImage, srcChannel, srcChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel)
|
bool Surface::copyChannel(const Surface & srcImage, int srcChannel, int dstChannel)
|
||||||
{
|
{
|
||||||
if (srcChannel < 0 || srcChannel > 3 || dstChannel < 0 || dstChannel > 3) return false;
|
if (srcChannel < 0 || srcChannel > 3 || dstChannel < 0 || dstChannel > 3) return false;
|
||||||
|
|
||||||
@ -1994,7 +1994,7 @@ bool TexImage::copyChannel(const TexImage & srcImage, int srcChannel, int dstCha
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TexImage::addChannel(const TexImage & srcImage, int srcChannel, int dstChannel, float scale)
|
bool Surface::addChannel(const Surface & srcImage, int srcChannel, int dstChannel, float scale)
|
||||||
{
|
{
|
||||||
if (srcChannel < 0 || srcChannel > 3 || dstChannel < 0 || dstChannel > 3) return false;
|
if (srcChannel < 0 || srcChannel > 3 || dstChannel < 0 || dstChannel > 3) return false;
|
||||||
|
|
||||||
@ -2024,43 +2024,43 @@ bool TexImage::addChannel(const TexImage & srcImage, int srcChannel, int dstChan
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
float nvtt::rmsError(const TexImage & reference, const TexImage & image)
|
float nvtt::rmsError(const Surface & reference, const Surface & image)
|
||||||
{
|
{
|
||||||
return nv::rmsColorError(reference.m->image, image.m->image, reference.alphaMode() == nvtt::AlphaMode_Transparency);
|
return nv::rmsColorError(reference.m->image, image.m->image, reference.alphaMode() == nvtt::AlphaMode_Transparency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float nvtt::rmsAlphaError(const TexImage & reference, const TexImage & image)
|
float nvtt::rmsAlphaError(const Surface & reference, const Surface & image)
|
||||||
{
|
{
|
||||||
return nv::rmsAlphaError(reference.m->image, image.m->image);
|
return nv::rmsAlphaError(reference.m->image, image.m->image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float nvtt::cieLabError(const TexImage & reference, const TexImage & image)
|
float nvtt::cieLabError(const Surface & reference, const Surface & image)
|
||||||
{
|
{
|
||||||
return nv::cieLabError(reference.m->image, image.m->image);
|
return nv::cieLabError(reference.m->image, image.m->image);
|
||||||
}
|
}
|
||||||
|
|
||||||
float nvtt::angularError(const TexImage & reference, const TexImage & image)
|
float nvtt::angularError(const Surface & reference, const Surface & image)
|
||||||
{
|
{
|
||||||
//return nv::averageAngularError(reference.m->image, image.m->image);
|
//return nv::averageAngularError(reference.m->image, image.m->image);
|
||||||
return nv::rmsAngularError(reference.m->image, image.m->image);
|
return nv::rmsAngularError(reference.m->image, image.m->image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TexImage nvtt::diff(const TexImage & reference, const TexImage & image, float scale)
|
Surface nvtt::diff(const Surface & reference, const Surface & image, float scale)
|
||||||
{
|
{
|
||||||
const FloatImage * ref = reference.m->image;
|
const FloatImage * ref = reference.m->image;
|
||||||
const FloatImage * img = image.m->image;
|
const FloatImage * img = image.m->image;
|
||||||
|
|
||||||
if (!sameLayout(img, ref)) {
|
if (!sameLayout(img, ref)) {
|
||||||
return TexImage();
|
return Surface();
|
||||||
}
|
}
|
||||||
|
|
||||||
nvDebugCheck(img->componentCount() == 4);
|
nvDebugCheck(img->componentCount() == 4);
|
||||||
nvDebugCheck(ref->componentCount() == 4);
|
nvDebugCheck(ref->componentCount() == 4);
|
||||||
|
|
||||||
nvtt::TexImage diffImage;
|
nvtt::Surface diffImage;
|
||||||
FloatImage * diff = diffImage.m->image = new FloatImage;
|
FloatImage * diff = diffImage.m->image = new FloatImage;
|
||||||
diff->allocate(4, img->width(), img->height(), img->depth());
|
diff->allocate(4, img->width(), img->height(), img->depth());
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
namespace nvtt
|
namespace nvtt
|
||||||
{
|
{
|
||||||
|
|
||||||
struct TexImage::Private : public nv::RefCounted
|
struct Surface::Private : public nv::RefCounted
|
||||||
{
|
{
|
||||||
void operator=(const Private &);
|
void operator=(const Private &);
|
||||||
public:
|
public:
|
||||||
|
@ -67,8 +67,8 @@
|
|||||||
namespace nvtt
|
namespace nvtt
|
||||||
{
|
{
|
||||||
// Forward declarations.
|
// Forward declarations.
|
||||||
struct TexImage;
|
struct Surface;
|
||||||
struct CubeImage;
|
struct CubeSurface;
|
||||||
|
|
||||||
/// Supported compression formats.
|
/// Supported compression formats.
|
||||||
enum Format
|
enum Format
|
||||||
@ -378,15 +378,15 @@ namespace nvtt
|
|||||||
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;
|
||||||
|
|
||||||
// TexImage API.
|
// Surface API.
|
||||||
NVTT_API bool outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
NVTT_API bool outputHeader(const Surface & img, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||||
NVTT_API bool compress(const TexImage & tex, int face, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
NVTT_API bool compress(const Surface & img, int face, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||||
NVTT_API int estimateSize(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
NVTT_API int estimateSize(const Surface & img, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
||||||
|
|
||||||
// CubeImage API.
|
// CubeSurface API.
|
||||||
NVTT_API bool outputHeader(const CubeImage & cube, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
NVTT_API bool outputHeader(const CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||||
NVTT_API bool compress(const CubeImage & cube, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
NVTT_API bool compress(const CubeSurface & cube, int mipmap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||||
NVTT_API int estimateSize(const CubeImage & cube, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
NVTT_API int estimateSize(const CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
||||||
|
|
||||||
// Raw API.
|
// Raw API.
|
||||||
NVTT_API bool outputHeader(TextureType type, int w, int h, int d, int mipmapCount, bool isNormalMap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
NVTT_API bool outputHeader(TextureType type, int w, int h, int d, int mipmapCount, bool isNormalMap, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
|
||||||
@ -405,14 +405,15 @@ namespace nvtt
|
|||||||
//NormalTransform_DualParaboloid,
|
//NormalTransform_DualParaboloid,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A texture mipmap.
|
|
||||||
struct TexImage
|
|
||||||
{
|
|
||||||
NVTT_API TexImage();
|
|
||||||
NVTT_API TexImage(const TexImage & tex);
|
|
||||||
NVTT_API ~TexImage();
|
|
||||||
|
|
||||||
NVTT_API void operator=(const TexImage & tex);
|
/// A surface is a texture mipmap. Can be 2D or 3D.
|
||||||
|
struct Surface
|
||||||
|
{
|
||||||
|
NVTT_API Surface();
|
||||||
|
NVTT_API Surface(const Surface & img);
|
||||||
|
NVTT_API ~Surface();
|
||||||
|
|
||||||
|
NVTT_API void operator=(const Surface & img);
|
||||||
|
|
||||||
// Texture parameters.
|
// Texture parameters.
|
||||||
NVTT_API void setWrapMode(WrapMode mode);
|
NVTT_API void setWrapMode(WrapMode mode);
|
||||||
@ -500,19 +501,12 @@ namespace nvtt
|
|||||||
NVTT_API void flipZ();
|
NVTT_API void flipZ();
|
||||||
|
|
||||||
// Copy image data.
|
// Copy image data.
|
||||||
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel);
|
NVTT_API bool copyChannel(const Surface & srcImage, int srcChannel);
|
||||||
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel);
|
NVTT_API bool copyChannel(const Surface & srcImage, int srcChannel, int dstChannel);
|
||||||
|
|
||||||
NVTT_API bool addChannel(const TexImage & img, int srcChannel, int dstChannel, float scale);
|
NVTT_API bool addChannel(const Surface & img, int srcChannel, int dstChannel, float scale);
|
||||||
|
|
||||||
// Error compare.
|
//private:
|
||||||
NVTT_API friend float rmsError(const TexImage & reference, const TexImage & img);
|
|
||||||
NVTT_API friend float rmsAlphaError(const TexImage & reference, const TexImage & img);
|
|
||||||
NVTT_API friend float cieLabError(const TexImage & reference, const TexImage & img);
|
|
||||||
NVTT_API friend float angularError(const TexImage & reference, const TexImage & img);
|
|
||||||
NVTT_API friend TexImage diff(const TexImage & reference, const TexImage & img, float scale);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void detach();
|
void detach();
|
||||||
|
|
||||||
struct Private;
|
struct Private;
|
||||||
@ -528,14 +522,14 @@ namespace nvtt
|
|||||||
CubeLayout_LatitudeLongitude,
|
CubeLayout_LatitudeLongitude,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A cubemap mipmap.
|
/// A cubemap mipmap. CubeSurface?
|
||||||
struct CubeImage
|
struct CubeSurface
|
||||||
{
|
{
|
||||||
NVTT_API CubeImage();
|
NVTT_API CubeSurface();
|
||||||
NVTT_API CubeImage(const CubeImage & tex);
|
NVTT_API CubeSurface(const CubeSurface & img);
|
||||||
NVTT_API ~CubeImage();
|
NVTT_API ~CubeSurface();
|
||||||
|
|
||||||
NVTT_API void operator=(const CubeImage & tex);
|
NVTT_API void operator=(const CubeSurface & img);
|
||||||
|
|
||||||
// Queries.
|
// Queries.
|
||||||
NVTT_API bool isNull() const;
|
NVTT_API bool isNull() const;
|
||||||
@ -546,20 +540,20 @@ namespace nvtt
|
|||||||
NVTT_API bool load(const char * fileName);
|
NVTT_API bool load(const char * fileName);
|
||||||
NVTT_API bool save(const char * fileName) const;
|
NVTT_API bool save(const char * fileName) const;
|
||||||
|
|
||||||
TexImage & face(int face);
|
Surface & face(int face);
|
||||||
const TexImage & face(int face) const;
|
const Surface & face(int face) const;
|
||||||
|
|
||||||
// Layout conversion.
|
// Layout conversion.
|
||||||
void fold(const TexImage & img, CubeLayout layout);
|
void fold(const Surface & img, CubeLayout layout);
|
||||||
TexImage unfold(CubeLayout layout) const;
|
Surface unfold(CubeLayout layout) const;
|
||||||
|
|
||||||
// @@ Angular extent filtering.
|
// @@ Angular extent filtering.
|
||||||
|
|
||||||
// @@ Add resizing methods.
|
// @@ Add resizing methods.
|
||||||
|
|
||||||
// Filtering.
|
// Filtering.
|
||||||
CubeImage irradianceFilter(int size) const;
|
CubeSurface irradianceFilter(int size) const;
|
||||||
CubeImage cosinePowerFilter(int size, float cosinePower) const;
|
CubeSurface cosinePowerFilter(int size, float cosinePower) const;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -575,7 +569,7 @@ namespace nvtt
|
|||||||
NVTT_API void toLinear(float gamma);
|
NVTT_API void toLinear(float gamma);
|
||||||
NVTT_API void toGamma(float gamma);
|
NVTT_API void toGamma(float gamma);
|
||||||
|
|
||||||
private:
|
//private:
|
||||||
void detach();
|
void detach();
|
||||||
|
|
||||||
struct Private;
|
struct Private;
|
||||||
@ -589,11 +583,11 @@ namespace nvtt
|
|||||||
// Return NVTT version.
|
// Return NVTT version.
|
||||||
NVTT_API unsigned int version();
|
NVTT_API unsigned int version();
|
||||||
|
|
||||||
NVTT_API float rmsError(const TexImage & reference, const TexImage & img);
|
NVTT_API float rmsError(const Surface & reference, const Surface & img);
|
||||||
NVTT_API float rmsAlphaError(const TexImage & reference, const TexImage & img);
|
NVTT_API float rmsAlphaError(const Surface & reference, const Surface & img);
|
||||||
NVTT_API float cieLabError(const TexImage & reference, const TexImage & img);
|
NVTT_API float cieLabError(const Surface & reference, const Surface & img);
|
||||||
NVTT_API float angularError(const TexImage & reference, const TexImage & img);
|
NVTT_API float angularError(const Surface & reference, const Surface & img);
|
||||||
NVTT_API TexImage diff(const TexImage & reference, const TexImage & img, float scale);
|
NVTT_API Surface diff(const Surface & reference, const Surface & img, float scale);
|
||||||
|
|
||||||
|
|
||||||
} // nvtt namespace
|
} // nvtt namespace
|
||||||
|
@ -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;
|
nvtt::Surface image;
|
||||||
if (!image.load(inputFileName)) {
|
if (!image.load(inputFileName)) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ int main(int argc, char *argv[])
|
|||||||
int m = 1;
|
int m = 1;
|
||||||
while (image.buildNextMipmap(nvtt::MipmapFilter_Kaiser))
|
while (image.buildNextMipmap(nvtt::MipmapFilter_Kaiser))
|
||||||
{
|
{
|
||||||
nvtt::TexImage tmpImage = image;
|
nvtt::Surface tmpImage = image;
|
||||||
tmpImage.toGamma(gamma);
|
tmpImage.toGamma(gamma);
|
||||||
|
|
||||||
tmpImage.scaleAlphaToCoverage(coverage, alphaRef);
|
tmpImage.scaleAlphaToCoverage(coverage, alphaRef);
|
||||||
|
@ -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;
|
nvtt::Surface 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,7 +63,7 @@ int main(int argc, char *argv[])
|
|||||||
colorOutputOptions.setFileName(outputFileNameColor.str());
|
colorOutputOptions.setFileName(outputFileNameColor.str());
|
||||||
|
|
||||||
// Load normal map.
|
// Load normal map.
|
||||||
nvtt::TexImage normalMap;
|
nvtt::Surface normalMap;
|
||||||
if (inputFileNameNormal != NULL) {
|
if (inputFileNameNormal != NULL) {
|
||||||
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);
|
||||||
@ -123,7 +123,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
colorMap.scaleAlphaToCoverage(coverage, alphaRef);
|
colorMap.scaleAlphaToCoverage(coverage, alphaRef);
|
||||||
|
|
||||||
nvtt::TexImage tmpColorMap = colorMap;
|
nvtt::Surface tmpColorMap = colorMap;
|
||||||
tmpColorMap.toGamma(gamma);
|
tmpColorMap.toGamma(gamma);
|
||||||
|
|
||||||
context.compress(tmpColorMap, 0, m, colorCompressionOptions, colorOutputOptions);
|
context.compress(tmpColorMap, 0, m, colorCompressionOptions, colorOutputOptions);
|
||||||
|
@ -280,9 +280,9 @@ struct MyOutputHandler : public nvtt::OutputHandler
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nvtt::TexImage decompress(Mode mode, nvtt::Format format, nvtt::Decoder decoder)
|
nvtt::Surface decompress(Mode mode, nvtt::Format format, nvtt::Decoder decoder)
|
||||||
{
|
{
|
||||||
nvtt::TexImage img;
|
nvtt::Surface img;
|
||||||
img.setImage2D(format, decoder, m_width, m_height, m_data);
|
img.setImage2D(format, decoder, m_width, m_height, m_data);
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
@ -576,7 +576,7 @@ int main(int argc, char *argv[])
|
|||||||
//int failedTests = 0;
|
//int failedTests = 0;
|
||||||
//float totalDiff = 0;
|
//float totalDiff = 0;
|
||||||
|
|
||||||
nvtt::TexImage img;
|
nvtt::Surface img;
|
||||||
|
|
||||||
printf("Running Test: %s\n", set.name);
|
printf("Running Test: %s\n", set.name);
|
||||||
|
|
||||||
@ -640,7 +640,7 @@ int main(int argc, char *argv[])
|
|||||||
img.toGamma(2);
|
img.toGamma(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
nvtt::TexImage tmp = img;
|
nvtt::Surface tmp = img;
|
||||||
if (mode == Mode_BC1) {
|
if (mode == Mode_BC1) {
|
||||||
if (set.type == ImageType_HDR) {
|
if (set.type == ImageType_HDR) {
|
||||||
/*for (int i = 0; i < 3; i++) {
|
/*for (int i = 0; i < 3; i++) {
|
||||||
@ -727,7 +727,7 @@ int main(int argc, char *argv[])
|
|||||||
printf(" Time: \t%.3f sec\n", timer.elapsed());
|
printf(" Time: \t%.3f sec\n", timer.elapsed());
|
||||||
totalTime += timer.elapsed();
|
totalTime += timer.elapsed();
|
||||||
|
|
||||||
nvtt::TexImage img_out = outputHandler.decompress(mode, format, decoder);
|
nvtt::Surface img_out = outputHandler.decompress(mode, format, decoder);
|
||||||
img_out.setAlphaMode(img.alphaMode());
|
img_out.setAlphaMode(img.alphaMode());
|
||||||
img_out.setNormalMap(img.isNormalMap());
|
img_out.setNormalMap(img.isNormalMap());
|
||||||
|
|
||||||
@ -796,14 +796,14 @@ int main(int argc, char *argv[])
|
|||||||
tmp.transformNormals(nvtt::NormalTransform_DualParaboloid);
|
tmp.transformNormals(nvtt::NormalTransform_DualParaboloid);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
nvtt::TexImage diff = nvtt::diff(img, img_out, 1.0f);
|
nvtt::Surface diff = nvtt::diff(img, img_out, 1.0f);
|
||||||
|
|
||||||
//bool residualCompression = (set.type == ImageType_HDR);
|
//bool residualCompression = (set.type == ImageType_HDR);
|
||||||
bool residualCompression = (mode == Mode_BC3_RGBS);
|
bool residualCompression = (mode == Mode_BC3_RGBS);
|
||||||
if (residualCompression)
|
if (residualCompression)
|
||||||
{
|
{
|
||||||
float residualScale = 8.0f;
|
float residualScale = 8.0f;
|
||||||
nvtt::TexImage residual = diff;
|
nvtt::Surface residual = diff;
|
||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; j++) {
|
||||||
residual.scaleBias(j, residualScale, 0.5); // @@ The residual scale is fairly arbitrary.
|
residual.scaleBias(j, residualScale, 0.5); // @@ The residual scale is fairly arbitrary.
|
||||||
residual.clamp(j);
|
residual.clamp(j);
|
||||||
@ -821,7 +821,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
context.compress(residual, 0, 0, compressionOptions, outputOptions);
|
context.compress(residual, 0, 0, compressionOptions, outputOptions);
|
||||||
|
|
||||||
nvtt::TexImage residual_out = outputHandler.decompress(mode, format, decoder);
|
nvtt::Surface residual_out = outputHandler.decompress(mode, format, decoder);
|
||||||
|
|
||||||
/*outputFileName.format("%s/%s", outputFilePath.str(), set.fileNames[i]);
|
/*outputFileName.format("%s/%s", outputFilePath.str(), set.fileNames[i]);
|
||||||
outputFileName.stripExtension();
|
outputFileName.stripExtension();
|
||||||
@ -904,7 +904,7 @@ int main(int argc, char *argv[])
|
|||||||
regressFileName.stripExtension();
|
regressFileName.stripExtension();
|
||||||
regressFileName.append(".png");
|
regressFileName.append(".png");
|
||||||
|
|
||||||
nvtt::TexImage img_reg;
|
nvtt::Surface img_reg;
|
||||||
if (!img_reg.load(regressFileName.str()))
|
if (!img_reg.load(regressFileName.str()))
|
||||||
{
|
{
|
||||||
printf("Regression image '%s' not found.\n", regressFileName.str());
|
printf("Regression image '%s' not found.\n", regressFileName.str());
|
||||||
|
Loading…
Reference in New Issue
Block a user