mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2025-01-23 20:46:37 +00:00
Sprout.Darkroom 外部ファイルからテクスチャ読み込み機能を追加
texture_map クラス追加
This commit is contained in:
parent
c0309c22ed
commit
6f2be58007
7 changed files with 368 additions and 11 deletions
|
@ -14,5 +14,6 @@
|
||||||
#include <sprout/darkroom/renderers.hpp>
|
#include <sprout/darkroom/renderers.hpp>
|
||||||
#include <sprout/darkroom/tracers.hpp>
|
#include <sprout/darkroom/tracers.hpp>
|
||||||
#include <sprout/darkroom/pixels.hpp>
|
#include <sprout/darkroom/pixels.hpp>
|
||||||
|
#include <sprout/darkroom/textures.hpp>
|
||||||
|
|
||||||
#endif // #ifndef SPROUT_DARKROOM_HPP
|
#endif // #ifndef SPROUT_DARKROOM_HPP
|
||||||
|
|
50
sprout/darkroom/load/texture.hpp
Normal file
50
sprout/darkroom/load/texture.hpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
|
||||||
|
#ifndef DARKROOM_DEF_LOAD_TEXTURE_IDENTIFIER
|
||||||
|
# error should define DARKROOM_DEF_LOAD_TEXTURE_IDENTIFIER.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DARKROOM_DEF_LOAD_TEXTURE_FILE
|
||||||
|
# error should define DARKROOM_DEF_LOAD_TEXTURE_FILE.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DARKROOM_LOAD_IDENTIFIER_DETAIL_CAT(id, suffix) DARKROOM_LOAD_IDENTIFIER_DETAIL_CAT_I(id, suffix)
|
||||||
|
#define DARKROOM_LOAD_IDENTIFIER_DETAIL_CAT_I(id, suffix) DARKROOM_LOAD_IDENTIFIER_DETAIL_CAT_II(id ## suffix)
|
||||||
|
#define DARKROOM_LOAD_IDENTIFIER_DETAIL_CAT_II(res) res
|
||||||
|
|
||||||
|
#define DARKROOM_LOAD_IDENTIFIER DARKROOM_DEF_LOAD_TEXTURE_IDENTIFIER
|
||||||
|
#define DARKROOM_LOAD_DETAIL_IDENTIFIER(id) DARKROOM_LOAD_IDENTIFIER_DETAIL_CAT( \
|
||||||
|
DARKROOM_LOAD_IDENTIFIER_DETAIL_CAT(DARKROOM_DEF_LOAD_TEXTURE_IDENTIFIER, id), \
|
||||||
|
_darkroom_load_texture_detail \
|
||||||
|
)
|
||||||
|
|
||||||
|
SPROUT_STATIC_CONSTEXPR sprout::darkroom::textures::version_type DARKROOM_LOAD_DETAIL_IDENTIFIER(version) =
|
||||||
|
# define DARKROOM_LOADING_TEXTURE_VERSION
|
||||||
|
# include DARKROOM_DEF_LOAD_TEXTURE_FILE
|
||||||
|
# undef DARKROOM_LOADING_TEXTURE_VERSION
|
||||||
|
;
|
||||||
|
SPROUT_STATIC_CONSTEXPR sprout::darkroom::textures::info_type DARKROOM_LOAD_DETAIL_IDENTIFIER(info) = {
|
||||||
|
# define DARKROOM_LOADING_TEXTURE_INFO
|
||||||
|
# include DARKROOM_DEF_LOAD_TEXTURE_FILE
|
||||||
|
# undef DARKROOM_LOADING_TEXTURE_INFO
|
||||||
|
};
|
||||||
|
|
||||||
|
SPROUT_STATIC_CONSTEXPR sprout::darkroom::textures::image_type<
|
||||||
|
DARKROOM_LOAD_DETAIL_IDENTIFIER(info).width,
|
||||||
|
DARKROOM_LOAD_DETAIL_IDENTIFIER(info).height
|
||||||
|
> DARKROOM_LOAD_IDENTIFIER(
|
||||||
|
DARKROOM_LOAD_DETAIL_IDENTIFIER(info).image_format,
|
||||||
|
DARKROOM_LOAD_DETAIL_IDENTIFIER(info).pixel_format,
|
||||||
|
# define DARKROOM_LOADING_TEXTURE_PIXEL
|
||||||
|
# include DARKROOM_DEF_LOAD_TEXTURE_FILE
|
||||||
|
# undef DARKROOM_LOADING_TEXTURE_PIXEL
|
||||||
|
);
|
||||||
|
|
||||||
|
#undef DARKROOM_LOAD_IDENTIFIER
|
||||||
|
#undef DARKROOM_LOAD_DETAIL_IDENTIFIER
|
||||||
|
|
||||||
|
#undef DARKROOM_LOAD_IDENTIFIER_DETAIL_CAT
|
||||||
|
#undef DARKROOM_LOAD_IDENTIFIER_DETAIL_CAT_I
|
||||||
|
#undef DARKROOM_LOAD_IDENTIFIER_DETAIL_CAT_II
|
||||||
|
|
||||||
|
#undef DARKROOM_DEF_LOAD_TEXTURE_IDENTIFIER
|
||||||
|
#undef DARKROOM_DEF_LOAD_TEXTURE_FILE
|
|
@ -5,5 +5,6 @@
|
||||||
#include <sprout/darkroom/materials/material.hpp>
|
#include <sprout/darkroom/materials/material.hpp>
|
||||||
#include <sprout/darkroom/materials/uniform.hpp>
|
#include <sprout/darkroom/materials/uniform.hpp>
|
||||||
#include <sprout/darkroom/materials/plaid.hpp>
|
#include <sprout/darkroom/materials/plaid.hpp>
|
||||||
|
#include <sprout/darkroom/materials/texture_map.hpp>
|
||||||
|
|
||||||
#endif // #ifndef SPROUT_DARKROOM_MATERIALS_HPP
|
#endif // #ifndef SPROUT_DARKROOM_MATERIALS_HPP
|
||||||
|
|
202
sprout/darkroom/materials/texture_map.hpp
Normal file
202
sprout/darkroom/materials/texture_map.hpp
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
#ifndef SPROUT_DARKROOM_MATERIALS_TEXTURE_MAP_HPP
|
||||||
|
#define SPROUT_DARKROOM_MATERIALS_TEXTURE_MAP_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cmath>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/utility/value_holder.hpp>
|
||||||
|
#include <sprout/darkroom/colors/rgb.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace darkroom {
|
||||||
|
namespace materials {
|
||||||
|
//
|
||||||
|
// texture_map_interpolation
|
||||||
|
//
|
||||||
|
struct texture_map_interpolation {
|
||||||
|
public:
|
||||||
|
enum values {
|
||||||
|
nearest_neighbor,
|
||||||
|
bilinear,
|
||||||
|
bicubic
|
||||||
|
};
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// texture_map_placement
|
||||||
|
//
|
||||||
|
struct texture_map_placement {
|
||||||
|
public:
|
||||||
|
enum values {
|
||||||
|
tile,
|
||||||
|
once
|
||||||
|
};
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// texture_map
|
||||||
|
//
|
||||||
|
template<typename Texture, typename Scale = double>
|
||||||
|
class texture_map {
|
||||||
|
public:
|
||||||
|
typedef Texture texture_type;
|
||||||
|
typedef typename texture_type::value_type result_type;
|
||||||
|
typedef Scale unit_type;
|
||||||
|
typedef sprout::darkroom::materials::texture_map_interpolation texture_map_interpolation;
|
||||||
|
typedef sprout::darkroom::materials::texture_map_placement texture_map_placement;
|
||||||
|
private:
|
||||||
|
static SPROUT_CONSTEXPR unit_type fmod(unit_type const& n, unit_type const& d) {
|
||||||
|
return n - std::intmax_t(n / d) * d;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
sprout::value_holder<texture_type const&> texture_;
|
||||||
|
unit_type scale_;
|
||||||
|
unit_type offset_u_;
|
||||||
|
unit_type offset_v_;
|
||||||
|
result_type default_color_;
|
||||||
|
texture_map_interpolation::values interpolation_value_;
|
||||||
|
texture_map_placement::values placement_value_;
|
||||||
|
private:
|
||||||
|
SPROUT_CONSTEXPR bool is_nearest() const {
|
||||||
|
return interpolation_value_ == texture_map_interpolation::nearest_neighbor;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR bool is_bilinear() const {
|
||||||
|
return interpolation_value_ == texture_map_interpolation::bilinear;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR bool is_bicubic() const {
|
||||||
|
return interpolation_value_ == texture_map_interpolation::bicubic;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR bool is_tile() const {
|
||||||
|
return placement_value_ == texture_map_placement::tile;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR bool is_once() const {
|
||||||
|
return placement_value_ == texture_map_placement::once;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR result_type get_color(unit_type const& x, unit_type const& y) const {
|
||||||
|
return is_tile()
|
||||||
|
? texture_.get()(
|
||||||
|
x < 0
|
||||||
|
? texture_.get().width() - 1 - static_cast<std::size_t>(-x) % texture_.get().width()
|
||||||
|
: static_cast<std::size_t>(x) % texture_.get().width()
|
||||||
|
,
|
||||||
|
y < 0
|
||||||
|
? texture_.get().height() - 1 - static_cast<std::size_t>(-y) % texture_.get().height()
|
||||||
|
: static_cast<std::size_t>(y) % texture_.get().height()
|
||||||
|
)
|
||||||
|
: x < 0 || x >= texture_.get().width()
|
||||||
|
|| y < 0 || y >= texture_.get().height()
|
||||||
|
? default_color_
|
||||||
|
: texture_.get()(static_cast<std::size_t>(x), static_cast<std::size_t>(y))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
template<typename Unit>
|
||||||
|
SPROUT_CONSTEXPR result_type calc_nearest(Unit const& x, Unit const& y) const {
|
||||||
|
return get_color(x, y);
|
||||||
|
}
|
||||||
|
template<typename Unit>
|
||||||
|
SPROUT_CONSTEXPR result_type calc_bilinear_1(
|
||||||
|
Unit const& x,
|
||||||
|
Unit const& xf,
|
||||||
|
Unit const& xc,
|
||||||
|
Unit const& y,
|
||||||
|
Unit const& yf,
|
||||||
|
Unit const& yc
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sprout::darkroom::colors::add(
|
||||||
|
sprout::darkroom::colors::mul(
|
||||||
|
sprout::darkroom::colors::add(
|
||||||
|
sprout::darkroom::colors::mul(get_color(xf, yf), 1 - (x - xf)),
|
||||||
|
sprout::darkroom::colors::mul(get_color(xc, yf), 1 - (xc - x))
|
||||||
|
),
|
||||||
|
1 - (y - yf)
|
||||||
|
),
|
||||||
|
sprout::darkroom::colors::mul(
|
||||||
|
sprout::darkroom::colors::add(
|
||||||
|
sprout::darkroom::colors::mul(get_color(xf, yc), 1 - (x - xf)),
|
||||||
|
sprout::darkroom::colors::mul(get_color(xc, yc), 1 - (xc - x))
|
||||||
|
),
|
||||||
|
1 - (yc - y)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
template<typename Unit>
|
||||||
|
SPROUT_CONSTEXPR result_type calc_bilinear(Unit const& x, Unit const& y) const {
|
||||||
|
using std::floor;
|
||||||
|
return calc_bilinear_1(x, floor(x - 0.5), floor(x + 0.5), y, floor(y - 0.5), floor(y + 0.5));
|
||||||
|
}
|
||||||
|
template<typename Unit>
|
||||||
|
SPROUT_CONSTEXPR result_type calc(Unit const& x, Unit const& y) const {
|
||||||
|
return is_nearest() ? calc_nearest(x, y)
|
||||||
|
: calc_bilinear(x, y)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
SPROUT_CONSTEXPR explicit texture_map(
|
||||||
|
texture_type const& texture,
|
||||||
|
unit_type const& scale = 1,
|
||||||
|
unit_type const& offset_u = 0,
|
||||||
|
unit_type const& offset_v = 0,
|
||||||
|
result_type const& default_color = result_type(),
|
||||||
|
texture_map_interpolation::values interpolation_value = texture_map_interpolation::nearest_neighbor,
|
||||||
|
texture_map_placement::values placement_value = texture_map_placement::tile
|
||||||
|
)
|
||||||
|
: texture_(texture)
|
||||||
|
, scale_(scale)
|
||||||
|
, offset_u_(offset_u)
|
||||||
|
, offset_v_(offset_v)
|
||||||
|
, default_color_(default_color)
|
||||||
|
, interpolation_value_(interpolation_value)
|
||||||
|
, placement_value_(placement_value)
|
||||||
|
{}
|
||||||
|
template<typename Unit>
|
||||||
|
SPROUT_CONSTEXPR result_type operator()(Unit const& u, Unit const& v) const {
|
||||||
|
return calc(
|
||||||
|
(u - offset_u_ + scale_ / 2) / scale_ * texture_.get().width(),
|
||||||
|
(-(v - offset_v_) + scale_ / 2) / scale_ * texture_.get().height()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// make_texture_map
|
||||||
|
//
|
||||||
|
template<typename Texture>
|
||||||
|
SPROUT_CONSTEXPR sprout::darkroom::materials::texture_map<Texture>
|
||||||
|
make_texture_map(Texture const& texture) {
|
||||||
|
return sprout::darkroom::materials::texture_map<Texture>(texture);
|
||||||
|
}
|
||||||
|
template<typename Texture, typename Unit>
|
||||||
|
SPROUT_CONSTEXPR sprout::darkroom::materials::texture_map<Texture, Unit>
|
||||||
|
make_texture_map(
|
||||||
|
Texture const& texture,
|
||||||
|
Unit const& scale,
|
||||||
|
Unit const& offset_u
|
||||||
|
= 0
|
||||||
|
,
|
||||||
|
Unit const& offset_v
|
||||||
|
= 0
|
||||||
|
,
|
||||||
|
typename sprout::darkroom::materials::texture_map<Texture, Unit>::result_type const& default_color
|
||||||
|
= typename sprout::darkroom::materials::texture_map<Texture, Unit>::result_typ()
|
||||||
|
,
|
||||||
|
sprout::darkroom::materials::texture_map_interpolation::values interpolation_value
|
||||||
|
= sprout::darkroom::materials::texture_map_interpolation::nearest_neighbor
|
||||||
|
,
|
||||||
|
sprout::darkroom::materials::texture_map_placement::values placement_value
|
||||||
|
= sprout::darkroom::materials::texture_map_placement::tile
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return sprout::darkroom::materials::texture_map<Texture, Unit>(
|
||||||
|
texture,
|
||||||
|
scale,
|
||||||
|
offset_u,
|
||||||
|
offset_v,
|
||||||
|
default_color,
|
||||||
|
interpolation_value,
|
||||||
|
placement_value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} // namespace materials
|
||||||
|
} // namespace darkroom
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_DARKROOM_MATERIALS_TEXTURE_MAP_HPP
|
|
@ -135,12 +135,12 @@ namespace sprout {
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
template<typename Ray, typename Point>
|
template<typename Ray, typename Vec>
|
||||||
SPROUT_CONSTEXPR typename intersection<Ray>::type intersect_6(
|
SPROUT_CONSTEXPR typename intersection<Ray>::type intersect_6(
|
||||||
Ray const& ray,
|
Ray const& ray,
|
||||||
zwo_type const& zwo,
|
zwo_type const& zwo,
|
||||||
drei_type const& drei,
|
drei_type const& drei,
|
||||||
Point const& poi
|
Vec const& normal
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
using std::atan2;
|
using std::atan2;
|
||||||
|
@ -153,19 +153,19 @@ namespace sprout {
|
||||||
sprout::darkroom::materials::calc_material( // ! Spherical
|
sprout::darkroom::materials::calc_material( // ! Spherical
|
||||||
mat_,
|
mat_,
|
||||||
atan2(
|
atan2(
|
||||||
sprout::darkroom::coords::x(poi),
|
sprout::darkroom::coords::z(normal),
|
||||||
sprout::darkroom::coords::z(poi)
|
sprout::darkroom::coords::x(normal)
|
||||||
)
|
)
|
||||||
/ (2 * pi)
|
/ pi
|
||||||
,
|
,
|
||||||
atan2(
|
atan2(
|
||||||
|
sprout::darkroom::coords::y(normal),
|
||||||
sqrt(
|
sqrt(
|
||||||
sprout::darkroom::coords::x(poi) * sprout::darkroom::coords::x(poi)
|
sprout::darkroom::coords::x(normal) * sprout::darkroom::coords::x(normal)
|
||||||
+ sprout::darkroom::coords::y(poi) * sprout::darkroom::coords::y(poi)
|
+ sprout::darkroom::coords::z(normal) * sprout::darkroom::coords::z(normal)
|
||||||
),
|
)
|
||||||
sprout::darkroom::coords::z(poi)
|
|
||||||
)
|
)
|
||||||
/ (2 * pi)
|
/ (pi / 2)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ namespace sprout {
|
||||||
ray,
|
ray,
|
||||||
zwo,
|
zwo,
|
||||||
drei,
|
drei,
|
||||||
sprout::tuples::get<dr::point_of_intersection>(drei)
|
sprout::tuples::get<dr::normal>(drei)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
template<typename Ray>
|
template<typename Ray>
|
||||||
|
|
7
sprout/darkroom/textures.hpp
Normal file
7
sprout/darkroom/textures.hpp
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef SPROUT_DARKROOM_TEXTURES_HPP
|
||||||
|
#define SPROUT_DARKROOM_TEXTURES_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/darkroom/textures/texture.hpp>
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_DARKROOM_TEXTURES_HPP
|
96
sprout/darkroom/textures/texture.hpp
Normal file
96
sprout/darkroom/textures/texture.hpp
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#ifndef SPROUT_DARKROOM_TEXTURES_TEXTURE_HPP
|
||||||
|
#define SPROUT_DARKROOM_TEXTURES_TEXTURE_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/array.hpp>
|
||||||
|
#include <sprout/darkroom/access/access.hpp>
|
||||||
|
#include <sprout/darkroom/colors/rgb.hpp>
|
||||||
|
|
||||||
|
//
|
||||||
|
// DARKROOM_LOAD_TEXTURE
|
||||||
|
//
|
||||||
|
#define DARKROOM_LOAD_TEXTURE <sprout/darkroom/load/texture.hpp>
|
||||||
|
|
||||||
|
//
|
||||||
|
// DARKROOM_TEX_VERSION
|
||||||
|
//
|
||||||
|
#define DARKROOM_TEX_VERSION(NUM) NUM
|
||||||
|
|
||||||
|
//
|
||||||
|
// DARKROOM_TEX_IMAGE_DEFAULT
|
||||||
|
//
|
||||||
|
#define DARKROOM_TEX_IMAGE_DEFAULT 0
|
||||||
|
|
||||||
|
//
|
||||||
|
// DARKROOM_TEX_PIXEL_INT_R8G8B8
|
||||||
|
//
|
||||||
|
#define DARKROOM_TEX_PIXEL_INT_R8G8B8 0
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace darkroom {
|
||||||
|
namespace textures {
|
||||||
|
//
|
||||||
|
// version_type
|
||||||
|
//
|
||||||
|
typedef unsigned long version_type;
|
||||||
|
//
|
||||||
|
// info_type
|
||||||
|
//
|
||||||
|
struct info_type {
|
||||||
|
public:
|
||||||
|
unsigned long image_format;
|
||||||
|
unsigned long pixel_format;
|
||||||
|
std::size_t width;
|
||||||
|
std::size_t height;
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// image_type
|
||||||
|
//
|
||||||
|
template<std::size_t Width, std::size_t Height, typename Color = sprout::darkroom::colors::rgb_f>
|
||||||
|
struct image_type {
|
||||||
|
public:
|
||||||
|
typedef Color color_type;
|
||||||
|
typedef color_type value_type;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
SPROUT_STATIC_CONSTEXPR size_type static_width = Width;
|
||||||
|
SPROUT_STATIC_CONSTEXPR size_type static_height = Height;
|
||||||
|
typedef sprout::array<value_type, static_width * static_height> pixels_type;
|
||||||
|
typedef typename sprout::darkroom::access::unit<color_type>::type color_component_type;
|
||||||
|
private:
|
||||||
|
pixels_type pixels_;
|
||||||
|
public:
|
||||||
|
template<typename... Elems>
|
||||||
|
SPROUT_CONSTEXPR image_type(
|
||||||
|
unsigned long image_format,
|
||||||
|
unsigned long pixel_format,
|
||||||
|
Elems const&... elems
|
||||||
|
)
|
||||||
|
: pixels_{{
|
||||||
|
color_type(
|
||||||
|
static_cast<color_component_type>((elems >> 16) & 0xFF) / 0xFF,
|
||||||
|
static_cast<color_component_type>((elems >> 8) & 0xFF) / 0xFF,
|
||||||
|
static_cast<color_component_type>(elems & 0xFF) / 0xFF
|
||||||
|
)...
|
||||||
|
}}
|
||||||
|
{
|
||||||
|
static_assert(sizeof...(Elems) == static_width * static_height, "image_type<>: unmatch image size");
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR value_type const& operator()(size_type x, size_type y) const {
|
||||||
|
return pixels_[y * static_width + x];
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR size_type width() const {
|
||||||
|
return static_width;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR size_type height() const {
|
||||||
|
return static_height;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR pixels_type const& pixels() const {
|
||||||
|
return pixels_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace textures
|
||||||
|
} // namespace darkroom
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_DARKROOM_TEXTURES_TEXTURE_HPP
|
Loading…
Reference in a new issue