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.
|
||||
bool Compressor::outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
|
||||
// Surface API.
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 h = tex.height();
|
||||
@ -152,12 +152,12 @@ int Compressor::estimateSize(const TexImage & tex, int mipmapCount, const Compre
|
||||
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);
|
||||
}
|
||||
|
||||
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++) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@ -223,7 +223,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
|
||||
return false;
|
||||
}
|
||||
|
||||
nvtt::TexImage img;
|
||||
nvtt::Surface img;
|
||||
img.setWrapMode(inputOptions.wrapMode);
|
||||
img.setAlphaMode(inputOptions.alphaMode);
|
||||
img.setNormalMap(inputOptions.isNormalMap);
|
||||
@ -269,7 +269,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
|
||||
// Resize input.
|
||||
img.resize(w, h, d, ResizeFilter_Box);
|
||||
|
||||
nvtt::TexImage tmp = img;
|
||||
nvtt::Surface tmp = img;
|
||||
if (!img.isNormalMap()) {
|
||||
tmp.toGamma(inputOptions.outputGamma);
|
||||
}
|
||||
@ -333,7 +333,7 @@ bool Compressor::Private::compress(const InputOptions::Private & inputOptions, c
|
||||
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)) {
|
||||
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.format >= Format_BC1 && compressionOptions.format <= Format_BC3) {
|
||||
|
@ -46,10 +46,10 @@ namespace nvtt
|
||||
Private() {}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -24,41 +24,46 @@
|
||||
#include "CubeImage.h"
|
||||
#include "TexImage.h"
|
||||
|
||||
#include "nvmath/Vector.h"
|
||||
|
||||
#include "nvcore/Array.h"
|
||||
|
||||
|
||||
using namespace nv;
|
||||
using namespace nvtt;
|
||||
|
||||
|
||||
|
||||
|
||||
CubeImage::CubeImage() : m(new CubeImage::Private())
|
||||
CubeSurface::CubeSurface() : m(new CubeSurface::Private())
|
||||
{
|
||||
m->addRef();
|
||||
}
|
||||
|
||||
CubeImage::CubeImage(const CubeImage & cube) : m(cube.m)
|
||||
CubeSurface::CubeSurface(const CubeSurface & cube) : m(cube.m)
|
||||
{
|
||||
if (m != NULL) m->addRef();
|
||||
}
|
||||
|
||||
CubeImage::~CubeImage()
|
||||
CubeSurface::~CubeSurface()
|
||||
{
|
||||
if (m != NULL) m->release();
|
||||
m = NULL;
|
||||
}
|
||||
|
||||
void CubeImage::operator=(const CubeImage & cube)
|
||||
void CubeSurface::operator=(const CubeSurface & cube)
|
||||
{
|
||||
if (cube.m != NULL) cube.m->addRef();
|
||||
if (m != NULL) m->release();
|
||||
m = cube.m;
|
||||
}
|
||||
|
||||
void CubeImage::detach()
|
||||
void CubeSurface::detach()
|
||||
{
|
||||
if (m->refCount() > 1)
|
||||
{
|
||||
m->release();
|
||||
m = new CubeImage::Private(*m);
|
||||
m = new CubeSurface::Private(*m);
|
||||
m->addRef();
|
||||
nvDebugCheck(m->refCount() == 1);
|
||||
}
|
||||
@ -66,73 +71,301 @@ void CubeImage::detach()
|
||||
|
||||
|
||||
|
||||
bool CubeImage::isNull() const
|
||||
bool CubeSurface::isNull() const
|
||||
{
|
||||
return m->size == 0;
|
||||
}
|
||||
|
||||
int CubeImage::size() const
|
||||
int CubeSurface::size() const
|
||||
{
|
||||
return m->size;
|
||||
}
|
||||
|
||||
int CubeImage::countMipmaps() const
|
||||
int CubeSurface::countMipmaps() const
|
||||
{
|
||||
return nv::countMipmaps(m->size);
|
||||
}
|
||||
|
||||
TexImage & CubeImage::face(int f)
|
||||
Surface & CubeSurface::face(int f)
|
||||
{
|
||||
nvDebugCheck(f >= 0 && f < 6);
|
||||
return m->face[f];
|
||||
}
|
||||
|
||||
const TexImage & CubeImage::face(int f) const
|
||||
const Surface & CubeSurface::face(int f) const
|
||||
{
|
||||
nvDebugCheck(f >= 0 && f < 6);
|
||||
return m->face[f];
|
||||
}
|
||||
|
||||
|
||||
bool CubeImage::load(const char * fileName)
|
||||
bool CubeSurface::load(const char * fileName)
|
||||
{
|
||||
// @@ TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CubeImage::save(const char * fileName) const
|
||||
bool CubeSurface::save(const char * fileName) const
|
||||
{
|
||||
// @@ TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CubeImage::fold(const TexImage & tex, CubeLayout layout)
|
||||
void CubeSurface::fold(const Surface & tex, CubeLayout layout)
|
||||
{
|
||||
// @@ TODO
|
||||
}
|
||||
|
||||
TexImage CubeImage::unfold(CubeLayout layout) const
|
||||
Surface CubeSurface::unfold(CubeLayout layout) const
|
||||
{
|
||||
// @@ TODO
|
||||
return TexImage();
|
||||
return Surface();
|
||||
}
|
||||
|
||||
|
||||
CubeImage CubeImage::irradianceFilter(int size) const
|
||||
CubeSurface CubeSurface::irradianceFilter(int size) const
|
||||
{
|
||||
// @@ TODO
|
||||
return CubeImage();
|
||||
}
|
||||
|
||||
CubeImage CubeImage::cosinePowerFilter(int size, float cosinePower) const
|
||||
{
|
||||
// @@ TODO
|
||||
return CubeImage();
|
||||
return CubeSurface();
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
@ -143,7 +376,7 @@ void CubeImage::toLinear(float gamma)
|
||||
}
|
||||
}
|
||||
|
||||
void CubeImage::toGamma(float gamma)
|
||||
void CubeSurface::toGamma(float gamma)
|
||||
{
|
||||
if (isNull()) return;
|
||||
|
||||
|
@ -25,6 +25,9 @@
|
||||
#define NVTT_CUBEIMAGE_H
|
||||
|
||||
#include "nvtt.h"
|
||||
#include "TexImage.h"
|
||||
|
||||
#include "nvimage/FloatImage.h"
|
||||
|
||||
#include "nvcore/RefCounted.h"
|
||||
#include "nvcore/Ptr.h"
|
||||
@ -33,7 +36,7 @@
|
||||
namespace nvtt
|
||||
{
|
||||
|
||||
struct CubeImage::Private : public nv::RefCounted
|
||||
struct CubeSurface::Private : public nv::RefCounted
|
||||
{
|
||||
void operator=(const Private &);
|
||||
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;
|
||||
TexImage face[6];
|
||||
Surface face[6];
|
||||
};
|
||||
|
||||
} // 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();
|
||||
}
|
||||
|
||||
TexImage::TexImage(const TexImage & tex) : m(tex.m)
|
||||
Surface::Surface(const Surface & tex) : m(tex.m)
|
||||
{
|
||||
if (m != NULL) m->addRef();
|
||||
}
|
||||
|
||||
TexImage::~TexImage()
|
||||
Surface::~Surface()
|
||||
{
|
||||
if (m != NULL) m->release();
|
||||
m = NULL;
|
||||
}
|
||||
|
||||
void TexImage::operator=(const TexImage & tex)
|
||||
void Surface::operator=(const Surface & tex)
|
||||
{
|
||||
if (tex.m != NULL) tex.m->addRef();
|
||||
if (m != NULL) m->release();
|
||||
m = tex.m;
|
||||
}
|
||||
|
||||
void TexImage::detach()
|
||||
void Surface::detach()
|
||||
{
|
||||
if (m->refCount() > 1)
|
||||
{
|
||||
m->release();
|
||||
m = new TexImage::Private(*m);
|
||||
m = new Surface::Private(*m);
|
||||
m->addRef();
|
||||
nvDebugCheck(m->refCount() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
void TexImage::setWrapMode(WrapMode wrapMode)
|
||||
void Surface::setWrapMode(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)
|
||||
{
|
||||
@ -236,7 +236,7 @@ void TexImage::setAlphaMode(AlphaMode alphaMode)
|
||||
}
|
||||
}
|
||||
|
||||
void TexImage::setNormalMap(bool isNormalMap)
|
||||
void Surface::setNormalMap(bool 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;
|
||||
}
|
||||
|
||||
int TexImage::width() const
|
||||
int Surface::width() const
|
||||
{
|
||||
if (m->image != NULL) return m->image->width();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TexImage::height() const
|
||||
int Surface::height() const
|
||||
{
|
||||
if (m->image != NULL) return m->image->height();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TexImage::depth() const
|
||||
int Surface::depth() const
|
||||
{
|
||||
if (m->image != NULL) return m->image->depth();
|
||||
return 0;
|
||||
}
|
||||
|
||||
WrapMode TexImage::wrapMode() const
|
||||
WrapMode Surface::wrapMode() const
|
||||
{
|
||||
return m->wrapMode;
|
||||
}
|
||||
|
||||
AlphaMode TexImage::alphaMode() const
|
||||
AlphaMode Surface::alphaMode() const
|
||||
{
|
||||
return m->alphaMode;
|
||||
}
|
||||
|
||||
bool TexImage::isNormalMap() const
|
||||
bool Surface::isNormalMap() const
|
||||
{
|
||||
return m->isNormalMap;
|
||||
}
|
||||
|
||||
TextureType TexImage::type() const
|
||||
TextureType Surface::type() const
|
||||
{
|
||||
return m->type;
|
||||
}
|
||||
|
||||
int TexImage::countMipmaps() const
|
||||
int Surface::countMipmaps() const
|
||||
{
|
||||
if (m->image == NULL) return 0;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
@ -337,12 +337,12 @@ float TexImage::average(int channel, int alpha_channel/*= -1*/, float gamma /*=
|
||||
return sum / denom;
|
||||
}
|
||||
|
||||
const float * TexImage::data() const
|
||||
const float * Surface::data() const
|
||||
{
|
||||
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.
|
||||
//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);
|
||||
|
||||
@ -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));
|
||||
if (img == NULL) {
|
||||
@ -406,7 +406,7 @@ bool TexImage::load(const char * fileName, bool * hasAlpha/*= NULL*/)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TexImage::save(const char * fileName) const
|
||||
bool Surface::save(const char * fileName) const
|
||||
{
|
||||
if (m->image != NULL)
|
||||
{
|
||||
@ -416,7 +416,7 @@ bool TexImage::save(const char * fileName) const
|
||||
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();
|
||||
|
||||
@ -488,7 +488,7 @@ bool TexImage::setImage(nvtt::InputFormat format, int w, int h, int d, const voi
|
||||
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();
|
||||
|
||||
@ -561,7 +561,7 @@ bool TexImage::setImage(InputFormat format, int w, int h, int d, const void * r,
|
||||
}
|
||||
|
||||
// @@ 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)
|
||||
{
|
||||
@ -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 params[2];
|
||||
@ -702,7 +702,7 @@ void TexImage::resize(int w, int h, int d, ResizeFilter filter)
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
|
||||
void Surface::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
|
||||
{
|
||||
float filterWidth;
|
||||
float params[2];
|
||||
@ -779,7 +779,7 @@ void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
|
||||
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;
|
||||
|
||||
@ -792,7 +792,7 @@ void TexImage::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter, f
|
||||
resize(w, h, d, filter, filterWidth, params);
|
||||
}
|
||||
|
||||
bool TexImage::buildNextMipmap(MipmapFilter filter)
|
||||
bool Surface::buildNextMipmap(MipmapFilter filter)
|
||||
{
|
||||
float filterWidth;
|
||||
float params[2];
|
||||
@ -801,7 +801,7 @@ bool TexImage::buildNextMipmap(MipmapFilter filter)
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -901,7 +901,7 @@ void TexImage::canvasSize(int w, int h, int d)
|
||||
|
||||
|
||||
// Color transforms.
|
||||
void TexImage::toLinear(float gamma)
|
||||
void Surface::toLinear(float gamma)
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
if (equal(gamma, 1.0f)) return;
|
||||
@ -911,7 +911,7 @@ void TexImage::toLinear(float gamma)
|
||||
m->image->toLinear(0, 3, gamma);
|
||||
}
|
||||
|
||||
void TexImage::toGamma(float gamma)
|
||||
void Surface::toGamma(float gamma)
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
if (equal(gamma, 1.0f)) return;
|
||||
@ -930,7 +930,7 @@ static float toSrgb(float f) {
|
||||
return f;
|
||||
}
|
||||
|
||||
void TexImage::toSrgb()
|
||||
void Surface::toSrgb()
|
||||
{
|
||||
FloatImage * img = m->image;
|
||||
if (img == NULL) return;
|
||||
@ -960,7 +960,7 @@ static float toXenonSrgb(float f) {
|
||||
return f;
|
||||
}
|
||||
|
||||
void TexImage::toXenonSrgb()
|
||||
void Surface::toXenonSrgb()
|
||||
{
|
||||
FloatImage * img = m->image;
|
||||
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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
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 (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
|
||||
void TexImage::scaleBias(int channel, float scale, float bias)
|
||||
void Surface::scaleBias(int channel, float scale, float bias)
|
||||
{
|
||||
if (m->image == NULL) 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);
|
||||
}
|
||||
|
||||
void TexImage::clamp(int channel, float low, float high)
|
||||
void Surface::clamp(int channel, float low, float high)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void TexImage::packNormal()
|
||||
void Surface::packNormal()
|
||||
{
|
||||
scaleBias(0, 0.5f, 0.5f);
|
||||
scaleBias(1, 0.5f, 0.5f);
|
||||
scaleBias(2, 0.5f, 0.5f);
|
||||
}
|
||||
|
||||
void TexImage::expandNormal()
|
||||
void Surface::expandNormal()
|
||||
{
|
||||
scaleBias(0, 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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -1114,7 +1114,7 @@ void TexImage::toGreyScale(float redScale, float greenScale, float blueScale, fl
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@ -1156,7 +1156,7 @@ void TexImage::setBorder(float r, float g, float b, float a)
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -1188,7 +1188,7 @@ void TexImage::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
|
||||
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;
|
||||
|
||||
@ -1218,7 +1218,7 @@ void TexImage::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
|
||||
|
||||
// Ideally you should compress/quantize the RGB and M portions independently.
|
||||
// Once you have M quantized, you would compute the corresponding RGB and quantize that.
|
||||
void TexImage::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
|
||||
void Surface::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
|
||||
{
|
||||
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;
|
||||
|
||||
@ -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.
|
||||
void TexImage::toYCoCg()
|
||||
void Surface::toYCoCg()
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
|
||||
@ -1348,7 +1348,7 @@ void TexImage::toYCoCg()
|
||||
// @@ Add support for threshold.
|
||||
// We could do something to prevent scale values from adjacent blocks from being too different to each other
|
||||
// and minimize bilinear interpolation artifacts.
|
||||
void TexImage::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
|
||||
void Surface::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
|
||||
{
|
||||
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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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.
|
||||
fromRGBM(range * sqrtf(3));
|
||||
}
|
||||
|
||||
void TexImage::abs(int channel)
|
||||
void Surface::abs(int channel)
|
||||
{
|
||||
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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -1575,7 +1575,7 @@ void TexImage::blockLuminanceScale(float scale)
|
||||
*/
|
||||
|
||||
/*
|
||||
void TexImage::toJPEGLS()
|
||||
void Surface::toJPEGLS()
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
|
||||
@ -1598,7 +1598,7 @@ void TexImage::toJPEGLS()
|
||||
}
|
||||
}
|
||||
|
||||
void TexImage::fromJPEGLS()
|
||||
void Surface::fromJPEGLS()
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
|
||||
@ -1624,7 +1624,7 @@ void TexImage::fromJPEGLS()
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
@ -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.
|
||||
// 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.
|
||||
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;
|
||||
|
||||
@ -1758,7 +1758,7 @@ void TexImage::quantize(int channel, int bits, bool exactEndPoints, bool dither)
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
@ -1777,7 +1777,7 @@ void TexImage::toNormalMap(float sm, float medium, float big, float large)
|
||||
m->isNormalMap = true;
|
||||
}
|
||||
|
||||
void TexImage::normalizeNormalMap()
|
||||
void Surface::normalizeNormalMap()
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
if (!m->isNormalMap) return;
|
||||
@ -1787,7 +1787,7 @@ void TexImage::normalizeNormalMap()
|
||||
nv::normalizeNormalMap(m->image);
|
||||
}
|
||||
|
||||
void TexImage::transformNormals(NormalTransform xform)
|
||||
void Surface::transformNormals(NormalTransform xform)
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
|
||||
@ -1860,7 +1860,7 @@ void TexImage::transformNormals(NormalTransform xform)
|
||||
img->packNormals(0);
|
||||
}
|
||||
|
||||
void TexImage::reconstructNormals(NormalTransform xform)
|
||||
void Surface::reconstructNormals(NormalTransform xform)
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
|
||||
@ -1909,7 +1909,7 @@ void TexImage::reconstructNormals(NormalTransform xform)
|
||||
img->packNormals(0);
|
||||
}
|
||||
|
||||
void TexImage::toCleanNormalMap()
|
||||
void Surface::toCleanNormalMap()
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
|
||||
@ -1929,21 +1929,21 @@ void TexImage::toCleanNormalMap()
|
||||
}
|
||||
|
||||
// [-1,1] -> [ 0,1]
|
||||
void TexImage::packNormals() {
|
||||
void Surface::packNormals() {
|
||||
if (m->image == NULL) return;
|
||||
detach();
|
||||
m->image->packNormals(0);
|
||||
}
|
||||
|
||||
// [ 0,1] -> [-1,1]
|
||||
void TexImage::expandNormals() {
|
||||
void Surface::expandNormals() {
|
||||
if (m->image == NULL) return;
|
||||
detach();
|
||||
m->image->expandNormals(0);
|
||||
}
|
||||
|
||||
|
||||
void TexImage::flipX()
|
||||
void Surface::flipX()
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
|
||||
@ -1952,7 +1952,7 @@ void TexImage::flipX()
|
||||
m->image->flipX();
|
||||
}
|
||||
|
||||
void TexImage::flipY()
|
||||
void Surface::flipY()
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
|
||||
@ -1961,7 +1961,7 @@ void TexImage::flipY()
|
||||
m->image->flipY();
|
||||
}
|
||||
|
||||
void TexImage::flipZ()
|
||||
void Surface::flipZ()
|
||||
{
|
||||
if (m->image == NULL) return;
|
||||
|
||||
@ -1970,12 +1970,12 @@ void TexImage::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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -1994,7 +1994,7 @@ bool TexImage::copyChannel(const TexImage & srcImage, int srcChannel, int dstCha
|
||||
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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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::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 * img = image.m->image;
|
||||
|
||||
if (!sameLayout(img, ref)) {
|
||||
return TexImage();
|
||||
return Surface();
|
||||
}
|
||||
|
||||
nvDebugCheck(img->componentCount() == 4);
|
||||
nvDebugCheck(ref->componentCount() == 4);
|
||||
|
||||
nvtt::TexImage diffImage;
|
||||
nvtt::Surface diffImage;
|
||||
FloatImage * diff = diffImage.m->image = new FloatImage;
|
||||
diff->allocate(4, img->width(), img->height(), img->depth());
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
namespace nvtt
|
||||
{
|
||||
|
||||
struct TexImage::Private : public nv::RefCounted
|
||||
struct Surface::Private : public nv::RefCounted
|
||||
{
|
||||
void operator=(const Private &);
|
||||
public:
|
||||
|
@ -67,8 +67,8 @@
|
||||
namespace nvtt
|
||||
{
|
||||
// Forward declarations.
|
||||
struct TexImage;
|
||||
struct CubeImage;
|
||||
struct Surface;
|
||||
struct CubeSurface;
|
||||
|
||||
/// Supported compression formats.
|
||||
enum Format
|
||||
@ -378,15 +378,15 @@ namespace nvtt
|
||||
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;
|
||||
|
||||
// TexImage API.
|
||||
NVTT_API bool outputHeader(const TexImage & tex, 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 int estimateSize(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
||||
// Surface API.
|
||||
NVTT_API bool outputHeader(const Surface & img, int mipmapCount, 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 Surface & img, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
||||
|
||||
// CubeImage API.
|
||||
NVTT_API bool outputHeader(const CubeImage & 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 int estimateSize(const CubeImage & cube, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
||||
// CubeSurface API.
|
||||
NVTT_API bool outputHeader(const CubeSurface & cube, int mipmapCount, 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 CubeSurface & cube, int mipmapCount, const CompressionOptions & compressionOptions) const;
|
||||
|
||||
// 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;
|
||||
@ -405,14 +405,15 @@ namespace nvtt
|
||||
//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.
|
||||
NVTT_API void setWrapMode(WrapMode mode);
|
||||
@ -500,19 +501,12 @@ namespace nvtt
|
||||
NVTT_API void flipZ();
|
||||
|
||||
// Copy image data.
|
||||
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel);
|
||||
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel);
|
||||
NVTT_API bool copyChannel(const Surface & srcImage, int srcChannel);
|
||||
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.
|
||||
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:
|
||||
//private:
|
||||
void detach();
|
||||
|
||||
struct Private;
|
||||
@ -528,14 +522,14 @@ namespace nvtt
|
||||
CubeLayout_LatitudeLongitude,
|
||||
};
|
||||
|
||||
/// A cubemap mipmap.
|
||||
struct CubeImage
|
||||
/// A cubemap mipmap. CubeSurface?
|
||||
struct CubeSurface
|
||||
{
|
||||
NVTT_API CubeImage();
|
||||
NVTT_API CubeImage(const CubeImage & tex);
|
||||
NVTT_API ~CubeImage();
|
||||
NVTT_API CubeSurface();
|
||||
NVTT_API CubeSurface(const CubeSurface & img);
|
||||
NVTT_API ~CubeSurface();
|
||||
|
||||
NVTT_API void operator=(const CubeImage & tex);
|
||||
NVTT_API void operator=(const CubeSurface & img);
|
||||
|
||||
// Queries.
|
||||
NVTT_API bool isNull() const;
|
||||
@ -546,20 +540,20 @@ namespace nvtt
|
||||
NVTT_API bool load(const char * fileName);
|
||||
NVTT_API bool save(const char * fileName) const;
|
||||
|
||||
TexImage & face(int face);
|
||||
const TexImage & face(int face) const;
|
||||
Surface & face(int face);
|
||||
const Surface & face(int face) const;
|
||||
|
||||
// Layout conversion.
|
||||
void fold(const TexImage & img, CubeLayout layout);
|
||||
TexImage unfold(CubeLayout layout) const;
|
||||
void fold(const Surface & img, CubeLayout layout);
|
||||
Surface unfold(CubeLayout layout) const;
|
||||
|
||||
// @@ Angular extent filtering.
|
||||
|
||||
// @@ Add resizing methods.
|
||||
|
||||
// Filtering.
|
||||
CubeImage irradianceFilter(int size) const;
|
||||
CubeImage cosinePowerFilter(int size, float cosinePower) const;
|
||||
CubeSurface irradianceFilter(int size) const;
|
||||
CubeSurface cosinePowerFilter(int size, float cosinePower) const;
|
||||
|
||||
|
||||
/*
|
||||
@ -575,7 +569,7 @@ namespace nvtt
|
||||
NVTT_API void toLinear(float gamma);
|
||||
NVTT_API void toGamma(float gamma);
|
||||
|
||||
private:
|
||||
//private:
|
||||
void detach();
|
||||
|
||||
struct Private;
|
||||
@ -589,11 +583,11 @@ namespace nvtt
|
||||
// Return NVTT version.
|
||||
NVTT_API unsigned int version();
|
||||
|
||||
NVTT_API float rmsError(const TexImage & reference, const TexImage & img);
|
||||
NVTT_API float rmsAlphaError(const TexImage & reference, const TexImage & img);
|
||||
NVTT_API float cieLabError(const TexImage & reference, const TexImage & img);
|
||||
NVTT_API float angularError(const TexImage & reference, const TexImage & img);
|
||||
NVTT_API TexImage diff(const TexImage & reference, const TexImage & img, float scale);
|
||||
NVTT_API float rmsError(const Surface & reference, const Surface & img);
|
||||
NVTT_API float rmsAlphaError(const Surface & reference, const Surface & img);
|
||||
NVTT_API float cieLabError(const Surface & reference, const Surface & img);
|
||||
NVTT_API float angularError(const Surface & reference, const Surface & img);
|
||||
NVTT_API Surface diff(const Surface & reference, const Surface & img, float scale);
|
||||
|
||||
|
||||
} // nvtt namespace
|
||||
|
@ -38,7 +38,7 @@ int main(int argc, char *argv[])
|
||||
context.enableCudaAcceleration(false);
|
||||
|
||||
// Load input image.
|
||||
nvtt::TexImage image;
|
||||
nvtt::Surface image;
|
||||
if (!image.load(inputFileName)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@ -76,7 +76,7 @@ int main(int argc, char *argv[])
|
||||
int m = 1;
|
||||
while (image.buildNextMipmap(nvtt::MipmapFilter_Kaiser))
|
||||
{
|
||||
nvtt::TexImage tmpImage = image;
|
||||
nvtt::Surface tmpImage = image;
|
||||
tmpImage.toGamma(gamma);
|
||||
|
||||
tmpImage.scaleAlphaToCoverage(coverage, alphaRef);
|
||||
|
@ -43,7 +43,7 @@ int main(int argc, char *argv[])
|
||||
context.enableCudaAcceleration(false);
|
||||
|
||||
// Load color map.
|
||||
nvtt::TexImage colorMap;
|
||||
nvtt::Surface colorMap;
|
||||
if (!colorMap.load(inputFileNameColor)) {
|
||||
printf("Image '%s' could not be loaded.\n", inputFileNameColor);
|
||||
return EXIT_FAILURE;
|
||||
@ -63,7 +63,7 @@ int main(int argc, char *argv[])
|
||||
colorOutputOptions.setFileName(outputFileNameColor.str());
|
||||
|
||||
// Load normal map.
|
||||
nvtt::TexImage normalMap;
|
||||
nvtt::Surface normalMap;
|
||||
if (inputFileNameNormal != NULL) {
|
||||
if (!normalMap.load(inputFileNameColor)) {
|
||||
printf("Image '%s' could not be loaded.\n", inputFileNameNormal);
|
||||
@ -123,7 +123,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
colorMap.scaleAlphaToCoverage(coverage, alphaRef);
|
||||
|
||||
nvtt::TexImage tmpColorMap = colorMap;
|
||||
nvtt::Surface tmpColorMap = colorMap;
|
||||
tmpColorMap.toGamma(gamma);
|
||||
|
||||
context.compress(tmpColorMap, 0, m, colorCompressionOptions, colorOutputOptions);
|
||||
|
@ -280,9 +280,9 @@ struct MyOutputHandler : public nvtt::OutputHandler
|
||||
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);
|
||||
return img;
|
||||
}
|
||||
@ -576,7 +576,7 @@ int main(int argc, char *argv[])
|
||||
//int failedTests = 0;
|
||||
//float totalDiff = 0;
|
||||
|
||||
nvtt::TexImage img;
|
||||
nvtt::Surface img;
|
||||
|
||||
printf("Running Test: %s\n", set.name);
|
||||
|
||||
@ -640,7 +640,7 @@ int main(int argc, char *argv[])
|
||||
img.toGamma(2);
|
||||
}
|
||||
|
||||
nvtt::TexImage tmp = img;
|
||||
nvtt::Surface tmp = img;
|
||||
if (mode == Mode_BC1) {
|
||||
if (set.type == ImageType_HDR) {
|
||||
/*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());
|
||||
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.setNormalMap(img.isNormalMap());
|
||||
|
||||
@ -796,14 +796,14 @@ int main(int argc, char *argv[])
|
||||
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 = (mode == Mode_BC3_RGBS);
|
||||
if (residualCompression)
|
||||
{
|
||||
float residualScale = 8.0f;
|
||||
nvtt::TexImage residual = diff;
|
||||
nvtt::Surface residual = diff;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
residual.scaleBias(j, residualScale, 0.5); // @@ The residual scale is fairly arbitrary.
|
||||
residual.clamp(j);
|
||||
@ -821,7 +821,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
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.stripExtension();
|
||||
@ -904,7 +904,7 @@ int main(int argc, char *argv[])
|
||||
regressFileName.stripExtension();
|
||||
regressFileName.append(".png");
|
||||
|
||||
nvtt::TexImage img_reg;
|
||||
nvtt::Surface img_reg;
|
||||
if (!img_reg.load(regressFileName.str()))
|
||||
{
|
||||
printf("Regression image '%s' not found.\n", regressFileName.str());
|
||||
|
Loading…
Reference in New Issue
Block a user