cubemap support, work in progress.

pull/216/head
castano 13 years ago
parent 0b05255f90
commit 86b43e55c1

@ -24,12 +24,11 @@ SET(NVTT_SRCS
OutputOptions.h OutputOptions.cpp
TaskDispatcher.h TaskDispatcher.cpp
TexImage.h TexImage.cpp
cuda/CudaUtils.h
cuda/CudaUtils.cpp
CubeImage.h CubeImage.cpp
cuda/CudaUtils.h cuda/CudaUtils.cpp
cuda/CudaMath.h
cuda/BitmapTable.h
cuda/CudaCompressorDXT.h
cuda/CudaCompressorDXT.cpp)
cuda/CudaCompressorDXT.h cuda/CudaCompressorDXT.cpp)
IF (CUDA_FOUND)
ADD_DEFINITIONS(-DHAVE_CUDA)

@ -0,0 +1,126 @@
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#include "CubeImage.h"
using namespace nv;
using namespace nvtt;
CubeImage::CubeImage() : m(new CubeImage::Private())
{
m->addRef();
}
CubeImage::CubeImage(const CubeImage & cube) : m(cube.m)
{
if (m != NULL) m->addRef();
}
CubeImage::~CubeImage()
{
if (m != NULL) m->release();
m = NULL;
}
void CubeImage::operator=(const CubeImage & cube)
{
if (cube.m != NULL) cube.m->addRef();
if (m != NULL) m->release();
m = cube.m;
}
void CubeImage::detach()
{
if (m->refCount() > 1)
{
m->release();
m = new CubeImage::Private(*m);
m->addRef();
nvDebugCheck(m->refCount() == 1);
}
}
bool CubeImage::isNull() const
{
return m->size == 0;
}
int CubeImage::size() const
{
return m->size;
}
int CubeImage::countMipmaps() const
{
return nv::countMipmaps(m->size);
}
TexImage & CubeImage::face(int f)
{
nvDebugCheck(f >= 0 && f < 6);
return m->face[f];
}
bool CubeImage::load(const char * fileName)
{
return false;
}
bool CubeImage::save(const char * fileName) const
{
return false;
}
void CubeImage::fold(const TexImage & tex, CubeLayout layout)
{
}
TexImage CubeImage::unfold(CubeLayout layout)
{
}
void CubeImage::toLinear(float gamma)
{
for (int i = 0; i < 6; i++) {
m->face.toLinear(gamma);
}
}
void CubeImage::toGamma(float gamma)
{
for (int i = 0; i < 6; i++) {
m->face.toGamma(gamma);
}
}

@ -0,0 +1,66 @@
// Copyright (c) 2009-2011 Ignacio Castano <castano@gmail.com>
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#ifndef NVTT_CUBEIMAGE_H
#define NVTT_CUBEIMAGE_H
#include "nvtt.h"
#include "nvcore/RefCounted.h"
#include "nvcore/Ptr.h"
namespace nvtt
{
struct CubeImage::Private : public nv::RefCounted
{
void operator=(const Private &);
public:
Private()
{
nvDebugCheck( refCount() == 0 );
size = 0;
}
Private(const Private & p) : RefCounted() // Copy ctor. inits refcount to 0.
{
nvDebugCheck( refCount() == 0 );
size = p.size;
for (uint i = 0; i < 6; i++) {
face[i] = p.face[6];
}
}
~Private()
{
}
int size;
TexImage face[6];
};
} // nvtt namespace
#endif // NVTT_CUBEIMAGE_H

