Initial commit.

This commit is contained in:
hal8174 2024-04-23 10:14:24 +02:00
commit d3bb49b3f5
1073 changed files with 484757 additions and 0 deletions

View file

@ -0,0 +1,19 @@
## Copyright 2009-2021 Intel Corporation
## SPDX-License-Identifier: Apache-2.0
ADD_LIBRARY(texture STATIC
texture2d.cpp
)
TARGET_LINK_LIBRARIES(texture sys math)
SET_PROPERTY(TARGET texture PROPERTY FOLDER tutorials/common)
SET_PROPERTY(TARGET texture APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
IF (EMBREE_ISPC_SUPPORT)
ADD_ISPC_LIBRARY(texture_ispc STATIC
texture2d.ispc
)
TARGET_LINK_LIBRARIES(texture_ispc sys math)
SET_TARGET_PROPERTIES(texture_ispc PROPERTIES LINKER_LANGUAGE CXX)
SET_PROPERTY(TARGET texture_ispc PROPERTY FOLDER tutorials/common)
SET_PROPERTY(TARGET texture_ispc APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
ENDIF()

View file

@ -0,0 +1,91 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "texture.h"
namespace embree
{
bool isPowerOf2 (unsigned int x)
{
while (((x % 2) == 0) && x > 1)
x /= 2;
return (x == 1);
}
static std::map<std::string,std::shared_ptr<Texture>> texture_cache;
void Texture::clearTextureCache() {
texture_cache.clear();
}
Texture::Texture ()
: width(-1), height(-1), format(INVALID), bytesPerTexel(0), width_mask(0), height_mask(0), data(nullptr) {}
Texture::Texture(Ref<Image> img, const std::string fileName)
: width(unsigned(img->width)), height(unsigned(img->height)), format(RGBA8), bytesPerTexel(4), width_mask(0), height_mask(0), data(nullptr), fileName(fileName)
{
width_mask = isPowerOf2(width) ? width-1 : 0;
height_mask = isPowerOf2(height) ? height-1 : 0;
data = alignedUSMMalloc(4*width*height,16);
img->convertToRGBA8((unsigned char*)data);
}
Texture::Texture (unsigned width, unsigned height, const Format format, const char* in)
: width(width), height(height), format(format), bytesPerTexel(getFormatBytesPerTexel(format)), width_mask(0), height_mask(0), data(nullptr)
{
width_mask = isPowerOf2(width) ? width-1 : 0;
height_mask = isPowerOf2(height) ? height-1 : 0;
data = alignedUSMMalloc(bytesPerTexel*width*height,16);
if (in) {
for (size_t i=0; i<bytesPerTexel*width*height; i++)
((char*)data)[i] = in[i];
}
else {
memset(data,0 ,bytesPerTexel*width*height);
}
}
Texture::~Texture () {
alignedUSMFree(data);
}
const char* Texture::format_to_string(const Format format)
{
switch (format) {
case RGBA8 : return "RGBA8";
case RGB8 : return "RGB8";
case FLOAT32: return "FLOAT32";
default : THROW_RUNTIME_ERROR("invalid texture format");
}
}
Texture::Format Texture::string_to_format(const std::string& str)
{
if (str == "RGBA8") return RGBA8;
else if (str == "RGB8") return RGB8;
else if (str == "FLOAT32") return FLOAT32;
else THROW_RUNTIME_ERROR("invalid texture format string");
}
unsigned Texture::getFormatBytesPerTexel(const Format format)
{
switch (format) {
case RGBA8 : return 4;
case RGB8 : return 3;
case FLOAT32: return 4;
default : THROW_RUNTIME_ERROR("invalid texture format");
}
}
/*! read png texture from disk */
std::shared_ptr<Texture> Texture::load(const FileName& fileName)
{
if (texture_cache.find(fileName.str()) != texture_cache.end())
return texture_cache[fileName.str()];
std::shared_ptr<Texture> tex(new Texture(loadImage(fileName),fileName));
return texture_cache[fileName.str()] = tex;
}
}

View file

@ -0,0 +1,31 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
/*! This header is shared with ISPC. */
#pragma once
/*! Embree format constants for Texture creation */
typedef enum {
TEXTURE_RGBA8,
TEXTURE_SRGBA,
TEXTURE_RGBA32F,
TEXTURE_RGB8,
TEXTURE_SRGB,
TEXTURE_RGB32F,
TEXTURE_R8,
TEXTURE_R32F,
/* TODO
LogLuv,
RGBA16F
RGB16F
RGBE, // radiance hdr
compressed (RGTC, BPTC, ETC, ...)
*/
} TextureFormat;
/*! flags that can be passed to ospNewTexture2D(); can be OR'ed together */
typedef enum {
TEXTURE_SHARED_BUFFER = (1<<0),
TEXTURE_FILTER_NEAREST = (1<<1) /*!< use nearest-neighbor interpolation rather than the default bilinear interpolation */
} TextureCreationFlags;

View file

@ -0,0 +1,203 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "texture2d.h"
namespace embree {
// Low-level texel accessors
//////////////////////////////////////////////////////////////////////////////
// TODO blocking
inline Vec4f getTexel_RGBA8(const Texture2D *self, const Vec2i i)
{
assert(self);
const uint32_t c = ((const uint32_t *)self->data)[i.y*self->size.x + i.x];
const uint32_t r = c & 0xff;
const uint32_t g = (c >> 8) & 0xff;
const uint32_t b = (c >> 16) & 0xff;
const uint32_t a = c >> 24;
return Vec4f((float)r, (float)g, (float)b, (float)a)*(1.f/255.f);
}
inline Vec4f getTexel_RGB8(const Texture2D *self, const Vec2i i)
{
assert(self);
const uint8_t *texel = (const uint8_t *)self->data;
const uint32_t texelOfs = 3*(i.y*self->size.x + i.x);
const uint32_t r = texel[texelOfs];
const uint32_t g = texel[texelOfs+1];
const uint32_t b = texel[texelOfs+2];
return Vec4f(Vec3fa((float)r, (float)g, (float)b)*(1.f/255.f), 1.f);
}
inline Vec4f getTexel_R8(const Texture2D *self, const Vec2i i)
{
assert(self);
const uint8_t c = ((const uint8_t *)self->data)[i.y*self->size.x + i.x];
return Vec4f(c*(1.f/255.f), 0.0f, 0.0f, 1.f);
}
inline Vec4f getTexel_SRGBA(const Texture2D *self, const Vec2i i)
{
return srgba_to_linear(getTexel_RGBA8(self, i));
}
inline Vec4f getTexel_SRGB(const Texture2D *self, const Vec2i i)
{
return srgba_to_linear(getTexel_RGB8(self, i));
}
inline Vec4f getTexel_RGBA32F(const Texture2D *self, const Vec2i i)
{
assert(self);
return ((const Vec4f *)self->data)[i.y*self->size.x + i.x];
}
inline Vec4f getTexel_RGB32F(const Texture2D *self, const Vec2i i)
{
assert(self);
Vec3fa v = ((const Vec3fa*)self->data)[i.y*self->size.x + i.x];
return Vec4f(v, 1.f);
}
inline Vec4f getTexel_R32F(const Texture2D *self, const Vec2i i)
{
assert(self);
float v = ((const float*)self->data)[i.y*self->size.x + i.x];
return Vec4f(v, 0.f, 0.f, 1.f);
}
// Texture coordinate utilities
//////////////////////////////////////////////////////////////////////////////
inline Vec2i nearest_coords(const Texture2D *self, const Vec2f p)
{
// repeat: get remainder within [0..1] parameter space
Vec2f tc = frac(p);
tc = max(tc, Vec2f(0.0f)); // filter out inf/NaN
// scale by texture size
tc = tc * self->sizef;
// nearest
return Vec2i(tc);
}
struct BilinCoords {
Vec2i st0;
Vec2i st1;
Vec2f frac;
};
inline BilinCoords bilinear_coords(const Texture2D *self, const Vec2f p)
{
BilinCoords coords;
// repeat: get remainder within [0..1] parameter space
// lower sample shifted by half a texel
Vec2f tc = frac(p - self->halfTexel);
tc = max(tc, Vec2f(0.0f)); // filter out inf/NaN
// scale by texture size
tc = tc * self->sizef;
coords.frac = frac(tc);
coords.st0 = Vec2i(tc);
coords.st1 = coords.st0 + 1;
// handle border cases
if (coords.st1.x >= self->size.x)
coords.st1.x = 0;
if (coords.st1.y >= self->size.y)
coords.st1.y = 0;
return coords;
}
inline Vec4f bilerp(const Vec2f frac, const Vec4f c00, const Vec4f c01, const Vec4f c10, const Vec4f c11)
{
return lerpr(frac.y,
lerpr(frac.x, c00, c01),
lerpr(frac.x, c10, c11));
}
// Implementations of Texture2D_get for different formats and filter modi
//////////////////////////////////////////////////////////////////////////////
#define __define_tex_get(FMT) \
\
static Vec4f Texture2D_nearest_##FMT(const Texture2D *self, \
const Vec2f &p) \
{ \
return getTexel_##FMT(self, nearest_coords(self, p)); \
} \
\
static Vec4f Texture2D_bilinear_##FMT(const Texture2D *self, \
const Vec2f &p) \
{ \
BilinCoords cs = bilinear_coords(self, p); \
\
const Vec4f c00 = getTexel_##FMT(self, Vec2i(cs.st0.x, cs.st0.y)); \
const Vec4f c01 = getTexel_##FMT(self, Vec2i(cs.st1.x, cs.st0.y)); \
const Vec4f c10 = getTexel_##FMT(self, Vec2i(cs.st0.x, cs.st1.y)); \
const Vec4f c11 = getTexel_##FMT(self, Vec2i(cs.st1.x, cs.st1.y)); \
\
return bilerp(cs.frac, c00, c01, c10, c11); \
}
#define __define_tex_get_case(FMT) \
case TEXTURE_##FMT: return filter_nearest ? &Texture2D_nearest_##FMT : \
&Texture2D_bilinear_##FMT;
#define __foreach_fetcher(FCT) \
FCT(RGBA8) \
FCT(SRGBA) \
FCT(RGBA32F) \
FCT(RGB8) \
FCT(SRGB) \
FCT(RGB32F) \
FCT(R8) \
FCT(R32F)
__foreach_fetcher(__define_tex_get)
static Texture2D_get Texture2D_get_addr(const uint32_t type,
const bool filter_nearest)
{
switch (type) {
__foreach_fetcher(__define_tex_get_case)
}
return 0;
};
#undef __define_tex_get
#undef __define_tex_get_addr
#undef __foreach_fetcher
// Exports (called from C++)
//////////////////////////////////////////////////////////////////////////////
extern "C" void *Texture2D_create(Vec2i &size, void *data,
uint32_t type, uint32_t flags)
{
Texture2D *self = (Texture2D*) alignedUSMMalloc(sizeof(Texture2D),16);
self->size = size;
// Due to float rounding frac(x) can be exactly 1.0f (e.g. for very small
// negative x), although it should be strictly smaller than 1.0f. We handle
// this case by having sizef slightly smaller than size, such that
// frac(x)*sizef is always < size.
self->sizef = Vec2f(nextafter((float)size.x, -1.0f), nextafter((float)size.y, -1.0f));
self->halfTexel = Vec2f(0.5f/size.x, 0.5f/size.y);
self->data = data;
self->get = Texture2D_get_addr(type, flags & TEXTURE_FILTER_NEAREST);
return self;
}
} // namespace embree

