Merge changes from the witness.

This commit is contained in:
castano
2011-10-10 20:24:12 +00:00
parent 94401919b8
commit 2ec37026be
35 changed files with 9420 additions and 9328 deletions

View File

@ -183,6 +183,35 @@ Surface CubeSurface::unfold(CubeLayout layout) const
}
float CubeSurface::average(int channel) const
{
const uint edgeLength = m->edgeLength;
// These tables along with the surface so that we only compute them once.
if (m->solidAngleTable == NULL) {
m->solidAngleTable = new SolidAngleTable(edgeLength);
}
float total = 0.0f;
float sum = 0.0f;
for (int f = 0; f < 6; f++) {
float * c = m->face[f].m->image->channel(channel);
for (uint y = 0; y < edgeLength; y++) {
for (uint x = 0; x < edgeLength; x++) {
float solidAngle = m->solidAngleTable->lookup(x, y);
total += solidAngle;
sum += c[y * edgeLength + x] * solidAngle;
}
}
}
return sum / total;
}
CubeSurface CubeSurface::irradianceFilter(int size) const
{
// @@ TODO
@ -237,7 +266,7 @@ SolidAngleTable::SolidAngleTable(uint edgeLength) : size(edgeLength/2) {
for (uint y = 0; y < size; y++) {
for (uint x = 0; x < size; x++) {
data[y * size + x] = solidAngleTerm(128+x, 128+y, inverseEdgeLength);
data[y * size + x] = solidAngleTerm(size+x, size+y, inverseEdgeLength);
}
}
}
@ -631,7 +660,7 @@ CubeSurface CubeSurface::cosinePowerFilter(int size, float cosinePower) const
CubeSurface filteredCube;
filteredCube.m->allocate(size);
// Store these tables along with the surface. Compute them only once!
// These tables along with the surface so that we only compute them once.
if (m->solidAngleTable == NULL) {
m->solidAngleTable = new SolidAngleTable(edgeLength);
}

View File

@ -74,7 +74,7 @@ namespace nvtt
edgeLength = p.edgeLength;
for (uint i = 0; i < 6; i++) {
face[i] = p.face[6];
face[i] = p.face[i];
}
solidAngleTable = NULL; // @@ Transfer tables. Needs refcounting?
vectorTable = NULL;

View File

@ -44,6 +44,7 @@ OutputOptions::~OutputOptions()
void OutputOptions::reset()
{
m.fileName.reset();
m.fileHandle = NULL;
m.outputHandler = NULL;
m.errorHandler = NULL;
@ -52,37 +53,67 @@ void OutputOptions::reset()
m.container = Container_DDS;
m.version = 0;
m.srgb = false;
m.deleteOutputHandler = false;
}
/// Set output file name.
void OutputOptions::setFileName(const char * fileName)
{
if (!m.fileName.isNull())
if (m.deleteOutputHandler)
{
// To close the file and avoid leak.
delete m.outputHandler;
}
m.fileName = fileName;
m.fileHandle = NULL;
m.outputHandler = NULL;
m.deleteOutputHandler = false;
DefaultOutputHandler * oh = new DefaultOutputHandler(fileName);
if (!oh->stream.isError())
{
if (oh->stream.isError()) {
delete oh;
}
else {
m.deleteOutputHandler = true;
m.outputHandler = oh;
}
}
/// Set output file handle.
void OutputOptions::setFileHandle(void * fp)
{
if (m.deleteOutputHandler) {
delete m.outputHandler;
}
m.fileName.reset();
m.fileHandle = (FILE *)fp;
m.outputHandler = NULL;
m.deleteOutputHandler = false;
DefaultOutputHandler * oh = new DefaultOutputHandler(m.fileHandle);
if (oh->stream.isError()) {
delete oh;
}
else {
m.deleteOutputHandler = true;
m.outputHandler = oh;
}
}
/// Set output handler.
void OutputOptions::setOutputHandler(OutputHandler * outputHandler)
{
if (!m.fileName.isNull())
{
if (m.deleteOutputHandler) {
delete m.outputHandler;
m.fileName.reset();
}
m.fileName.reset();
m.fileHandle = NULL;
m.outputHandler = outputHandler;
m.deleteOutputHandler = false;
}
/// Set error handler.
@ -117,7 +148,7 @@ void OutputOptions::setSrgbFlag(bool b)
bool OutputOptions::Private::hasValidOutputHandler() const
{
if (!fileName.isNull())
if (!fileName.isNull() || fileHandle != NULL)
{
return outputHandler != NULL;
}

View File

@ -25,16 +25,19 @@
#ifndef NV_TT_OUTPUTOPTIONS_H
#define NV_TT_OUTPUTOPTIONS_H
#include <nvcore/StrLib.h> // Path
#include <nvcore/StdStream.h>
#include "nvtt.h"
#include "nvcore/StrLib.h" // Path
#include "nvcore/StdStream.h"
namespace nvtt
{
struct DefaultOutputHandler : public nvtt::OutputHandler
{
DefaultOutputHandler(const char * fileName) : stream(fileName) {}
DefaultOutputHandler(FILE * fp) : stream(fp, false) {}
virtual ~DefaultOutputHandler() {}
@ -64,6 +67,7 @@ namespace nvtt
struct OutputOptions::Private
{
nv::Path fileName;
FILE * fileHandle;
OutputHandler * outputHandler;
ErrorHandler * errorHandler;
@ -72,6 +76,7 @@ namespace nvtt
Container container;
int version;
bool srgb;
bool deleteOutputHandler;
bool hasValidOutputHandler() const;

View File

@ -704,13 +704,14 @@ void Surface::resize(int w, int h, int d, ResizeFilter filter)
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())) {
if (isNull() || (w == width() && h == height() && d == depth())) {
return;
}
detach();
FloatImage * img = m->image;
FloatImage::WrapMode wrapMode = (FloatImage::WrapMode)m->wrapMode;
if (m->alphaMode == AlphaMode_Transparency)
@ -781,7 +782,7 @@ void Surface::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter)
void Surface::resize(int maxExtent, RoundMode roundMode, ResizeFilter filter, float filterWidth, const float * params)
{
if (m->image == NULL) return;
if (isNull()) return;
int w = m->image->width();
int h = m->image->height();
@ -803,13 +804,14 @@ bool Surface::buildNextMipmap(MipmapFilter filter)
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)) {
if (isNull() || (width() == 1 && height() == 1 && depth() == 1)) {
return false;
}
detach();
FloatImage * img = m->image;
FloatImage::WrapMode wrapMode = (FloatImage::WrapMode)m->wrapMode;
if (m->alphaMode == AlphaMode_Transparency)
@ -868,13 +870,14 @@ void Surface::canvasSize(int w, int h, int d)
{
nvDebugCheck(w > 0 && h > 0 && d > 0);
FloatImage * img = m->image;
if (img == NULL || (w == img->width() && h == img->height() && d == img->depth())) {
if (isNull() || (w == width() && h == height() && d == depth())) {
return;
}
detach();
FloatImage * img = m->image;
FloatImage * new_img = new FloatImage;
new_img->allocate(4, w, h, d);
new_img->clear();
@ -903,7 +906,7 @@ void Surface::canvasSize(int w, int h, int d)
// Color transforms.
void Surface::toLinear(float gamma)
{
if (m->image == NULL) return;
if (isNull()) return;
if (equal(gamma, 1.0f)) return;
detach();
@ -913,7 +916,7 @@ void Surface::toLinear(float gamma)
void Surface::toGamma(float gamma)
{
if (m->image == NULL) return;
if (isNull()) return;
if (equal(gamma, 1.0f)) return;
detach();
@ -923,7 +926,8 @@ void Surface::toGamma(float gamma)
static float toSrgb(float f) {
if (f <= 0.0) f = 0.0f;
if (isNan(f)) f = 0.0f;
else if (f <= 0.0f) f = 0.0f;
else if (f <= 0.0031308f) f = 12.92f * f;
else if (f <= 1.0f) f = (powf(f, 0.41666f) * 1.055f) - 0.055f;
else f = 1.0f;
@ -932,21 +936,43 @@ static float toSrgb(float f) {
void Surface::toSrgb()
{
FloatImage * img = m->image;
if (img == NULL) return;
if (isNull()) return;
detach();
const uint count = img->pixelCount();
for (uint j = 0; j < count; j++)
{
float & r = img->pixel(0, j);
float & g = img->pixel(1, j);
float & b = img->pixel(2, j);
FloatImage * img = m->image;
r = ::toSrgb(r);
g = ::toSrgb(g);
b = ::toSrgb(b);
const uint count = img->pixelCount();
for (uint c = 0; c < 3; c++) {
float * channel = img->channel(c);
for (uint i = 0; i < count; i++) {
channel[i] = ::toSrgb(channel[i]);
}
}
}
static float fromSrgb(float f) {
if (f < 0.0f) f = 0.0f;
else if (f < 0.04045f) f = f / 12.92f;
else if (f <= 1.0f) f = powf((f + 0.055f) / 1.055f, 2.4f);
else f = 1.0f;
return f;
}
void Surface::toLinearFromSrgb()
{
if (isNull()) return;
detach();
FloatImage * img = m->image;
const uint count = img->pixelCount();
for (uint c = 0; c < 3; c++) {
float * channel = img->channel(c);
for (uint i = 0; i < count; i++) {
channel[i] = ::fromSrgb(channel[i]);
}
}
}
@ -962,28 +988,25 @@ static float toXenonSrgb(float f) {
void Surface::toXenonSrgb()
{
FloatImage * img = m->image;
if (img == NULL) return;
if (isNull()) return;
detach();
const uint count = img->pixelCount();
for (uint j = 0; j < count; j++)
{
float & r = img->pixel(0, j);
float & g = img->pixel(1, j);
float & b = img->pixel(2, j);
FloatImage * img = m->image;
r = ::toXenonSrgb(r);
g = ::toXenonSrgb(g);
b = ::toXenonSrgb(b);
const uint count = img->pixelCount();
for (uint c = 0; c < 3; c++) {
float * channel = img->channel(c);
for (uint i = 0; i < count; i++) {
channel[i] = ::toXenonSrgb(channel[i]);
}
}
}
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 (isNull()) return;
detach();
@ -1000,7 +1023,7 @@ void Surface::transform(const float w0[4], const float w1[4], const float w2[4],
void Surface::swizzle(int r, int g, int b, int a)
{
if (m->image == NULL) return;
if (isNull()) return;
if (r == 0 && g == 1 && b == 2 && a == 3) return;
detach();
@ -1011,7 +1034,7 @@ void Surface::swizzle(int r, int g, int b, int a)
// color * scale + bias
void Surface::scaleBias(int channel, float scale, float bias)
{
if (m->image == NULL) return;
if (isNull()) return;
if (equal(scale, 1.0f) && equal(bias, 0.0f)) return;
detach();
@ -1021,7 +1044,7 @@ void Surface::scaleBias(int channel, float scale, float bias)
void Surface::clamp(int channel, float low, float high)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1045,7 +1068,7 @@ void Surface::expandNormal()
void Surface::blend(float red, float green, float blue, float alpha, float t)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1067,7 +1090,7 @@ void Surface::blend(float red, float green, float blue, float alpha, float t)
void Surface::premultiplyAlpha()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1089,7 +1112,7 @@ void Surface::premultiplyAlpha()
void Surface::toGreyScale(float redScale, float greenScale, float blueScale, float alphaScale)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1116,7 +1139,7 @@ void Surface::toGreyScale(float redScale, float greenScale, float blueScale, flo
// Draw colored border.
void Surface::setBorder(float r, float g, float b, float a)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1158,7 +1181,7 @@ void Surface::setBorder(float r, float g, float b, float a)
// Fill image with the given color.
void Surface::fill(float red, float green, float blue, float alpha)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1181,7 +1204,7 @@ void Surface::fill(float red, float green, float blue, float alpha)
void Surface::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1220,7 +1243,7 @@ void Surface::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
// Once you have M quantized, you would compute the corresponding RGB and quantize that.
void Surface::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1288,7 +1311,7 @@ void Surface::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
void Surface::fromRGBM(float range/*= 1*/)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1557,7 +1580,7 @@ void Surface::fromRGBE(int mantissaBits, int exponentBits)
// Y is in the [0, 1] range, while CoCg are in the [-1, 1] range.
void Surface::toYCoCg()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1594,7 +1617,7 @@ void Surface::toYCoCg()
// and minimize bilinear interpolation artifacts.
void Surface::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
{
if (m->image == NULL || m->image->depth() != 1) return;
if (isNull() || depth() != 1) return;
detach();
@ -1652,7 +1675,7 @@ void Surface::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
void Surface::fromYCoCg()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1685,7 +1708,7 @@ void Surface::fromYCoCg()
void Surface::toLUVW(float range/*= 1.0f*/)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1720,7 +1743,7 @@ void Surface::fromLUVW(float range/*= 1.0f*/)
void Surface::abs(int channel)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1735,7 +1758,7 @@ void Surface::abs(int channel)
void Surface::convolve(int channel, int kernelSize, float * kernelData)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1746,7 +1769,7 @@ void Surface::convolve(int channel, int kernelSize, float * kernelData)
/*
void Surface::blockLuminanceScale(float scale)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1821,7 +1844,7 @@ void Surface::blockLuminanceScale(float scale)
/*
void Surface::toJPEGLS()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1844,7 +1867,7 @@ void Surface::toJPEGLS()
void Surface::fromJPEGLS()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1870,7 +1893,7 @@ void Surface::fromJPEGLS()
// If dither is true, this uses Floyd-Steinberg dithering method.
void Surface::binarize(int channel, float threshold, bool dither)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -1933,7 +1956,7 @@ void Surface::binarize(int channel, float threshold, bool dither)
// When dither is true, this uses Floyd-Steinberg dithering.
void Surface::quantize(int channel, int bits, bool exactEndPoints, bool dither)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2004,7 +2027,7 @@ void Surface::quantize(int channel, int bits, bool exactEndPoints, bool dither)
// Set normal map options.
void Surface::toNormalMap(float sm, float medium, float big, float large)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2023,7 +2046,7 @@ void Surface::toNormalMap(float sm, float medium, float big, float large)
void Surface::normalizeNormalMap()
{
if (m->image == NULL) return;
if (isNull()) return;
if (!m->isNormalMap) return;
detach();
@ -2033,7 +2056,7 @@ void Surface::normalizeNormalMap()
void Surface::transformNormals(NormalTransform xform)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2106,7 +2129,7 @@ void Surface::transformNormals(NormalTransform xform)
void Surface::reconstructNormals(NormalTransform xform)
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2155,7 +2178,7 @@ void Surface::reconstructNormals(NormalTransform xform)
void Surface::toCleanNormalMap()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2174,14 +2197,14 @@ void Surface::toCleanNormalMap()
// [-1,1] -> [ 0,1]
void Surface::packNormals() {
if (m->image == NULL) return;
if (isNull()) return;
detach();
m->image->packNormals(0);
}
// [ 0,1] -> [-1,1]
void Surface::expandNormals() {
if (m->image == NULL) return;
if (isNull()) return;
detach();
m->image->expandNormals(0);
}
@ -2189,7 +2212,7 @@ void Surface::expandNormals() {
void Surface::flipX()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2198,7 +2221,7 @@ void Surface::flipX()
void Surface::flipY()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2207,7 +2230,7 @@ void Surface::flipY()
void Surface::flipZ()
{
if (m->image == NULL) return;
if (isNull()) return;
detach();
@ -2233,6 +2256,8 @@ bool Surface::copyChannel(const Surface & srcImage, int srcChannel, int dstChann
detach();
dst = m->image;
memcpy(dst->channel(dstChannel), src->channel(srcChannel), dst->pixelCount()*sizeof(float));
return true;
@ -2252,6 +2277,8 @@ bool Surface::addChannel(const Surface & srcImage, int srcChannel, int dstChanne
detach();
dst = m->image;
const uint w = src->width();
const uint h = src->height();

View File

@ -350,6 +350,7 @@ namespace nvtt
NVTT_API void reset();
NVTT_API void setFileName(const char * fileName);
NVTT_API void setFileHandle(void * fp);
NVTT_API void setOutputHandler(OutputHandler * outputHandler);
NVTT_API void setErrorHandler(ErrorHandler * errorHandler);
@ -464,6 +465,7 @@ namespace nvtt
NVTT_API void toLinear(float gamma);
NVTT_API void toGamma(float gamma);
NVTT_API void toSrgb();
NVTT_API void toLinearFromSrgb();
NVTT_API void toXenonSrgb();
NVTT_API void transform(const float w0[4], const float w1[4], const float w2[4], const float w3[4], const float offset[4]);
NVTT_API void swizzle(int r, int g, int b, int a);
@ -564,6 +566,8 @@ namespace nvtt
// @@ Add edge fixup methods.
NVTT_API float average(int channel) const;
// Filtering.
NVTT_API CubeSurface irradianceFilter(int size) const;
NVTT_API CubeSurface cosinePowerFilter(int size, float cosinePower) const;