@ -55,14 +55,14 @@ namespace
const uint np2 = nextPowerOfTwo(v);
const uint pp2 = previousPowerOfTwo(v);
if (np2 - v <= v - pp2)
{
return np2;
}
else
{
return pp2;
}
if (np2 - v <= v - pp2)
{
return np2;
}
else
{
return pp2;
}
}
static int blockSize(Format format)
@ -95,6 +95,18 @@ namespace
}
}
uint nv::countMipmaps(uint w)
{
uint mipmap = 0;
while (w != 1) {
w = max(1U, w / 2);
mipmap++;
}
return mipmap + 1;
}
uint nv::countMipmaps(uint w, uint h, uint d)
{
uint mipmap = 0;
@ -115,9 +127,7 @@ uint nv::computeImageSize(uint w, uint h, uint d, uint bitCount, uint pitchAlign
return d * h * computeBytePitch(w, bitCount, pitchAlignmentInBytes);
}
else {
nvDebugCheck(d == 1);
// @@ Handle 3D textures. DXT and VTC have different behaviors.
return ((w + 3) / 4) * ((h + 3) / 4) * blockSize(format);
return ((w + 3) / 4) * ((h + 3) / 4) * blockSize(format) * d;
}
}
@ -1118,6 +1128,8 @@ void TexImage::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
detach();
//threshold = clamp(threshold, 1e-6f, 1.0f);
threshold = 1e-6f;
float irange = 1.0f / range;
FloatImage * img = m->image;
@ -1131,13 +1143,51 @@ void TexImage::toRGBM(float range/*= 1*/, float threshold/*= 0.25*/)
float R = nv::clamp(r[i] * irange, 0.0f, 1.0f);
float G = nv::clamp(g[i] * irange, 0.0f, 1.0f);
float B = nv::clamp(b[i] * irange, 0.0f, 1.0f);
float M = max(max(R, G), max(B, 1e-6f)); // Avoid division by zero.
#if 1
float M = max(max(R, G), max(B, threshold));
r[i] = R / M;
g[i] = G / M;
b[i] = B / M;
a[i] = M;
#else
// The optimal compressor theoretically produces the best results, but unfortunately introduces
// severe interpolation errors!
float bestM;
float bestError = FLT_MAX;
int minM = iround(min(R, G, B) * 255.0f);
for (int m = minM; m < 256; m++) {
float fm = float(m) / 255.0f;
// Encode.
int ir = iround(255.0f * nv::clamp(R / fm, 0.0f, 1.0f));
int ig = iround(255.0f * nv::clamp(G / fm, 0.0f, 1.0f));
int ib = iround(255.0f * nv::clamp(B / fm, 0.0f, 1.0f));
// Decode.
float fr = (float(ir) / 255.0f) * fm;
float fg = (float(ig) / 255.0f) * fm;
float fb = (float(ib) / 255.0f) * fm;
// Measure error.
float error = square(R-fr) + square(G-fg) + square(B-fb);
if (error < bestError) {
bestError = error;
bestM = fm;
}
}
M = bestM;
r[i] = nv::clamp(R / M, 0.0f, 1.0f);
g[i] = nv::clamp(G / M, 0.0f, 1.0f);
b[i] = nv::clamp(B / M, 0.0f, 1.0f);
a[i] = M;
#endif
}
}

@ -78,6 +78,7 @@ namespace nvtt
} // nvtt namespace
namespace nv {
uint countMipmaps(uint w);
uint countMipmaps(uint w, uint h, uint d);
uint computeImageSize(uint w, uint h, uint d, uint bitCount, uint alignmentInBytes, nvtt::Format format);
void getTargetExtent(int & w, int & h, int & d, int maxExtent, nvtt::RoundMode roundMode, nvtt::TextureType textureType);

@ -507,7 +507,15 @@ namespace nvtt
};
/// A texture mipmap.
enum CubeLayout {
CubeLayout_VerticalCross,
CubeLayout_HorizontalCross,
CubeLayout_Column,
CubeLayout_Row,
CubeLayout_LatitudeLongitude,
};
/// A cubemap mipmap.
struct CubeImage
{
NVTT_API CubeImage();
@ -520,20 +528,24 @@ namespace nvtt
NVTT_API bool isNull() const;
NVTT_API int size() const;
NVTT_API int countMipmaps() const;
NVTT_API float average(int channel, int alpha_channel = -1, float gamma = 2.2f) const;
// Texture data.
NVTT_API bool load(const char * fileName);
NVTT_API bool save(const char * fileName) const;
NVTT_API bool setImage2D(InputFormat format, int face, int w, int h, const void * data);
NVTT_API bool setImage2D(InputFormat format, int face, int w, int h, const void * r, const void * g, const void * b, const void * a);
NVTT_API bool setImage2D(Format format, Decoder decoder, int face, int w, int h, const void * data);
TexImage & face(int face);
//
// Layout conversion.
void fold(TexImage & img, CubeLayout layout);
TexImage unfold(CubeLayout layout);
// @@ Angular extent filtering.
// @@ Add resizing methods.
// @@ Irradiance cubemaps.
CubeImage irradiance(int size);
/*
NVTT_API void resize(int w, int h, ResizeFilter filter);
NVTT_API void resize(int w, int h, ResizeFilter filter, float filterWidth, const float * params = 0);

Loading…
Cancel
Save