View file

@ -0,0 +1,104 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "texture.h"
#include "../math/vec.h"
namespace embree {
struct Texture2D;
typedef Vec4f (*Texture2D_get)(const Texture2D *self,
const Vec2f &p);
struct Texture2D {
Vec2i size;
Vec2f sizef; // size, as floats; slightly smaller than 'size' to avoid range checks
Vec2f halfTexel; // 0.5/size, needed for bilinear filtering and clamp-to-edge
Texture2D_get get;
void *data;
};
// XXX won't work with MIPmapping: clean implementation with clamping on integer coords needed then
inline Vec2f clamp2edge(const Texture2D *self, const Vec2f p)
{
return clamp(p, self->halfTexel, 1.0f - self->halfTexel);
}
/*! helper function that returns the sampled value for the first
channel of the given texture
Right now, this function always asks the texture for all four
channels, and then discards all but one; later implementations may
have specialized 'get1f' methods with the texture
\note self may NOT be nullptr!
*/
inline float get1f(const Texture2D *self,
const Vec2f where)
{
Vec4f ret = self->get(self, where);
return ret.x;
}
/*! helper function that returns the sampled value for the first three
channels of the given texture
Right now, this function always asks the texture for all four
channels, and then discards all but one; later implementations may
have specialized 'get3f' methods with the texture
\note self may NOT be nullptr!
*/
inline Vec3fa get3f(const Texture2D *self,
const Vec2f where)
{
Vec4f ret = self->get(self, where);
return Vec3fa(ret);
}
/*! helper function that returns the sampled value of the four
channels of the given texture.
Note that it's up to the texture to define clearly what happens if
we ask for four channels even if the texture has less physical
channels.
\note self may NOT be nullptr!
*/
inline Vec4f get4f(const Texture2D *self,
const Vec2f where)
{
return self->get(self, where);
}
/*! helper function: get1f() with a default value if the texture is nullptr */
inline float get1f(const Texture2D *self,
const Vec2f where,
const float defaultValue)
{
if (self == nullptr) return defaultValue;
else return get1f(self,where);
}
/*! helper function: get3f() with a default value if the texture is nullptr */
inline Vec3fa get3f(const Texture2D *self,
const Vec2f where,
const Vec3fa& defaultValue)
{
if (self == nullptr) return defaultValue;
else return get3f(self,where);
}
/*! helper function: get4f() with a default value if the texture is nullptr */
inline Vec4f get4f(const Texture2D *self,
const Vec2f where,
const Vec4f defaultValue)
{
if (self == nullptr) return defaultValue;
else return get4f(self,where);
}
} // namespace embree

