184 lines
6.5 KiB
Rust
184 lines
6.5 KiB
Rust
use crate::core::image::HostImage;
|
|
use crate::core::texture::{FloatTexture as HostFloatTexture, SpectrumTexture as HostSpectrumTexture};
|
|
use crate::spectra::default_colorspace;
|
|
use crate::Arena;
|
|
use shared::core::image::Image;
|
|
use shared::core::texture::{FloatTexture, SpectrumTexture};
|
|
use shared::textures::*;
|
|
use shared::Ptr;
|
|
use std::sync::Arc;
|
|
|
|
pub trait Upload {
|
|
type Target;
|
|
fn upload(self, arena: &Arena) -> Self::Target;
|
|
}
|
|
|
|
fn convert_float(tex: &HostFloatTexture, arena: &Arena) -> FloatTexture {
|
|
match tex {
|
|
HostFloatTexture::Constant(t) => FloatTexture::Constant(*t),
|
|
HostFloatTexture::Bilerp(t) => FloatTexture::Bilerp(*t),
|
|
HostFloatTexture::Checkerboard(t) => FloatTexture::Checkerboard(*t),
|
|
HostFloatTexture::Dots(t) => FloatTexture::Dots(*t),
|
|
HostFloatTexture::FBm(t) => FloatTexture::FBm(*t),
|
|
HostFloatTexture::Windy(t) => FloatTexture::Windy(*t),
|
|
HostFloatTexture::Wrinkled(t) => FloatTexture::Wrinkled(*t),
|
|
|
|
HostFloatTexture::Scaled(t) => {
|
|
let tex = arena.alloc(convert_float(t.tex.as_ref(), arena));
|
|
let scale = arena.alloc(convert_float(t.scale.as_ref(), arena));
|
|
FloatTexture::Scaled(FloatScaledTexture { tex, scale })
|
|
}
|
|
|
|
HostFloatTexture::Mix(t) => {
|
|
let tex1 = arena.alloc(convert_float(t.tex1.as_ref(), arena));
|
|
let tex2 = arena.alloc(convert_float(t.tex2.as_ref(), arena));
|
|
let amount = arena.alloc(convert_float(t.amount.as_ref(), arena));
|
|
FloatTexture::Mix(FloatMixTexture { tex1, tex2, amount })
|
|
}
|
|
|
|
HostFloatTexture::DirectionMix(t) => {
|
|
let tex1 = arena.alloc(convert_float(t.tex1.as_ref(), arena));
|
|
let tex2 = arena.alloc(convert_float(t.tex2.as_ref(), arena));
|
|
FloatTexture::DirectionMix(FloatDirectionMixTexture {
|
|
tex1,
|
|
tex2,
|
|
dir: t.dir,
|
|
})
|
|
}
|
|
|
|
HostFloatTexture::Image(t) => {
|
|
let image = arena.alloc(t.base.mipmap.base_image().inner.clone());
|
|
let tex_obj = arena.get_texture_object(&t.base.mipmap);
|
|
FloatTexture::Image(FloatImageTexture {
|
|
image,
|
|
mapping: t.base.mapping,
|
|
wrap_mode: t.base.mipmap.wrap_mode,
|
|
tex_obj,
|
|
scale: t.base.scale,
|
|
invert: t.base.invert,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
fn convert_spectrum(tex: &HostSpectrumTexture, arena: &Arena) -> SpectrumTexture {
|
|
match tex {
|
|
HostSpectrumTexture::Constant(t) => SpectrumTexture::Constant(*t),
|
|
HostSpectrumTexture::Bilerp(t) => SpectrumTexture::Bilerp(*t),
|
|
HostSpectrumTexture::Checkerboard(t) => SpectrumTexture::Checkerboard(*t),
|
|
HostSpectrumTexture::Dots(t) => SpectrumTexture::Dots(*t),
|
|
HostSpectrumTexture::Marble(t) => SpectrumTexture::Marble(*t),
|
|
|
|
HostSpectrumTexture::Scaled(t) => {
|
|
let tex = arena.alloc(convert_spectrum(t.tex.as_ref(), arena));
|
|
let scale = arena.alloc(convert_float(t.scale.as_ref(), arena));
|
|
SpectrumTexture::Scaled(SpectrumScaledTexture { tex, scale })
|
|
}
|
|
|
|
HostSpectrumTexture::Mix(t) => {
|
|
let tex1 = arena.alloc(convert_spectrum(t.tex1.as_ref(), arena));
|
|
let tex2 = arena.alloc(convert_spectrum(t.tex2.as_ref(), arena));
|
|
let amount = arena.alloc(convert_float(t.amount.as_ref(), arena));
|
|
SpectrumTexture::Mix(SpectrumMixTexture { tex1, tex2, amount })
|
|
}
|
|
|
|
HostSpectrumTexture::DirectionMix(t) => {
|
|
let tex1 = arena.alloc(convert_spectrum(t.tex1.as_ref(), arena));
|
|
let tex2 = arena.alloc(convert_spectrum(t.tex2.as_ref(), arena));
|
|
SpectrumTexture::DirectionMix(SpectrumDirectionMixTexture {
|
|
tex1,
|
|
tex2,
|
|
dir: t.dir,
|
|
})
|
|
}
|
|
|
|
HostSpectrumTexture::Image(t) => {
|
|
let image = arena.alloc(t.base.mipmap.base_image().inner.clone());
|
|
let tex_obj = arena.get_texture_object(&t.base.mipmap);
|
|
SpectrumTexture::Image(SpectrumImageTexture {
|
|
image,
|
|
tex_obj,
|
|
wrap_mode: t.base.mipmap.wrap_mode,
|
|
color_space: arena
|
|
.alloc(t.base.mipmap.color_space.unwrap_or_else(default_colorspace)),
|
|
mapping: t.base.mapping,
|
|
scale: t.base.scale,
|
|
invert: t.base.invert,
|
|
is_single_channel: t.base.mipmap.is_single_channel(),
|
|
spectrum_type: t.spectrum_type,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Upload for Arc<HostFloatTexture> {
|
|
type Target = Ptr<FloatTexture>;
|
|
fn upload(self, arena: &Arena) -> Self::Target {
|
|
arena.alloc(convert_float(&self, arena))
|
|
}
|
|
}
|
|
|
|
impl Upload for Arc<HostSpectrumTexture> {
|
|
type Target = Ptr<SpectrumTexture>;
|
|
fn upload(self, arena: &Arena) -> Self::Target {
|
|
arena.alloc(convert_spectrum(&self, arena))
|
|
}
|
|
}
|
|
|
|
impl Upload for &HostFloatTexture {
|
|
type Target = Ptr<FloatTexture>;
|
|
fn upload(self, arena: &Arena) -> Self::Target {
|
|
arena.alloc(convert_float(self, arena))
|
|
}
|
|
}
|
|
|
|
impl Upload for &HostSpectrumTexture {
|
|
type Target = Ptr<SpectrumTexture>;
|
|
fn upload(self, arena: &Arena) -> Self::Target {
|
|
arena.alloc(convert_spectrum(self, arena))
|
|
}
|
|
}
|
|
impl Upload for Option<Arc<HostFloatTexture>> {
|
|
type Target = Ptr<FloatTexture>;
|
|
fn upload(self, arena: &Arena) -> Self::Target {
|
|
arena.alloc_opt(self.map(|v| convert_float(&v, arena)))
|
|
}
|
|
}
|
|
|
|
impl Upload for Option<Arc<HostSpectrumTexture>> {
|
|
type Target = Ptr<SpectrumTexture>;
|
|
fn upload(self, arena: &Arena) -> Self::Target {
|
|
arena.alloc_opt(self.map(|v| convert_spectrum(&v, arena)))
|
|
}
|
|
}
|
|
|
|
impl Upload for HostImage {
|
|
type Target = Ptr<Image>;
|
|
fn upload(self, arena: &Arena) -> Ptr<Image> {
|
|
arena.alloc(self.inner)
|
|
}
|
|
}
|
|
|
|
impl Upload for Option<HostImage> {
|
|
type Target = Ptr<Image>;
|
|
fn upload(self, arena: &Arena) -> Ptr<Image> {
|
|
arena.alloc_opt(self.map(|h| h.inner))
|
|
}
|
|
}
|
|
|
|
impl Upload for Option<Arc<HostImage>> {
|
|
type Target = Ptr<Image>;
|
|
fn upload(self, arena: &Arena) -> Ptr<Image> {
|
|
arena.alloc_opt(self.map(|h| h.as_ref().inner.clone()))
|
|
}
|
|
}
|
|
|
|
pub trait ArenaUpload {
|
|
fn upload<T: Upload>(&self, value: T) -> T::Target;
|
|
}
|
|
|
|
impl ArenaUpload for Arena {
|
|
fn upload<T: Upload>(&self, value: T) -> T::Target {
|
|
value.upload(self)
|
|
}
|
|
}
|