Merge changes from the witness.
This commit is contained in:
@ -453,7 +453,7 @@ namespace
|
||||
{
|
||||
MSG msg;
|
||||
while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
|
||||
if( msg.message == WM_QUIT ) break;
|
||||
//if( msg.message == WM_QUIT ) break;
|
||||
TranslateMessage( &msg );
|
||||
DispatchMessage( &msg );
|
||||
}
|
||||
@ -467,12 +467,11 @@ namespace
|
||||
StringBuilder error_string;
|
||||
if( func != NULL ) {
|
||||
error_string.format( "*** Assertion failed: %s\n On file: %s\n On function: %s\n On line: %d\n ", exp, file, func, line );
|
||||
nvDebug( error_string.str() );
|
||||
}
|
||||
else {
|
||||
error_string.format( "*** Assertion failed: %s\n On file: %s\n On line: %d\n ", exp, file, line );
|
||||
nvDebug( error_string.str() );
|
||||
}
|
||||
nvDebug( error_string.str() );
|
||||
|
||||
if (debug::isDebuggerPresent()) {
|
||||
return NV_ABORT_DEBUG;
|
||||
|
@ -70,15 +70,11 @@ namespace nv
|
||||
b = temp;
|
||||
}
|
||||
|
||||
/// Return the maximum of the two arguments.
|
||||
/// Return the maximum of the two arguments. For floating point values, it returns the second value if the first is NaN.
|
||||
template <typename T>
|
||||
inline const T & max(const T & a, const T & b)
|
||||
{
|
||||
//return std::max(a, b);
|
||||
if( a < b ) {
|
||||
return b;
|
||||
}
|
||||
return a;
|
||||
return (b < a) ? a : b;
|
||||
}
|
||||
|
||||
/// Return the maximum of the three arguments.
|
||||
@ -92,11 +88,7 @@ namespace nv
|
||||
template <typename T>
|
||||
inline const T & min(const T & a, const T & b)
|
||||
{
|
||||
//return std::min(a, b);
|
||||
if( b < a ) {
|
||||
return b;
|
||||
}
|
||||
return a;
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
/// Return the maximum of the three arguments.
|
||||
|
@ -235,7 +235,7 @@ namespace nv
|
||||
nvDebugCheck(x < m_width);
|
||||
nvDebugCheck(y < m_height);
|
||||
nvDebugCheck(z < m_depth);
|
||||
return m_mem[((c * m_depth + z) * m_height + y) * m_width + x];
|
||||
return m_mem[c * m_pixelCount + index(x, y, z)];
|
||||
}
|
||||
|
||||
/// Get pixel component.
|
||||
@ -246,7 +246,7 @@ namespace nv
|
||||
nvDebugCheck(x < m_width);
|
||||
nvDebugCheck(y < m_height);
|
||||
nvDebugCheck(z < m_depth);
|
||||
return m_mem[((c * m_depth + z) * m_height + y) * m_width + x];
|
||||
return m_mem[c * m_pixelCount + index(x, y, z)];
|
||||
}
|
||||
|
||||
/// Get pixel component.
|
||||
@ -255,7 +255,7 @@ namespace nv
|
||||
nvDebugCheck(m_mem != NULL);
|
||||
nvDebugCheck(c < m_componentCount);
|
||||
nvDebugCheck(idx < m_pixelCount);
|
||||
return m_mem[c * m_height * m_width + idx];
|
||||
return m_mem[c * m_pixelCount + idx];
|
||||
}
|
||||
|
||||
/// Get pixel component.
|
||||
@ -264,7 +264,7 @@ namespace nv
|
||||
nvDebugCheck(m_mem != NULL);
|
||||
nvDebugCheck(c < m_componentCount);
|
||||
nvDebugCheck(idx < m_pixelCount);
|
||||
return m_mem[c * m_height * m_width + idx];
|
||||
return m_mem[c * m_pixelCount + idx];
|
||||
}
|
||||
|
||||
/// Get pixel component.
|
||||
@ -288,7 +288,9 @@ namespace nv
|
||||
nvDebugCheck(x < m_width);
|
||||
nvDebugCheck(y < m_height);
|
||||
nvDebugCheck(z < m_depth);
|
||||
return (z * m_height + y) * m_width + x;
|
||||
uint idx = (z * m_height + y) * m_width + x;
|
||||
nvDebugCheck(idx < m_pixelCount);
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "Image.h"
|
||||
|
||||
#include "nvmath/Color.inl"
|
||||
#include "nvmath/Vector.h"
|
||||
|
||||
#include "nvcore/Ptr.h"
|
||||
|
||||
|
@ -381,14 +381,14 @@ namespace nv
|
||||
return Vector2(max(a.x, b.x), max(a.y, b.y));
|
||||
}
|
||||
|
||||
inline bool isValid(Vector2::Arg v)
|
||||
inline bool isFinite(Vector2::Arg v)
|
||||
{
|
||||
return isFinite(v.x) && isFinite(v.y);
|
||||
}
|
||||
|
||||
inline Vector2 validate(Vector2::Arg v, Vector2::Arg fallback = Vector2(0.0f))
|
||||
{
|
||||
if (!isValid(v)) return fallback;
|
||||
if (!isFinite(v)) return fallback;
|
||||
Vector2 vf = v;
|
||||
nv::floatCleanup(vf.component, 2);
|
||||
return vf;
|
||||
@ -567,14 +567,14 @@ namespace nv
|
||||
return Vector3(ceilf(v.x), ceilf(v.y), ceilf(v.z));
|
||||
}
|
||||
|
||||
inline bool isValid(Vector3::Arg v)
|
||||
inline bool isFinite(Vector3::Arg v)
|
||||
{
|
||||
return isFinite(v.x) && isFinite(v.y) && isFinite(v.z);
|
||||
}
|
||||
|
||||
inline Vector3 validate(Vector3::Arg v, Vector3::Arg fallback = Vector3(0.0f))
|
||||
{
|
||||
if (!isValid(v)) return fallback;
|
||||
if (!isFinite(v)) return fallback;
|
||||
Vector3 vf = v;
|
||||
nv::floatCleanup(vf.component, 3);
|
||||
return vf;
|
||||
@ -699,14 +699,14 @@ namespace nv
|
||||
return Vector4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
|
||||
}
|
||||
|
||||
inline bool isValid(Vector4::Arg v)
|
||||
inline bool isFinite(Vector4::Arg v)
|
||||
{
|
||||
return isFinite(v.x) && isFinite(v.y) && isFinite(v.z) && isFinite(v.w);
|
||||
}
|
||||
|
||||
inline Vector4 validate(Vector4::Arg v, Vector4::Arg fallback = Vector4(0.0f))
|
||||
{
|
||||
if (!isValid(v)) return fallback;
|
||||
if (!isFinite(v)) return fallback;
|
||||
Vector4 vf = v;
|
||||
nv::floatCleanup(vf.component, 4);
|
||||
return vf;
|
||||
|
@ -5,14 +5,13 @@
|
||||
#define NV_MATH_H
|
||||
|
||||
#include "nvcore/nvcore.h"
|
||||
#include "nvcore/Debug.h"
|
||||
#include "nvcore/Debug.h" // nvDebugCheck
|
||||
#include "nvcore/Utils.h" // clamp
|
||||
|
||||
#include <math.h>
|
||||
#include <limits.h> // INT_MAX
|
||||
|
||||
#if NV_OS_WIN32 || NV_OS_XBOX
|
||||
#include <float.h>
|
||||
#include <float.h> // finite, isnan
|
||||
#endif
|
||||
|
||||
// Function linkage
|
||||
@ -105,9 +104,12 @@ namespace nv
|
||||
inline float toRadian(float degree) { return degree * (PI / 180.0f); }
|
||||
inline float toDegree(float radian) { return radian * (180.0f / PI); }
|
||||
|
||||
// Robust floating point comparisons:
|
||||
// http://realtimecollisiondetection.net/blog/?p=89
|
||||
inline bool equal(const float f0, const float f1, const float epsilon = NV_EPSILON)
|
||||
{
|
||||
return fabs(f0-f1) <= epsilon;
|
||||
//return fabs(f0-f1) <= epsilon;
|
||||
return fabs(f0-f1) <= epsilon * max(1.0f, fabs(f0), fabs(f1));
|
||||
}
|
||||
|
||||
inline bool isZero(const float f, const float epsilon = NV_EPSILON)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user