View file

@ -0,0 +1,199 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "texture2d.isph"
// Low-level texel accessors
//////////////////////////////////////////////////////////////////////////////
// TODO blocking
inline Vec4f getTexel_RGBA8(const uniform Texture2D *uniform self, const Vec2i i)
{
assert(self);
const uint32 c = ((const uniform uint32 *uniform)self->data)[i.y*self->size.x + i.x];
const uint32 r = c & 0xff;
const uint32 g = (c >> 8) & 0xff;
const uint32 b = (c >> 16) & 0xff;
const uint32 a = c >> 24;
return make_Vec4f((float)r, (float)g, (float)b, (float)a)*(1.f/255.f);
}
inline Vec4f getTexel_RGB8(const uniform Texture2D *uniform self, const Vec2i i)
{
assert(self);
const uniform uint8 *uniform texel = (const uniform uint8 *uniform)self->data;
const uint32 texelOfs = 3*(i.y*self->size.x + i.x);
const uint32 r = texel[texelOfs];
const uint32 g = texel[texelOfs+1];
const uint32 b = texel[texelOfs+2];
return make_Vec4f(make_Vec3f((float)r, (float)g, (float)b)*(1.f/255.f), 1.f);
}
inline Vec4f getTexel_R8(const uniform Texture2D *uniform self, const Vec2i i)
{
assert(self);
const uint8 c = ((const uniform uint8 *uniform)self->data)[i.y*self->size.x + i.x];
return make_Vec4f(c*(1.f/255.f), 0.0f, 0.0f, 1.f);
}
inline Vec4f getTexel_SRGBA(const uniform Texture2D *uniform self, const Vec2i i)
{
return srgba_to_linear(getTexel_RGBA8(self, i));
}
inline Vec4f getTexel_SRGB(const uniform Texture2D *uniform self, const Vec2i i)
{
return srgba_to_linear(getTexel_RGB8(self, i));
}
inline Vec4f getTexel_RGBA32F(const uniform Texture2D *uniform self, const Vec2i i)
{
assert(self);
return ((const uniform Vec4f *uniform)self->data)[i.y*self->size.x + i.x];
}
inline Vec4f getTexel_RGB32F(const uniform Texture2D *uniform self, const Vec2i i)
{
assert(self);
Vec3f v = ((const uniform Vec3f*uniform )self->data)[i.y*self->size.x + i.x];
return make_Vec4f(v, 1.f);
}
inline Vec4f getTexel_R32F(const uniform Texture2D *uniform self, const Vec2i i)
{
assert(self);
float v = ((const uniform float*uniform)self->data)[i.y*self->size.x + i.x];
return make_Vec4f(v, 0.f, 0.f, 1.f);
}
// Texture coordinate utilities
//////////////////////////////////////////////////////////////////////////////
inline Vec2i nearest_coords(const uniform Texture2D *uniform self, const Vec2f p)
{
// repeat: get remainder within [0..1] parameter space
Vec2f tc = frac(p);
tc = max(tc, make_Vec2f(0.0f)); // filter out inf/NaN
// scale by texture size
tc = tc * self->sizef;
// nearest
return make_Vec2i(tc);
}
struct BilinCoords {
Vec2i st0;
Vec2i st1;
Vec2f frac;
};
inline BilinCoords bilinear_coords(const uniform Texture2D *uniform self, const Vec2f p)
{
BilinCoords coords;
// repeat: get remainder within [0..1] parameter space
// lower sample shifted by half a texel
Vec2f tc = frac(p - self->halfTexel);
tc = max(tc, make_Vec2f(0.0f)); // filter out inf/NaN
// scale by texture size
tc = tc * self->sizef;
coords.frac = frac(tc);
coords.st0 = make_Vec2i(tc);
coords.st1 = coords.st0 + 1;
// handle border cases
if (coords.st1.x >= self->size.x)
coords.st1.x = 0;
if (coords.st1.y >= self->size.y)
coords.st1.y = 0;
return coords;
}
inline Vec4f bilerp(const Vec2f frac, const Vec4f c00, const Vec4f c01, const Vec4f c10, const Vec4f c11)
{
return lerp(frac.y,
lerp(frac.x, c00, c01),
lerp(frac.x, c10, c11));
}
// Implementations of Texture2D_get for different formats and filter modi
//////////////////////////////////////////////////////////////////////////////
#define __define_tex_get(FMT) \
\
static Vec4f Texture2D_nearest_##FMT(const uniform Texture2D *uniform self, \
const Vec2f &p) \
{ \
return getTexel_##FMT(self, nearest_coords(self, p)); \
} \
\
static Vec4f Texture2D_bilinear_##FMT(const uniform Texture2D *uniform self, \
const Vec2f &p) \
{ \
BilinCoords cs = bilinear_coords(self, p); \
\
const Vec4f c00 = getTexel_##FMT(self, make_Vec2i(cs.st0.x, cs.st0.y)); \
const Vec4f c01 = getTexel_##FMT(self, make_Vec2i(cs.st1.x, cs.st0.y)); \
const Vec4f c10 = getTexel_##FMT(self, make_Vec2i(cs.st0.x, cs.st1.y)); \
const Vec4f c11 = getTexel_##FMT(self, make_Vec2i(cs.st1.x, cs.st1.y)); \
\
return bilerp(cs.frac, c00, c01, c10, c11); \
}
#define __define_tex_get_case(FMT) \
case TEXTURE_##FMT: return filter_nearest ? &Texture2D_nearest_##FMT : \
&Texture2D_bilinear_##FMT;
#define __foreach_fetcher(FCT) \
FCT(RGBA8) \
FCT(SRGBA) \
FCT(RGBA32F) \
FCT(RGB8) \
FCT(SRGB) \
FCT(RGB32F) \
FCT(R8) \
FCT(R32F)
__foreach_fetcher(__define_tex_get)
static uniform Texture2D_get Texture2D_get_addr(const uniform uint32 type,
const uniform bool filter_nearest)
{
switch (type) {
__foreach_fetcher(__define_tex_get_case)
}
return 0;
};
#undef __define_tex_get
#undef __define_tex_get_addr
#undef __foreach_fetcher
// Exports (called from C++)
//////////////////////////////////////////////////////////////////////////////
export void *uniform Texture2D_create(uniform Vec2i &size, void *uniform data,
uniform uint32 type, uniform uint32 flags)
{
uniform Texture2D *uniform self = uniform new uniform Texture2D;
self->size = size;
// Due to float rounding frac(x) can be exactly 1.0f (e.g. for very small
// negative x), although it should be strictly smaller than 1.0f. We handle
// this case by having sizef slightly smaller than size, such that
// frac(x)*sizef is always < size.
self->sizef = make_Vec2f(nextafter((float)size.x, -1.0f), nextafter((float)size.y, -1.0f));
self->halfTexel = make_Vec2f(0.5f/size.x, 0.5f/size.y);
self->data = data;
self->get = Texture2D_get_addr(type, flags & TEXTURE_FILTER_NEAREST);
return self;
}

View file

@ -0,0 +1,100 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "texture.h"
#include "../math/vec.isph"
struct Texture2D;
typedef varying Vec4f (*Texture2D_get)(const uniform Texture2D *uniform self,
const varying Vec2f &p);
struct Texture2D {
Vec2i size;
Vec2f sizef; // size, as floats; slightly smaller than 'size' to avoid range checks
Vec2f halfTexel; // 0.5/size, needed for bilinear filtering and clamp-to-edge
Texture2D_get get;
void *data;
};
// XXX won't work with MIPmapping: clean implementation with clamping on integer coords needed then
inline Vec2f clamp2edge(const uniform Texture2D *uniform self, const Vec2f p)
{
return clamp(p, self->halfTexel, 1.0f - self->halfTexel);
}
/*! helper function that returns the sampled value for the first
channel of the given texture
Right now, this function always asks the texture for all four
channels, and then discards all but one; later implementations may
have specialized 'get1f' methods with the texture
\note self may NOT be NULL!
*/
inline float get1f(const uniform Texture2D *uniform self,
const varying Vec2f where)
{
Vec4f ret = self->get(self, where);
return ret.x;
}
/*! helper function that returns the sampled value for the first three
channels of the given texture
Right now, this function always asks the texture for all four
channels, and then discards all but one; later implementations may
have specialized 'get3f' methods with the texture
\note self may NOT be NULL!
*/
inline Vec3f get3f(const uniform Texture2D *uniform self,
const varying Vec2f where)
{
Vec4f ret = self->get(self, where);
return make_Vec3f(ret);
}
/*! helper function that returns the sampled value of the four
channels of the given texture.
Note that it's up to the texture to define clearly what happens if
we ask for four channels even if the texture has less physical
channels.
\note self may NOT be NULL!
*/
inline Vec4f get4f(const uniform Texture2D *uniform self,
const varying Vec2f where)
{
return self->get(self, where);
}
/*! helper function: get1f() with a default value if the texture is NULL */
inline float get1f(const uniform Texture2D *uniform self,
const varying Vec2f where,
const varying float defaultValue)
{
if (self == NULL) return defaultValue;
else return get1f(self,where);
}
/*! helper function: get3f() with a default value if the texture is NULL */
inline Vec3f get3f(const uniform Texture2D *uniform self,
const varying Vec2f where,
const varying Vec3f defaultValue)
{
if (self == NULL) return defaultValue;
else return get3f(self,where);
}
/*! helper function: get4f() with a default value if the texture is NULL */
inline Vec4f get4f(const uniform Texture2D *uniform self,
const varying Vec2f where,
const varying Vec4f defaultValue)
{
if (self == NULL) return defaultValue;
else return get4f(self,where);
}

View file

@ -0,0 +1,79 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "texture2d.h"
#include "ospray/math/AffineSpace.ih"
namespace embree {
//! Texture2D including coordinate transformation, plus helpers
struct TextureParam
{
Texture2D* map;
affine2f xform;
};
inline TextureParam make_TextureParam(Texture2D * tex, const affine2f &xform)
{
TextureParam t;
t.map = tex;
t.xform = xform;
return t;
}
inline bool valid(const TextureParam &tex)
{
return tex.map;
}
inline float get1f(const TextureParam &tex,
const Vec2f uv)
{
return get1f(tex.map, tex.xform * uv);
}
inline float get1f(const TextureParam &tex,
const Vec2f uv,
const float defaultValue)
{
if (tex.map == nullptr)
return defaultValue;
return get1f(tex.map, tex.xform * uv);
}
inline Vec3fa get3f(const TextureParam &tex,
const Vec2f uv)
{
return get3f(tex.map, tex.xform * uv);
}
inline Vec3fa get3f(const TextureParam &tex,
const Vec2f uv,
const Vec3fa& defaultValue)
{
if (tex.map == nullptr)
return defaultValue;
return get3f(tex.map, tex.xform * uv);
}
inline Vec4f get4f(const TextureParam &tex,
const Vec2f uv)
{
return get4f(tex.map, tex.xform * uv);
}
inline Vec4f get4f(const TextureParam &tex,
const Vec2f uv,
const Vec4f defaultValue)
{
if (tex.map == nullptr)
return defaultValue;
return get4f(tex.map, tex.xform * uv);
}
} // namespace embree

View file

@ -0,0 +1,75 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "texture2d.isph"
#include "ospray/math/AffineSpace.ih"
//! Texture2D including coordinate transformation, plus helpers
struct TextureParam
{
uniform Texture2D* map;
affine2f xform;
};
inline uniform TextureParam make_TextureParam(uniform Texture2D * uniform tex, const uniform affine2f &xform)
{
uniform TextureParam t;
t.map = tex;
t.xform = xform;
return t;
}
inline bool valid(const uniform TextureParam uniform &tex)
{
return tex.map;
}
inline float get1f(const uniform TextureParam uniform &tex,
const varying Vec2f uv)
{
return get1f(tex.map, tex.xform * uv);
}
inline float get1f(const uniform TextureParam uniform &tex,
const varying Vec2f uv,
const varying float defaultValue)
{
if (tex.map == NULL)
return defaultValue;
return get1f(tex.map, tex.xform * uv);
}
inline Vec3f get3f(const uniform TextureParam uniform &tex,
const varying Vec2f uv)
{
return get3f(tex.map, tex.xform * uv);
}
inline Vec3f get3f(const uniform TextureParam uniform &tex,
const varying Vec2f uv,
const varying Vec3f defaultValue)
{
if (tex.map == NULL)
return defaultValue;
return get3f(tex.map, tex.xform * uv);
}
inline Vec4f get4f(const uniform TextureParam uniform &tex,
const varying Vec2f uv)
{
return get4f(tex.map, tex.xform * uv);
}
inline Vec4f get4f(const uniform TextureParam uniform &tex,
const varying Vec2f uv,
const varying Vec4f defaultValue)
{
if (tex.map == NULL)
return defaultValue;
return get4f(tex.map, tex.xform * uv);
}