diff --git a/headers/enduro2d/base/configs.hpp b/headers/enduro2d/base/configs.hpp index 7be5a252..2a9ce7f7 100644 --- a/headers/enduro2d/base/configs.hpp +++ b/headers/enduro2d/base/configs.hpp @@ -34,8 +34,8 @@ // E2D_PLATFORM // -#define E2D_PLATFORM_LINUX 1 -#define E2D_PLATFORM_IOS 2 +#define E2D_PLATFORM_IOS 1 +#define E2D_PLATFORM_LINUX 2 #define E2D_PLATFORM_MACOSX 3 #define E2D_PLATFORM_WINDOWS 4 #define E2D_PLATFORM_ANDROID 5 @@ -79,3 +79,125 @@ #ifndef E2D_BUILD_MODE # error E2D_BUILD_MODE not detected #endif + +// +// E2D_FILES_MODE +// + +#define E2D_FILES_MODE_POSIX 1 +#define E2D_FILES_MODE_WINAPI 2 + +#ifndef E2D_FILES_MODE +# if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_IOS +# define E2D_FILES_MODE E2D_FILES_MODE_POSIX +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_LINUX +# define E2D_FILES_MODE E2D_FILES_MODE_POSIX +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_MACOSX +# define E2D_FILES_MODE E2D_FILES_MODE_POSIX +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_WINDOWS +# define E2D_FILES_MODE E2D_FILES_MODE_WINAPI +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_ANDROID +# define E2D_FILES_MODE E2D_FILES_MODE_POSIX +# endif +#endif + +#ifndef E2D_FILES_MODE +# error E2D_FILES_MODE not detected +#endif + +// +// E2D_AUDIO_MODE +// + +#define E2D_AUDIO_MODE_NONE 1 +#define E2D_AUDIO_MODE_BASS 2 + +#ifndef E2D_AUDIO_MODE +# if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_IOS +# define E2D_AUDIO_MODE E2D_AUDIO_MODE_NONE +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_LINUX +# define E2D_AUDIO_MODE E2D_AUDIO_MODE_BASS +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_MACOSX +# define E2D_AUDIO_MODE E2D_AUDIO_MODE_BASS +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_WINDOWS +# define E2D_AUDIO_MODE E2D_AUDIO_MODE_BASS +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_ANDROID +# define E2D_AUDIO_MODE E2D_AUDIO_MODE_BASS +# endif +#endif + +#ifndef E2D_AUDIO_MODE +# error E2D_AUDIO_MODE not detected +#endif + +// +// E2D_RENDER_MODE +// + +#define E2D_RENDER_MODE_NONE 1 +#define E2D_RENDER_MODE_OPENGL 2 +#define E2D_RENDER_MODE_OPENGLES 3 + +#ifndef E2D_RENDER_MODE +# if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_IOS +# define E2D_RENDER_MODE E2D_RENDER_MODE_OPENGLES +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_LINUX +# define E2D_RENDER_MODE E2D_RENDER_MODE_OPENGL +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_MACOSX +# define E2D_RENDER_MODE E2D_RENDER_MODE_OPENGL +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_WINDOWS +# define E2D_RENDER_MODE E2D_RENDER_MODE_OPENGL +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_ANDROID +# define E2D_RENDER_MODE E2D_RENDER_MODE_OPENGLES +# endif +#endif + +#ifndef E2D_RENDER_MODE +# error E2D_RENDER_MODE not detected +#endif + +// +// E2D_WINDOW_MODE +// + +#define E2D_WINDOW_MODE_NONE 1 +#define E2D_WINDOW_MODE_GLFW 2 + +#ifndef E2D_WINDOW_MODE +# if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_IOS +# define E2D_WINDOW_MODE E2D_WINDOW_MODE_NONE +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_LINUX +# define E2D_WINDOW_MODE E2D_WINDOW_MODE_GLFW +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_MACOSX +# define E2D_WINDOW_MODE E2D_WINDOW_MODE_GLFW +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_WINDOWS +# define E2D_WINDOW_MODE E2D_WINDOW_MODE_GLFW +# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_ANDROID +# define E2D_WINDOW_MODE E2D_WINDOW_MODE_NONE +# endif +#endif + +#ifndef E2D_WINDOW_MODE +# error E2D_WINDOW_MODE not detected +#endif + +// +// E2D_CLIPPING_MODE +// + +#define E2D_CLIPPING_MODE_ZO 1 +#define E2D_CLIPPING_MODE_NO 2 + +#ifndef E2D_CLIPPING_MODE +# if defined(E2D_RENDER_MODE) && E2D_RENDER_MODE == E2D_RENDER_MODE_NONE +# define E2D_CLIPPING_MODE E2D_CLIPPING_MODE_ZO +# elif defined(E2D_RENDER_MODE) && E2D_RENDER_MODE == E2D_RENDER_MODE_OPENGL +# define E2D_CLIPPING_MODE E2D_CLIPPING_MODE_NO +# elif defined(E2D_RENDER_MODE) && E2D_RENDER_MODE == E2D_RENDER_MODE_OPENGLES +# define E2D_CLIPPING_MODE E2D_CLIPPING_MODE_NO +# endif +#endif + +#ifndef E2D_CLIPPING_MODE +# error E2D_CLIPPING_MODE not detected +#endif diff --git a/headers/enduro2d/core/render.hpp b/headers/enduro2d/core/render.hpp index adf88318..49774c6b 100644 --- a/headers/enduro2d/core/render.hpp +++ b/headers/enduro2d/core/render.hpp @@ -816,23 +816,23 @@ namespace e2d class viewport_command final { public: viewport_command() = delete; - viewport_command(const b2u& viewport_rect) noexcept; - viewport_command(const b2u& viewport_rect, const b2u& scissor_rect) noexcept; + viewport_command(const b2i& viewport_rect) noexcept; + viewport_command(const b2i& viewport_rect, const b2i& scissor_rect) noexcept; - viewport_command& viewport_rect(const b2u& value) noexcept; - viewport_command& scissor_rect(const b2u& value) noexcept; + viewport_command& viewport_rect(const b2i& value) noexcept; + viewport_command& scissor_rect(const b2i& value) noexcept; viewport_command& scissoring(bool value) noexcept; - b2u& viewport_rect() noexcept; - b2u& scissor_rect() noexcept; + b2i& viewport_rect() noexcept; + b2i& scissor_rect() noexcept; bool& scissoring() noexcept; - const b2u& viewport_rect() const noexcept; - const b2u& scissor_rect() const noexcept; + const b2i& viewport_rect() const noexcept; + const b2i& scissor_rect() const noexcept; bool scissoring() const noexcept; private: - b2u viewport_rect_ = b2u::zero(); - b2u scissor_rect_ = b2u::zero(); + b2i viewport_rect_ = b2i::zero(); + b2i scissor_rect_ = b2i::zero(); bool scissoring_ = false; }; diff --git a/headers/enduro2d/high/_all.hpp b/headers/enduro2d/high/_all.hpp index 266215ca..959ec2b4 100644 --- a/headers/enduro2d/high/_all.hpp +++ b/headers/enduro2d/high/_all.hpp @@ -43,6 +43,7 @@ #include "components/spine_player.hpp" #include "components/sprite_renderer.hpp" +#include "systems/camera_system.hpp" #include "systems/flipbook_system.hpp" #include "systems/frame_system.hpp" #include "systems/gizmos_system.hpp" diff --git a/headers/enduro2d/high/_high.hpp b/headers/enduro2d/high/_high.hpp index 2120dc51..1a118740 100644 --- a/headers/enduro2d/high/_high.hpp +++ b/headers/enduro2d/high/_high.hpp @@ -61,6 +61,7 @@ namespace e2d class spine_player; class sprite_renderer; + class camera_system; class flipbook_system; class frame_system; class gizmos_system; diff --git a/headers/enduro2d/high/components/camera.hpp b/headers/enduro2d/high/components/camera.hpp index 8ce8e40c..20449dac 100644 --- a/headers/enduro2d/high/components/camera.hpp +++ b/headers/enduro2d/high/components/camera.hpp @@ -17,29 +17,50 @@ namespace e2d class camera final { public: class gizmos final {}; + public: + ENUM_HPP_CLASS_DECL(modes, u8, + (manual) + (stretch) + (flexible) + (fixed_fit) + (fixed_crop)) public: camera() = default; camera& depth(i32 value) noexcept; - camera& viewport(const b2u& value) noexcept; + camera& mode(modes value) noexcept; + camera& znear(f32 value) noexcept; + camera& zfar(f32 value) noexcept; + camera& view(const m4f& value) noexcept; + camera& viewport(const b2f& value) noexcept; camera& projection(const m4f& value) noexcept; camera& target(const render_target_ptr& value) noexcept; camera& background(const color& value) noexcept; [[nodiscard]] i32 depth() const noexcept; - [[nodiscard]] const b2u& viewport() const noexcept; + [[nodiscard]] modes mode() const noexcept; + [[nodiscard]] f32 znear() const noexcept; + [[nodiscard]] f32 zfar() const noexcept; + [[nodiscard]] const m4f& view() const noexcept; + [[nodiscard]] const b2f& viewport() const noexcept; [[nodiscard]] const m4f& projection() const noexcept; [[nodiscard]] const render_target_ptr& target() const noexcept; [[nodiscard]] const color& background() const noexcept; private: i32 depth_ = 0; - b2u viewport_ = b2u::zero(); + modes mode_ = modes::flexible; + f32 znear_ = 0.f; + f32 zfar_ = 1000.f; + m4f view_ = m4f::identity(); + b2f viewport_ = b2f::unit(); m4f projection_ = m4f::identity(); render_target_ptr target_ = nullptr; color background_ = color::clear(); }; } +ENUM_HPP_REGISTER_TRAITS(e2d::camera::modes) + namespace e2d { template <> @@ -89,7 +110,27 @@ namespace e2d return *this; } - inline camera& camera::viewport(const b2u& value) noexcept { + inline camera& camera::mode(modes value) noexcept { + mode_ = value; + return *this; + } + + inline camera& camera::znear(f32 value) noexcept { + znear_ = value; + return *this; + } + + inline camera& camera::zfar(f32 value) noexcept { + zfar_ = value; + return *this; + } + + inline camera& camera::view(const m4f& value) noexcept { + view_ = value; + return *this; + } + + inline camera& camera::viewport(const b2f& value) noexcept { viewport_ = value; return *this; } @@ -113,7 +154,23 @@ namespace e2d return depth_; } - inline const b2u& camera::viewport() const noexcept { + inline camera::modes camera::mode() const noexcept { + return mode_; + } + + inline f32 camera::znear() const noexcept { + return znear_; + } + + inline f32 camera::zfar() const noexcept { + return zfar_; + } + + inline const m4f& camera::view() const noexcept { + return view_; + } + + inline const b2f& camera::viewport() const noexcept { return viewport_; } diff --git a/headers/enduro2d/high/systems/camera_system.hpp b/headers/enduro2d/high/systems/camera_system.hpp new file mode 100644 index 00000000..7a1cb89a --- /dev/null +++ b/headers/enduro2d/high/systems/camera_system.hpp @@ -0,0 +1,26 @@ +/******************************************************************************* + * This file is part of the "Enduro2D" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include "_systems.hpp" + +namespace e2d +{ + class camera_system final + : public ecs::system> { + public: + camera_system(); + ~camera_system() noexcept; + + void process( + ecs::registry& owner, + const ecs::after& trigger) override; + private: + class internal_state; + std::unique_ptr state_; + }; +} diff --git a/headers/enduro2d/math/mat4.hpp b/headers/enduro2d/math/mat4.hpp index 530ef866..b5172993 100644 --- a/headers/enduro2d/math/mat4.hpp +++ b/headers/enduro2d/math/mat4.hpp @@ -517,103 +517,231 @@ namespace e2d::math ax.x, ay.x, az.x, T(0), ax.y, ay.y, az.y, T(0), ax.z, ay.z, az.z, T(0), - dx, dy, dz, T(1)}; + -dx, -dy, -dz, T(1)}; } // - // make_orthogonal_lh_matrix4 + // make_orthographic_lh_matrix4 // - template < typename T > - std::enable_if_t, mat4> - make_orthogonal_lh_matrix4(T width, T height, T znear, T zfar) noexcept { - E2D_ASSERT(!math::is_near_zero(width, T(0))); - E2D_ASSERT(!math::is_near_zero(height, T(0))); - E2D_ASSERT(!math::approximately(znear, zfar, T(0))); - const T sx = T(2) / width; - const T sy = T(2) / height; - const T sz = T(1) / (zfar - znear); - const T tz = -znear * sz; - return { - sx, T(0), T(0), T(0), - T(0), sy, T(0), T(0), - T(0), T(0), sz, T(0), - T(0), T(0), tz, T(1)}; + namespace impl + { + template < typename T > + std::enable_if_t, mat4> + make_orthographic_lh_zo_matrix4(T width, T height, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(width, T(0))); + E2D_ASSERT(!math::is_near_zero(height, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + const T sx = T(2) / width; + const T sy = T(2) / height; + const T sz = T(1) / (zfar - znear); + const T tz = -znear / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(0), + T(0), T(0), tz, T(1)}; + } + + template < typename T > + std::enable_if_t, mat4> + make_orthographic_lh_no_matrix4(T width, T height, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(width, T(0))); + E2D_ASSERT(!math::is_near_zero(height, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + const T sx = T(2) / width; + const T sy = T(2) / height; + const T sz = T(2) / (zfar - znear); + const T tz = -(zfar + znear) / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(0), + T(0), T(0), tz, T(1)}; + } } template < typename T > std::enable_if_t, mat4> - make_orthogonal_lh_matrix4(const vec2& size, T znear, T zfar) { - return make_orthogonal_lh_matrix4(size.x, size.y, znear, zfar); - } - - // - // make_orthogonal_rh_matrix4 - // - - template < typename T > - std::enable_if_t, mat4> - make_orthogonal_rh_matrix4(T width, T height, T znear, T zfar) noexcept { - E2D_ASSERT(!math::is_near_zero(width, T(0))); - E2D_ASSERT(!math::is_near_zero(height, T(0))); - E2D_ASSERT(!math::approximately(znear, zfar, T(0))); - const T sx = T(2) / width; - const T sy = T(2) / height; - const T sz = T(1) / (znear - zfar); - const T tz = znear * sz; - return { - sx, T(0), T(0), T(0), - T(0), sy, T(0), T(0), - T(0), T(0), sz, T(0), - T(0), T(0), tz, T(1)}; + make_orthographic_lh_matrix4(T width, T height, T znear, T zfar) noexcept { + #if defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_ZO + return impl::make_orthographic_lh_zo_matrix4(width, height, znear, zfar); + #elif defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_NO + return impl::make_orthographic_lh_no_matrix4(width, height, znear, zfar); + #else + # error "E2D_CLIPPING_MODE not detected" + #endif } template < typename T > std::enable_if_t, mat4> - make_orthogonal_rh_matrix4(const vec2& size, T znear, T zfar) { - return make_orthogonal_rh_matrix4(size.x, size.y, znear, zfar); + make_orthographic_lh_matrix4(const vec2& size, T znear, T zfar) noexcept { + return make_orthographic_lh_matrix4(size.x, size.y, znear, zfar); + } + + // + // make_orthographic_rh_matrix4 + // + + namespace impl + { + template < typename T > + std::enable_if_t, mat4> + make_orthographic_rh_zo_matrix4(T width, T height, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(width, T(0))); + E2D_ASSERT(!math::is_near_zero(height, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + const T sx = T(2) / width; + const T sy = T(2) / height; + const T sz = T(-1) / (zfar - znear); + const T tz = -znear / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(0), + T(0), T(0), tz, T(1)}; + } + + template < typename T > + std::enable_if_t, mat4> + make_orthographic_rh_no_matrix4(T width, T height, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(width, T(0))); + E2D_ASSERT(!math::is_near_zero(height, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + const T sx = T(2) / width; + const T sy = T(2) / height; + const T sz = T(-2) / (zfar - znear); + const T tz = -(zfar + znear) / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(0), + T(0), T(0), tz, T(1)}; + } + } + + template < typename T > + std::enable_if_t, mat4> + make_orthographic_rh_matrix4(T width, T height, T znear, T zfar) noexcept { + #if defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_ZO + return impl::make_orthographic_rh_zo_matrix4(width, height, znear, zfar); + #elif defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_NO + return impl::make_orthographic_rh_no_matrix4(width, height, znear, zfar); + #else + # error "E2D_CLIPPING_MODE not detected" + #endif + } + + template < typename T > + std::enable_if_t, mat4> + make_orthographic_rh_matrix4(const vec2& size, T znear, T zfar) noexcept { + return make_orthographic_rh_matrix4(size.x, size.y, znear, zfar); } // // make_perspective_lh_matrix4 // + namespace impl + { + template < typename T, typename AngleTag > + std::enable_if_t, mat4> + make_perspective_lh_zo_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(aspect, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + E2D_ASSERT(!math::approximately(fov, unit::zero(), T(0))); + const T sy = T(1) / math::tan(fov * T(0.5)); + const T sx = sy / aspect; + const T sz = zfar / (zfar - znear); + const T tz = -(zfar * znear) / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(1), + T(0), T(0), tz, T(0)}; + } + + template < typename T, typename AngleTag > + std::enable_if_t, mat4> + make_perspective_lh_no_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(aspect, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + E2D_ASSERT(!math::approximately(fov, unit::zero(), T(0))); + const T sy = T(1) / math::tan(fov * T(0.5)); + const T sx = sy / aspect; + const T sz = (zfar + znear) / (zfar - znear); + const T tz = -(T(2) * zfar * znear) / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(1), + T(0), T(0), tz, T(0)}; + } + } + template < typename T, typename AngleTag > std::enable_if_t, mat4> make_perspective_lh_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { - E2D_ASSERT(!math::is_near_zero(aspect, T(0))); - E2D_ASSERT(!math::approximately(znear, zfar, T(0))); - E2D_ASSERT(!math::approximately(fov, unit::zero(), T(0))); - const T sy = T(1) / math::tan(fov * T(0.5)); - const T sx = sy / aspect; - const T sz = zfar / (zfar - znear); - const T tz = -znear * zfar / (zfar - znear); - return { - sx, T(0), T(0), T(0), - T(0), sy, T(0), T(0), - T(0), T(0), sz, T(1), - T(0), T(0), tz, T(0)}; + #if defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_ZO + return impl::make_perspective_lh_zo_matrix4(fov, aspect, znear, zfar); + #elif defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_NO + return impl::make_perspective_lh_no_matrix4(fov, aspect, znear, zfar); + #else + # error "E2D_CLIPPING_MODE not detected" + #endif } // // make_perspective_rh_matrix4 // + namespace impl + { + template < typename T, typename AngleTag > + std::enable_if_t, mat4> + make_perspective_rh_zo_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(aspect, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + E2D_ASSERT(!math::approximately(fov, unit::zero(), T(0))); + const T sy = T(1) / math::tan(fov * T(0.5)); + const T sx = sy / aspect; + const T sz = zfar / (znear - zfar); + const T tz = -(zfar * znear) / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(-1), + T(0), T(0), tz, T(0)}; + } + + template < typename T, typename AngleTag > + std::enable_if_t, mat4> + make_perspective_rh_no_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(aspect, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + E2D_ASSERT(!math::approximately(fov, unit::zero(), T(0))); + const T sy = T(1) / math::tan(fov * T(0.5)); + const T sx = sy / aspect; + const T sz = -(zfar + znear) / (zfar - znear); + const T tz = -(T(2) * zfar * znear) / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(-1), + T(0), T(0), tz, T(0)}; + } + } + template < typename T, typename AngleTag > std::enable_if_t, mat4> make_perspective_rh_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { - E2D_ASSERT(!math::is_near_zero(aspect, T(0))); - E2D_ASSERT(!math::approximately(znear, zfar, T(0))); - E2D_ASSERT(!math::approximately(fov, unit::zero(), T(0))); - const T sy = T(1) / math::tan(fov * T(0.5)); - const T sx = sy / aspect; - const T sz = zfar / (znear - zfar); - const T tz = znear * zfar / (znear - zfar); - return { - sx, T(0), T(0), T(0), - T(0), sy, T(0), T(0), - T(0), T(0), sz, T(-1), - T(0), T(0), tz, T(0)}; + #if defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_ZO + return impl::make_perspective_rh_zo_matrix4(fov, aspect, znear, zfar); + #elif defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_NO + return impl::make_perspective_rh_no_matrix4(fov, aspect, znear, zfar); + #else + # error "E2D_CLIPPING_MODE not detected" + #endif } // diff --git a/samples/bin/library/prefabs/background_prefab.json b/samples/bin/library/prefabs/background_prefab.json new file mode 100644 index 00000000..0b88f705 --- /dev/null +++ b/samples/bin/library/prefabs/background_prefab.json @@ -0,0 +1,84 @@ +{ + "components" : {}, + "children" : [{ + "prototype" : "sprite_prefab.json", + "components" : { + "actor" : { + "translation" : [-512,0] + }, + "sprite_renderer" : { + "sprite" : "../sprites/background_sprite.json" + } + } + },{ + "prototype" : "sprite_prefab.json", + "components" : { + "actor" : { + "translation" : [-256,0] + }, + "sprite_renderer" : { + "sprite" : "../sprites/background_sprite.json" + } + } + },{ + "prototype" : "sprite_prefab.json", + "components" : { + "actor" : { + "translation" : [0,0] + }, + "sprite_renderer" : { + "sprite" : "../sprites/background_sprite.json" + } + } + },{ + "prototype" : "sprite_prefab.json", + "components" : { + "actor" : { + "translation" : [256,0] + }, + "sprite_renderer" : { + "sprite" : "../sprites/background_sprite.json" + } + } + },{ + "prototype" : "sprite_prefab.json", + "components" : { + "actor" : { + "translation" : [-512,-256] + }, + "sprite_renderer" : { + "sprite" : "../sprites/background_sprite.json" + } + } + },{ + "prototype" : "sprite_prefab.json", + "components" : { + "actor" : { + "translation" : [-256,-256] + }, + "sprite_renderer" : { + "sprite" : "../sprites/background_sprite.json" + } + } + },{ + "prototype" : "sprite_prefab.json", + "components" : { + "actor" : { + "translation" : [0,-256] + }, + "sprite_renderer" : { + "sprite" : "../sprites/background_sprite.json" + } + } + },{ + "prototype" : "sprite_prefab.json", + "components" : { + "actor" : { + "translation" : [256,-256] + }, + "sprite_renderer" : { + "sprite" : "../sprites/background_sprite.json" + } + } + }] +} diff --git a/samples/bin/library/prefabs/gnome_prefab.json b/samples/bin/library/prefabs/gnome_prefab.json index 238cb8a0..f839fe53 100644 --- a/samples/bin/library/prefabs/gnome_prefab.json +++ b/samples/bin/library/prefabs/gnome_prefab.json @@ -4,7 +4,10 @@ "renderer" : { "materials" : [ "../models/gnome/gnome_material.json" - ] + ], + "transform" : { + "translation" : [0,0,5] + } }, "model_renderer" : { "model" : "../models/gnome/gnome_model.json" diff --git a/samples/bin/library/scenes/sample_04.json b/samples/bin/library/scenes/sample_04.json index 012d0001..45cc963e 100644 --- a/samples/bin/library/scenes/sample_04.json +++ b/samples/bin/library/scenes/sample_04.json @@ -3,7 +3,57 @@ "scene" : {} }, "children" : [{ - "prototype" : "../prefabs/camera_prefab.json" + "prototype" : "../prefabs/camera_prefab.json", + "components" : { + "actor" : { + "rotation" : 0.5 + }, + "camera" : { + "viewport" : [0.0,0.0,0.5,0.5] + }, + "named" : { + "name" : "camera(1)" + } + } + },{ + "prototype" : "../prefabs/camera_prefab.json", + "components" : { + "actor" : { + "rotation" : -0.5 + }, + "camera" : { + "viewport" : [0.5,0.0,0.5,0.5] + }, + "named" : { + "name" : "camera(2)" + } + } + },{ + "prototype" : "../prefabs/camera_prefab.json", + "components" : { + "actor" : { + "rotation" : 0.5 + }, + "camera" : { + "viewport" : [0.5,0.5,0.5,0.5] + }, + "named" : { + "name" : "camera(3)" + } + } + },{ + "prototype" : "../prefabs/camera_prefab.json", + "components" : { + "actor" : { + "rotation" : -0.5 + }, + "camera" : { + "viewport" : [0.0,0.5,0.5,0.5] + }, + "named" : { + "name" : "camera(4)" + } + } },{ "prototype" : "../prefabs/gnome_prefab.json", "components" : { diff --git a/samples/bin/library/scenes/sample_07.json b/samples/bin/library/scenes/sample_07.json index bfc3d104..a3678f06 100644 --- a/samples/bin/library/scenes/sample_07.json +++ b/samples/bin/library/scenes/sample_07.json @@ -7,6 +7,8 @@ }, "children" : [{ "prototype" : "../prefabs/camera_prefab.json" + },{ + "prototype" : "../prefabs/background_prefab.json" },{ "prototype" : "../prefabs/gnome_prefab.json", "components" : { @@ -28,7 +30,7 @@ "outline_color" : [0,0,0,255] }, "actor" : { - "translation" : [-315,-235], + "translation" : [-502,-246], "scale" : 1 }, "behaviour" : { diff --git a/samples/bin/library/scripts/emmy/components/camera.lua b/samples/bin/library/scripts/emmy/components/camera.lua index fb147ddc..f7c40a1a 100644 --- a/samples/bin/library/scripts/emmy/components/camera.lua +++ b/samples/bin/library/scripts/emmy/components/camera.lua @@ -9,6 +9,18 @@ local camera = { ---@type integer depth = 0, + ---@type camera_modes + mode = camera.modes.flexible, + + ---@type number + znear = 0.0, + + ---@type number + zfar = 1000.0, + + ---@type m4f + view = m4f.identity(), + ---@type rect viewport = rect.zero(), @@ -19,6 +31,15 @@ local camera = { background = color.white() } +---@class camera_modes +camera.modes = { + manual = "manual", + stretch = "stretch", + flexible = "flexible", + fixed_fit = "fixed_fit", + fixed_crop = "fixed_crop" +} + ---@overload fun(self: camera) ---@param self camera function camera.enable(self) end diff --git a/samples/bin/library/scripts/emmy/math/m4f.lua b/samples/bin/library/scripts/emmy/math/m4f.lua index e67335d6..49a982dd 100644 --- a/samples/bin/library/scripts/emmy/math/m4f.lua +++ b/samples/bin/library/scripts/emmy/math/m4f.lua @@ -53,12 +53,12 @@ function m4f.make_look_at_rh(eye, at, up) end ---@overload fun(width: number, height: number, znear: number, zfar: number): m4f ---@overload fun(size: v2f, znear: number, zfar: number): m4f ---@return m4f -function m4f.make_orthogonal_lh(...) end +function m4f.make_orthographic_lh(...) end ---@overload fun(width: number, height: number, znear: number, zfar: number): m4f ---@overload fun(size: v2f, znear: number, zfar: number): m4f ---@return m4f -function m4f.make_orthogonal_rh(...) end +function m4f.make_orthographic_rh(...) end ---@param angle number ---@param aspect number diff --git a/samples/bin/library/sprites/background.png b/samples/bin/library/sprites/background.png new file mode 100755 index 00000000..d860923f --- /dev/null +++ b/samples/bin/library/sprites/background.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0739fc3ed0d3c14226ba7cb58d3afec1564f7a5101b1544f8b372e7d5ac18a5 +size 3132 diff --git a/samples/bin/library/sprites/background_sprite.json b/samples/bin/library/sprites/background_sprite.json new file mode 100644 index 00000000..e57b5343 --- /dev/null +++ b/samples/bin/library/sprites/background_sprite.json @@ -0,0 +1,5 @@ +{ + "texture" : "background.png", + "pivot" : { "x" : 0, "y" : 0 }, + "texrect" : { "x" : 0, "y" : 0, "w" : 256, "h" : 256 } +} diff --git a/samples/sources/sample_00/sample_00.cpp b/samples/sources/sample_00/sample_00.cpp index e9e74212..a87367fe 100644 --- a/samples/sources/sample_00/sample_00.cpp +++ b/samples/sources/sample_00/sample_00.cpp @@ -184,7 +184,7 @@ namespace void frame_render() final { const auto framebuffer_size = the().real_size().cast_to(); - const auto projection = math::make_orthogonal_lh_matrix4( + const auto projection = math::make_orthographic_lh_matrix4( framebuffer_size, 0.f, 1.f); material_.properties() @@ -193,7 +193,7 @@ namespace the().execute(render::command_block<64>() .add_command(render::viewport_command( - the().framebuffer_size())) + the().framebuffer_size().cast_to())) .add_command(render::clear_command() .color_value({1.f, 0.4f, 0.f, 1.f})) .add_command(render::draw_command(material_, geometry_))); diff --git a/samples/sources/sample_01/sample_01.cpp b/samples/sources/sample_01/sample_01.cpp index 1c825d0c..d3287d47 100644 --- a/samples/sources/sample_01/sample_01.cpp +++ b/samples/sources/sample_01/sample_01.cpp @@ -254,7 +254,7 @@ namespace the().execute(render::command_block<64>() .add_command(render::viewport_command( - the().framebuffer_size())) + the().framebuffer_size().cast_to())) .add_command(render::clear_command() .color_value({1.f, 0.4f, 0.f, 1.f})) .add_command(render::draw_command(material_, geometry_))); diff --git a/samples/sources/sample_02/sample_02.cpp b/samples/sources/sample_02/sample_02.cpp index 62bccd06..65604ff0 100644 --- a/samples/sources/sample_02/sample_02.cpp +++ b/samples/sources/sample_02/sample_02.cpp @@ -224,7 +224,7 @@ namespace the().execute(render::command_block<64>() .add_command(render::target_command(render_target_)) - .add_command(render::viewport_command(render_target_->size())) + .add_command(render::viewport_command(render_target_->size().cast_to())) .add_command(render::clear_command() .color_value({0.f, 0.4f, 0.f, 1.f})) .add_command(render::draw_command(material_, geometry_, tex_props_))); @@ -233,8 +233,8 @@ namespace .add_command(render::target_command(nullptr)) .add_command(render::clear_command() .color_value(color::blue())) - .add_command(render::viewport_command(the().framebuffer_size()) - .scissor_rect(make_rect(v2u{100u}, the().framebuffer_size() - 200u))) + .add_command(render::viewport_command(the().framebuffer_size().cast_to()) + .scissor_rect(make_rect(v2i{100}, the().framebuffer_size().cast_to() - 200))) .add_command(render::clear_command() .color_value({1.f, 0.4f, 0.f, 1.f})) .add_command(render::draw_command(material_, geometry_, rt_props_))); diff --git a/samples/sources/sample_03/sample_03.cpp b/samples/sources/sample_03/sample_03.cpp index 23d41c4d..07864bc6 100644 --- a/samples/sources/sample_03/sample_03.cpp +++ b/samples/sources/sample_03/sample_03.cpp @@ -39,25 +39,6 @@ namespace } }; - class camera_system final : public systems::post_update_system { - public: - void process( - ecs::registry& owner, - const systems::post_update_event& event) override - { - E2D_UNUSED(event); - owner.for_joined_components( - [](const ecs::const_entity&, camera& cam){ - if ( !cam.target() ) { - cam.viewport( - the().framebuffer_size()); - cam.projection(math::make_orthogonal_lh_matrix4( - the().real_size().cast_to(), 0.f, 1000.f)); - } - }); - } - }; - class rotator_system final : public systems::update_system { public: void process( @@ -103,8 +84,11 @@ namespace { prefab prefab; prefab.prototype() + .component(named() + .name("camera")) .component(camera() - .background({1.f, 0.4f, 0.f, 1.f})); + .background({1.f, 0.4f, 0.f, 1.f})) + .component(); the().instantiate( prefab, @@ -114,8 +98,12 @@ namespace { prefab prefab; prefab.prototype() + .component(named() + .name("gnome")) .component(v3f::unit_y()) - .component(renderer().materials({model_mat})) + .component(renderer() + .materials({model_mat}) + .translation({0.f, 0.f, 5.f})) .component(model_res); the().instantiate( @@ -127,6 +115,8 @@ namespace { prefab prefab; prefab.prototype() + .component(named() + .name("ship")) .component() .component() .component(sprite_renderer(sprite_res) @@ -141,6 +131,8 @@ namespace { prefab prefab_a; prefab_a.prototype() + .component(named() + .name("cube")) .component() .component() .component(sprite_renderer() @@ -182,8 +174,7 @@ namespace ecs::registry_filler(the().registry()) .feature(ecs::feature() .add_system() - .add_system() - .add_system()); + .add_system()); return true; } }; diff --git a/samples/sources/sample_04/sample_04.cpp b/samples/sources/sample_04/sample_04.cpp index 6c07a3dd..ebfb622f 100644 --- a/samples/sources/sample_04/sample_04.cpp +++ b/samples/sources/sample_04/sample_04.cpp @@ -32,25 +32,6 @@ namespace } }; - class camera_system final : public systems::post_update_system { - public: - void process( - ecs::registry& owner, - const systems::post_update_event& event) override - { - E2D_UNUSED(event); - owner.for_joined_components( - [](const ecs::const_entity&, camera& cam){ - if ( !cam.target() ) { - cam.viewport( - the().framebuffer_size()); - cam.projection(math::make_orthogonal_lh_matrix4( - the().real_size().cast_to(), 0.f, 1000.f)); - } - }); - } - }; - class game final : public starter::application { public: bool initialize() final { @@ -69,8 +50,7 @@ namespace bool create_systems() { ecs::registry_filler(the().registry()) .feature(ecs::feature() - .add_system() - .add_system()); + .add_system()); return true; } }; diff --git a/samples/sources/sample_05/sample_05.cpp b/samples/sources/sample_05/sample_05.cpp index 5740be19..b3911ab8 100644 --- a/samples/sources/sample_05/sample_05.cpp +++ b/samples/sources/sample_05/sample_05.cpp @@ -67,7 +67,7 @@ namespace void frame_render() final { the().execute(render::command_block<64>() .add_command(render::viewport_command( - the().framebuffer_size())) + the().framebuffer_size().cast_to())) .add_command(render::clear_command() .color_value({1.f, 0.4f, 0.f, 1.f}))); } diff --git a/samples/sources/sample_06/sample_06.cpp b/samples/sources/sample_06/sample_06.cpp index 5e9579a9..bb02995b 100644 --- a/samples/sources/sample_06/sample_06.cpp +++ b/samples/sources/sample_06/sample_06.cpp @@ -70,25 +70,6 @@ namespace } }; - class camera_system final : public systems::post_update_system { - public: - void process( - ecs::registry& owner, - const systems::post_update_event& event) override - { - E2D_UNUSED(event); - owner.for_joined_components( - [](const ecs::const_entity&, camera& cam){ - if ( !cam.target() ) { - cam.viewport( - the().framebuffer_size()); - cam.projection(math::make_orthogonal_lh_matrix4( - the().real_size().cast_to(), 0.f, 1000.f)); - } - }); - } - }; - class game final : public starter::application { public: bool initialize() final { @@ -107,8 +88,7 @@ namespace bool create_systems() { ecs::registry_filler(the().registry()) .feature(ecs::feature() - .add_system() - .add_system()); + .add_system()); return true; } }; diff --git a/samples/sources/sample_07/sample_07.cpp b/samples/sources/sample_07/sample_07.cpp index dce8351c..1e7c9254 100644 --- a/samples/sources/sample_07/sample_07.cpp +++ b/samples/sources/sample_07/sample_07.cpp @@ -32,25 +32,6 @@ namespace } }; - class camera_system final : public systems::post_update_system { - public: - void process( - ecs::registry& owner, - const systems::post_update_event& event) override - { - E2D_UNUSED(event); - owner.for_joined_components( - [](const ecs::const_entity&, camera& cam){ - if ( !cam.target() ) { - cam.viewport( - the().framebuffer_size()); - cam.projection(math::make_orthogonal_lh_matrix4( - the().real_size().cast_to(), 0.f, 1000.f)); - } - }); - } - }; - class game final : public starter::application { public: bool initialize() final { @@ -69,8 +50,7 @@ namespace bool create_systems() { ecs::registry_filler(the().registry()) .feature(ecs::feature() - .add_system() - .add_system()); + .add_system()); return true; } }; @@ -80,7 +60,8 @@ int e2d_main(int argc, char *argv[]) { const auto starter_params = starter::parameters( engine::parameters("sample_07", "enduro2d") .window_params(engine::window_parameters() - .size({1024, 768})) + .size({1024, 512}) + .resizable(true)) .timer_params(engine::timer_parameters() .maximal_framerate(100))); modules::initialize(argc, argv, starter_params).start(); diff --git a/sources/enduro2d/core/audio_impl/audio.hpp b/sources/enduro2d/core/audio_impl/audio.hpp index 1509f5b7..95bbc80f 100644 --- a/sources/enduro2d/core/audio_impl/audio.hpp +++ b/sources/enduro2d/core/audio_impl/audio.hpp @@ -9,22 +9,3 @@ #include #include #include - -#define E2D_AUDIO_MODE_NONE 1 -#define E2D_AUDIO_MODE_BASS 2 - -#ifndef E2D_AUDIO_MODE -# if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_IOS -# define E2D_AUDIO_MODE E2D_AUDIO_MODE_NONE -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_LINUX -# define E2D_AUDIO_MODE E2D_AUDIO_MODE_BASS -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_MACOSX -# define E2D_AUDIO_MODE E2D_AUDIO_MODE_BASS -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_WINDOWS -# define E2D_AUDIO_MODE E2D_AUDIO_MODE_BASS -# endif -#endif - -#ifndef E2D_AUDIO_MODE -# error E2D_AUDIO_MODE not detected -#endif diff --git a/sources/enduro2d/core/dbgui.cpp b/sources/enduro2d/core/dbgui.cpp index 6fa21d35..7798be5e 100644 --- a/sources/enduro2d/core/dbgui.cpp +++ b/sources/enduro2d/core/dbgui.cpp @@ -129,8 +129,8 @@ namespace e2d const v2f framebuffer_size = display_size * v2f(draw_data->FramebufferScale); const m4f projection = - math::make_translation_matrix4(display_size * v2f(-0.5f, 0.5f)) * - math::make_orthogonal_lh_matrix4(display_size, 0.f, 1.f); + math::make_orthographic_lh_matrix4(display_size, 0.f, 1.f) * + math::make_translation_matrix4(-1.f, 1.f); for ( int i = 0; i < draw_data->CmdListsCount; ++i ) { const ImDrawList* cmd_list = draw_data->CmdLists[i]; @@ -174,8 +174,8 @@ namespace e2d render_.execute(render::command_block<8>() .add_command(render::viewport_command( - framebuffer_size.cast_to(), - clip_r.cast_to())) + framebuffer_size.cast_to(), + clip_r.cast_to())) .add_command(render::draw_command(material_, geometry, mprops_) .index_range(first_index, pcmd.ElemCount))); } diff --git a/sources/enduro2d/core/platform_impl/platform.hpp b/sources/enduro2d/core/platform_impl/platform.hpp index cb796684..ce59fc2d 100644 --- a/sources/enduro2d/core/platform_impl/platform.hpp +++ b/sources/enduro2d/core/platform_impl/platform.hpp @@ -8,28 +8,6 @@ #include -#define E2D_PLATFORM_MODE_NONE 1 -#define E2D_PLATFORM_MODE_IOS 2 -#define E2D_PLATFORM_MODE_LINUX 3 -#define E2D_PLATFORM_MODE_MACOSX 4 -#define E2D_PLATFORM_MODE_WINDOWS 5 - -#ifndef E2D_PLATFORM_MODE -# if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_IOS -# define E2D_PLATFORM_MODE E2D_PLATFORM_MODE_IOS -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_LINUX -# define E2D_PLATFORM_MODE E2D_PLATFORM_MODE_LINUX -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_MACOSX -# define E2D_PLATFORM_MODE E2D_PLATFORM_MODE_MACOSX -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_WINDOWS -# define E2D_PLATFORM_MODE E2D_PLATFORM_MODE_WINDOWS -# endif -#endif - -#ifndef E2D_PLATFORM_MODE -# error E2D_PLATFORM_MODE not detected -#endif - namespace e2d { class platform_internal_state_impl; diff --git a/sources/enduro2d/core/platform_impl/platform_none.cpp b/sources/enduro2d/core/platform_impl/platform_android.cpp similarity index 60% rename from sources/enduro2d/core/platform_impl/platform_none.cpp rename to sources/enduro2d/core/platform_impl/platform_android.cpp index 39c99dbf..e45331ea 100644 --- a/sources/enduro2d/core/platform_impl/platform_none.cpp +++ b/sources/enduro2d/core/platform_impl/platform_android.cpp @@ -6,23 +6,23 @@ #include "platform.hpp" -#if defined(E2D_PLATFORM_MODE) && E2D_PLATFORM_MODE == E2D_PLATFORM_MODE_NONE +#if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_ANDROID namespace { using namespace e2d; - class platform_internal_state_impl_none final : public platform_internal_state_impl { + class platform_internal_state_impl_android final : public platform_internal_state_impl { public: - platform_internal_state_impl_none() = default; - ~platform_internal_state_impl_none() noexcept final = default; + platform_internal_state_impl_android() = default; + ~platform_internal_state_impl_android() noexcept final = default; }; } namespace e2d { platform_internal_state_impl_uptr platform_internal_state_impl::create() { - return std::make_unique(); + return std::make_unique(); } } diff --git a/sources/enduro2d/core/platform_impl/platform_ios.cpp b/sources/enduro2d/core/platform_impl/platform_ios.cpp index d2ee7256..d9981a62 100644 --- a/sources/enduro2d/core/platform_impl/platform_ios.cpp +++ b/sources/enduro2d/core/platform_impl/platform_ios.cpp @@ -6,7 +6,7 @@ #include "platform.hpp" -#if defined(E2D_PLATFORM_MODE) && E2D_PLATFORM_MODE == E2D_PLATFORM_MODE_IOS +#if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_IOS namespace { diff --git a/sources/enduro2d/core/platform_impl/platform_linux.cpp b/sources/enduro2d/core/platform_impl/platform_linux.cpp index 8cf6efe2..6132ce84 100644 --- a/sources/enduro2d/core/platform_impl/platform_linux.cpp +++ b/sources/enduro2d/core/platform_impl/platform_linux.cpp @@ -6,7 +6,7 @@ #include "platform.hpp" -#if defined(E2D_PLATFORM_MODE) && E2D_PLATFORM_MODE == E2D_PLATFORM_MODE_LINUX +#if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_LINUX namespace { diff --git a/sources/enduro2d/core/platform_impl/platform_macosx.cpp b/sources/enduro2d/core/platform_impl/platform_macosx.cpp index d6c8a037..25742545 100644 --- a/sources/enduro2d/core/platform_impl/platform_macosx.cpp +++ b/sources/enduro2d/core/platform_impl/platform_macosx.cpp @@ -6,7 +6,7 @@ #include "platform.hpp" -#if defined(E2D_PLATFORM_MODE) && E2D_PLATFORM_MODE == E2D_PLATFORM_MODE_MACOSX +#if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_MACOSX namespace { diff --git a/sources/enduro2d/core/platform_impl/platform_windows.cpp b/sources/enduro2d/core/platform_impl/platform_windows.cpp index 0b0e3d6f..063449c2 100644 --- a/sources/enduro2d/core/platform_impl/platform_windows.cpp +++ b/sources/enduro2d/core/platform_impl/platform_windows.cpp @@ -6,7 +6,7 @@ #include "platform.hpp" -#if defined(E2D_PLATFORM_MODE) && E2D_PLATFORM_MODE == E2D_PLATFORM_MODE_WINDOWS +#if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_WINDOWS #include diff --git a/sources/enduro2d/core/render.cpp b/sources/enduro2d/core/render.cpp index 9e9a7c9c..c534a2aa 100644 --- a/sources/enduro2d/core/render.cpp +++ b/sources/enduro2d/core/render.cpp @@ -1076,20 +1076,20 @@ namespace e2d // viewport_command // - render::viewport_command::viewport_command(const b2u& viewport_rect) noexcept + render::viewport_command::viewport_command(const b2i& viewport_rect) noexcept : viewport_rect_(viewport_rect) {} - render::viewport_command::viewport_command(const b2u& viewport_rect, const b2u& scissor_rect) noexcept + render::viewport_command::viewport_command(const b2i& viewport_rect, const b2i& scissor_rect) noexcept : viewport_rect_(viewport_rect) , scissor_rect_(scissor_rect) , scissoring_(true) {} - render::viewport_command& render::viewport_command::viewport_rect(const b2u& value) noexcept { + render::viewport_command& render::viewport_command::viewport_rect(const b2i& value) noexcept { viewport_rect_ = value; return *this; } - render::viewport_command& render::viewport_command::scissor_rect(const b2u& value) noexcept { + render::viewport_command& render::viewport_command::scissor_rect(const b2i& value) noexcept { scissor_rect_ = value; scissoring_ = true; return *this; @@ -1100,11 +1100,11 @@ namespace e2d return *this; } - b2u& render::viewport_command::viewport_rect() noexcept { + b2i& render::viewport_command::viewport_rect() noexcept { return viewport_rect_; } - b2u& render::viewport_command::scissor_rect() noexcept { + b2i& render::viewport_command::scissor_rect() noexcept { return scissor_rect_; } @@ -1112,11 +1112,11 @@ namespace e2d return scissoring_; } - const b2u& render::viewport_command::viewport_rect() const noexcept { + const b2i& render::viewport_command::viewport_rect() const noexcept { return viewport_rect_; } - const b2u& render::viewport_command::scissor_rect() const noexcept { + const b2i& render::viewport_command::scissor_rect() const noexcept { return scissor_rect_; } diff --git a/sources/enduro2d/core/render_impl/render.hpp b/sources/enduro2d/core/render_impl/render.hpp index 0069c1a6..cec1bdea 100644 --- a/sources/enduro2d/core/render_impl/render.hpp +++ b/sources/enduro2d/core/render_impl/render.hpp @@ -10,25 +10,3 @@ #include #include #include - -#define E2D_RENDER_MODE_NONE 1 -#define E2D_RENDER_MODE_OPENGL 2 -#define E2D_RENDER_MODE_OPENGLES 3 - -#ifndef E2D_RENDER_MODE -# if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_IOS -# define E2D_RENDER_MODE E2D_RENDER_MODE_OPENGLES -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_LINUX -# define E2D_RENDER_MODE E2D_RENDER_MODE_OPENGL -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_MACOSX -# define E2D_RENDER_MODE E2D_RENDER_MODE_OPENGL -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_WINDOWS -# define E2D_RENDER_MODE E2D_RENDER_MODE_OPENGL -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_ANDROID -# define E2D_RENDER_MODE E2D_RENDER_MODE_OPENGLES -# endif -#endif - -#ifndef E2D_RENDER_MODE -# error E2D_RENDER_MODE not detected -#endif diff --git a/sources/enduro2d/core/render_impl/render_opengl.cpp b/sources/enduro2d/core/render_impl/render_opengl.cpp index bbd191e5..3ea19bea 100644 --- a/sources/enduro2d/core/render_impl/render_opengl.cpp +++ b/sources/enduro2d/core/render_impl/render_opengl.cpp @@ -1032,7 +1032,7 @@ namespace e2d render& render::execute(const viewport_command& command) { E2D_ASSERT(is_in_main_thread()); - const b2u viewport = math::make_minmax_rect(command.viewport_rect()); + const b2i viewport = math::make_minmax_rect(command.viewport_rect()); GL_CHECK_CODE(state_->dbg(), glViewport( math::numeric_cast(viewport.position.x), math::numeric_cast(viewport.position.y), @@ -1040,7 +1040,7 @@ namespace e2d math::numeric_cast(viewport.size.y))); if ( command.scissoring() ) { - const b2u scissor = math::make_minmax_rect(command.scissor_rect()); + const b2i scissor = math::make_minmax_rect(command.scissor_rect()); GL_CHECK_CODE(state_->dbg(), glScissor( math::numeric_cast(scissor.position.x), math::numeric_cast(scissor.position.y), diff --git a/sources/enduro2d/core/window_impl/window.hpp b/sources/enduro2d/core/window_impl/window.hpp index 92167dc4..27aea3a8 100644 --- a/sources/enduro2d/core/window_impl/window.hpp +++ b/sources/enduro2d/core/window_impl/window.hpp @@ -9,22 +9,3 @@ #include #include #include - -#define E2D_WINDOW_MODE_NONE 1 -#define E2D_WINDOW_MODE_GLFW 2 - -#ifndef E2D_WINDOW_MODE -# if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_IOS -# define E2D_WINDOW_MODE E2D_WINDOW_MODE_NONE -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_LINUX -# define E2D_WINDOW_MODE E2D_WINDOW_MODE_GLFW -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_MACOSX -# define E2D_WINDOW_MODE E2D_WINDOW_MODE_GLFW -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_WINDOWS -# define E2D_WINDOW_MODE E2D_WINDOW_MODE_GLFW -# endif -#endif - -#ifndef E2D_WINDOW_MODE -# error E2D_WINDOW_MODE not detected -#endif diff --git a/sources/enduro2d/high/bindings/high_binds/components/camera_binds.cpp b/sources/enduro2d/high/bindings/high_binds/components/camera_binds.cpp index fadae356..f32f5ef7 100644 --- a/sources/enduro2d/high/bindings/high_binds/components/camera_binds.cpp +++ b/sources/enduro2d/high/bindings/high_binds/components/camera_binds.cpp @@ -58,12 +58,44 @@ namespace e2d::bindings::high c->depth(v); }), + "mode", sol::property( + [](const gcomponent& c) -> camera::modes { + return c->mode(); + }, + [](gcomponent& c, camera::modes v){ + c->mode(v); + }), + + "znear", sol::property( + [](const gcomponent& c) -> f32 { + return c->znear(); + }, + [](gcomponent& c, f32 v){ + c->znear(v); + }), + + "zfar", sol::property( + [](const gcomponent& c) -> f32 { + return c->zfar(); + }, + [](gcomponent& c, f32 v){ + c->zfar(v); + }), + + "view", sol::property( + [](const gcomponent& c) -> m4f { + return c->view(); + }, + [](gcomponent& c, const m4f& v){ + c->view(v); + }), + "viewport", sol::property( [](const gcomponent& c) -> b2f { - return c->viewport().cast_to(); + return c->viewport(); }, [](gcomponent& c, const b2f& v){ - c->viewport(v.cast_to()); + c->viewport(v); }), "projection", sol::property( @@ -82,5 +114,16 @@ namespace e2d::bindings::high c->background(v); }) ); + + #define CAMERA_MODE_PAIR(x) {#x, camera::modes::x}, + l["camera"].get_or_create() + .new_enum("modes", { + CAMERA_MODE_PAIR(manual) + CAMERA_MODE_PAIR(stretch) + CAMERA_MODE_PAIR(flexible) + CAMERA_MODE_PAIR(fixed_fit) + CAMERA_MODE_PAIR(fixed_crop) + }); + #undef CAMERA_MODE_PAIR } } diff --git a/sources/enduro2d/high/bindings/math_binds/mat4_binds.cpp b/sources/enduro2d/high/bindings/math_binds/mat4_binds.cpp index b8b567e7..7b670e22 100644 --- a/sources/enduro2d/high/bindings/math_binds/mat4_binds.cpp +++ b/sources/enduro2d/high/bindings/math_binds/mat4_binds.cpp @@ -66,13 +66,13 @@ namespace "make_look_at_rh", sol::resolve< mat4(const vec3&,const vec3&,const vec3&)>(&math::make_look_at_rh_matrix4), - "make_orthogonal_lh", sol::overload( - sol::resolve(T,T,T,T)>(&math::make_orthogonal_lh_matrix4), - sol::resolve(const vec2&,T,T)>(&math::make_orthogonal_lh_matrix4)), + "make_orthographic_lh", sol::overload( + sol::resolve(T,T,T,T)>(&math::make_orthographic_lh_matrix4), + sol::resolve(const vec2&,T,T)>(&math::make_orthographic_lh_matrix4)), - "make_orthogonal_rh", sol::overload( - sol::resolve(T,T,T,T)>(&math::make_orthogonal_rh_matrix4), - sol::resolve(const vec2&,T,T)>(&math::make_orthogonal_rh_matrix4)), + "make_orthographic_rh", sol::overload( + sol::resolve(T,T,T,T)>(&math::make_orthographic_rh_matrix4), + sol::resolve(const vec2&,T,T)>(&math::make_orthographic_rh_matrix4)), "make_perspective_lh", [](T angle, T aspect, T znear, T zfar) -> mat4 { return math::make_perspective_lh_matrix4(make_rad(angle), aspect, znear, zfar); diff --git a/sources/enduro2d/high/components/camera.cpp b/sources/enduro2d/high/components/camera.cpp index 1523f91e..e255c35a 100644 --- a/sources/enduro2d/high/components/camera.cpp +++ b/sources/enduro2d/high/components/camera.cpp @@ -13,10 +13,26 @@ namespace e2d "required" : [], "additionalProperties" : false, "properties" : { - "depth" : { "type" : "number" }, + "depth" : { "type" : "integer" }, + "mode" : { "$ref": "#/definitions/modes" }, + "znear" : { "type" : "number" }, + "zfar" : { "type" : "number" }, + "view" : { "$ref": "#/common_definitions/m4" }, "viewport" : { "$ref": "#/common_definitions/b2" }, "projection" : { "$ref": "#/common_definitions/m4" }, "background" : { "$ref": "#/common_definitions/color" } + }, + "definitions" : { + "modes" : { + "type" : "string", + "enum" : [ + "manual", + "stretch", + "flexible", + "fixed_fit", + "fixed_crop" + ] + } } })json"; @@ -25,7 +41,7 @@ namespace e2d const fill_context& ctx) const { if ( ctx.root.HasMember("depth") ) { - auto depth = component.depth(); + i32 depth = component.depth(); if ( !json_utils::try_parse_value(ctx.root["depth"], depth) ) { the().error("CAMERA: Incorrect formatting of 'depth' property"); return false; @@ -33,8 +49,44 @@ namespace e2d component.depth(depth); } + if ( ctx.root.HasMember("mode") ) { + camera::modes mode = component.mode(); + if ( !json_utils::try_parse_value(ctx.root["mode"], mode) ) { + the().error("CAMERA: Incorrect formatting of 'mode' property"); + return false; + } + component.mode(mode); + } + + if ( ctx.root.HasMember("znear") ) { + f32 znear = component.znear(); + if ( !json_utils::try_parse_value(ctx.root["znear"], znear) ) { + the().error("CAMERA: Incorrect formatting of 'znear' property"); + return false; + } + component.znear(znear); + } + + if ( ctx.root.HasMember("zfar") ) { + f32 zfar = component.zfar(); + if ( !json_utils::try_parse_value(ctx.root["zfar"], zfar) ) { + the().error("CAMERA: Incorrect formatting of 'zfar' property"); + return false; + } + component.zfar(zfar); + } + + if ( ctx.root.HasMember("view") ) { + m4f view = component.view(); + if ( !json_utils::try_parse_value(ctx.root["view"], view) ) { + the().error("CAMERA: Incorrect formatting of 'view' property"); + return false; + } + component.view(view); + } + if ( ctx.root.HasMember("viewport") ) { - auto viewport = component.viewport(); + b2f viewport = component.viewport(); if ( !json_utils::try_parse_value(ctx.root["viewport"], viewport) ) { the().error("CAMERA: Incorrect formatting of 'viewport' property"); return false; @@ -43,7 +95,7 @@ namespace e2d } if ( ctx.root.HasMember("projection") ) { - auto projection = component.projection(); + m4f projection = component.projection(); if ( !json_utils::try_parse_value(ctx.root["projection"], projection) ) { the().error("CAMERA: Incorrect formatting of 'projection' property"); return false; @@ -56,7 +108,7 @@ namespace e2d } if ( ctx.root.HasMember("background") ) { - auto background = component.background(); + color background = component.background(); if ( !json_utils::try_parse_value(ctx.root["background"], background) ) { the().error("CAMERA: Incorrect formatting of 'background' property"); return false; @@ -118,12 +170,53 @@ namespace e2d } if ( i32 depth = c->depth(); - ImGui::DragInt("depth", &depth) ) + ImGui::DragInt("depth", &depth, 1.f) ) { c->depth(depth); } - ///TODO(BlackMat): add 'viewport' inspector + if ( camera::modes mode = c->mode(); + imgui_utils::show_enum_combo_box("mode", &mode) ) + { + c->mode(mode); + } + + if ( ImGui::TreeNode("clipping") ) { + E2D_DEFER([](){ ImGui::TreePop(); }); + + if ( f32 znear = c->znear(); + ImGui::DragFloat("znear", &znear, 1.f) ) + { + c->znear(znear); + c->zfar(math::max(c->zfar(), c->znear())); + } + + if ( f32 zfar = c->zfar(); + ImGui::DragFloat("zfar", &zfar, 1.f) ) + { + c->zfar(zfar); + c->znear(math::min(c->znear(), c->zfar())); + } + } + + ///TODO(BlackMat): add 'view' inspector + + if ( ImGui::TreeNode("viewport") ) { + E2D_DEFER([](){ ImGui::TreePop(); }); + + if ( b2f viewport = c->viewport(); + ImGui::DragFloat2("position", viewport.position.data(), 0.01f) ) + { + c->viewport(viewport); + } + + if ( b2f viewport = c->viewport(); + ImGui::DragFloat2("size", viewport.size.data(), 0.01f, 0.f, std::numeric_limits::max()) ) + { + c->viewport(viewport); + } + } + ///TODO(BlackMat): add 'projection' inspector ///TODO(BlackMat): add 'target' inspector diff --git a/sources/enduro2d/high/components/renderer.cpp b/sources/enduro2d/high/components/renderer.cpp index a693ff22..aa8e2f1c 100644 --- a/sources/enduro2d/high/components/renderer.cpp +++ b/sources/enduro2d/high/components/renderer.cpp @@ -85,7 +85,7 @@ namespace e2d void component_inspector::operator()(gcomponent& c) const { if ( v3f translation = c->translation(); - ImGui::DragFloat3("translation", translation.data(), 1.f) ) + ImGui::DragFloat3("translation", translation.data(), 0.01f) ) { c->translation(translation); } diff --git a/sources/enduro2d/high/starter.cpp b/sources/enduro2d/high/starter.cpp index c6fe3f76..725f7c35 100644 --- a/sources/enduro2d/high/starter.cpp +++ b/sources/enduro2d/high/starter.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -55,6 +56,8 @@ namespace bool initialize() final { ecs::registry_filler(the().registry()) + .feature(ecs::feature() + .add_system()) .feature(ecs::feature() .add_system()) .feature(ecs::feature() diff --git a/sources/enduro2d/high/systems/camera_system.cpp b/sources/enduro2d/high/systems/camera_system.cpp new file mode 100644 index 00000000..c5f74e52 --- /dev/null +++ b/sources/enduro2d/high/systems/camera_system.cpp @@ -0,0 +1,126 @@ +/******************************************************************************* + * This file is part of the "Enduro2D" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#include + +#include +#include + +namespace +{ + using namespace e2d; + + m4f make_camera_view(const actor& actor) noexcept { + return actor.node() + ? math::inversed(actor.node()->world_matrix()).first + : m4f::identity(); + } + + m4f make_camera_projection(const camera& camera, const window& window) noexcept { + const f32 ortho_znear = camera.znear(); + const f32 ortho_zfar = math::max( + camera.zfar(), + camera.znear() + math::default_precision()); + + const v2u target_size = camera.target() + ? camera.target()->size() + : window.real_size(); + + const v2f virtual_size = window.virtual_size().cast_to(); + const v2f viewport_size = target_size.cast_to() * camera.viewport().size; + + if ( math::is_near_zero(math::length_squared(virtual_size), 0.f) || + math::is_near_zero(math::length_squared(viewport_size), 0.f) ) + { + return camera.projection(); + } + + const f32 virtual_aspect = virtual_size.x / virtual_size.y; + const f32 viewport_aspect = viewport_size.x / viewport_size.y; + + switch ( camera.mode() ) { + case camera::modes::manual: + return camera.projection(); + case camera::modes::stretch: + return math::make_orthographic_lh_matrix4( + virtual_size, + ortho_znear, + ortho_zfar); + case camera::modes::flexible: + return math::make_orthographic_lh_matrix4( + viewport_size, + ortho_znear, + ortho_zfar); + case camera::modes::fixed_fit: + return math::make_orthographic_lh_matrix4( + viewport_aspect < virtual_aspect + ? v2f(virtual_size.x, virtual_size.y * (virtual_aspect / viewport_aspect)) + : v2f(virtual_size.x * (viewport_aspect / virtual_aspect), virtual_size.y), + ortho_znear, + ortho_zfar); + case camera::modes::fixed_crop: + return math::make_orthographic_lh_matrix4( + virtual_aspect < viewport_aspect + ? v2f(virtual_size.x, virtual_size.y * (virtual_aspect / viewport_aspect)) + : v2f(virtual_size.x * (viewport_aspect / virtual_aspect), virtual_size.y), + ortho_znear, + ortho_zfar); + default: + E2D_ASSERT_MSG(false, "unexpected camera mode"); + return camera.projection(); + } + } +} + +namespace e2d +{ + // + // camera_system::internal_state + // + + class camera_system::internal_state final : private noncopyable { + public: + internal_state(window& w) + : window_(w) {} + ~internal_state() noexcept = default; + + void process_update(ecs::registry& owner) { + owner.for_joined_components([]( + const ecs::const_entity&, + camera& c, + const actor& a) + { + c.view(make_camera_view(a)); + }); + + owner.for_each_component([this]( + const ecs::const_entity&, + camera& c) + { + c.projection(make_camera_projection(c, window_)); + }); + } + private: + window& window_; + }; + + // + // camera_system + // + + camera_system::camera_system() + : state_(new internal_state(the())) {} + camera_system::~camera_system() noexcept = default; + + void camera_system::process( + ecs::registry& owner, + const ecs::after& trigger) + { + E2D_UNUSED(trigger); + E2D_PROFILER_SCOPE("camera_system.process_update"); + state_->process_update(owner); + } +} diff --git a/sources/enduro2d/high/systems/frame_system.cpp b/sources/enduro2d/high/systems/frame_system.cpp index 9efb36bf..e3186f8a 100644 --- a/sources/enduro2d/high/systems/frame_system.cpp +++ b/sources/enduro2d/high/systems/frame_system.cpp @@ -13,6 +13,15 @@ namespace { using namespace e2d; + void clear_framebuffer(render& render, window& window) { + render.execute(render::command_block<3>() + .add_command(render::target_command()) + .add_command(render::viewport_command( + window.framebuffer_size().cast_to())) + .add_command(render::clear_command() + .color_value(color::black()))); + } + template < typename Event > void for_all_cameras(ecs::registry& owner) { const auto comp = [](const auto& l, const auto& r) noexcept { @@ -42,8 +51,10 @@ namespace e2d class frame_system::internal_state final : private noncopyable { public: - internal_state(engine& e) - : engine_(e) {} + internal_state(engine& e, render& r, window& w) + : engine_(e) + , render_(r) + , window_(w) {} ~internal_state() noexcept = default; void process_frame_update(ecs::registry& owner) { @@ -67,6 +78,8 @@ namespace e2d } void process_frame_render(ecs::registry& owner) { + clear_framebuffer(render_, window_); + { E2D_PROFILER_SCOPE("ecs.pre_render"); for_all_cameras(owner); @@ -84,6 +97,8 @@ namespace e2d } private: engine& engine_; + render& render_; + window& window_; }; // @@ -91,7 +106,7 @@ namespace e2d // frame_system::frame_system() - : state_(new internal_state(the())) {} + : state_(new internal_state(the(), the(), the())) {} frame_system::~frame_system() noexcept = default; void frame_system::process( diff --git a/sources/enduro2d/high/systems/gizmos_system.cpp b/sources/enduro2d/high/systems/gizmos_system.cpp index 6ac0b6fb..d2fd3383 100644 --- a/sources/enduro2d/high/systems/gizmos_system.cpp +++ b/sources/enduro2d/high/systems/gizmos_system.cpp @@ -40,10 +40,14 @@ namespace } camera_vp_ = - math::inversed(cam_n->world_matrix()).first * + cam.view() * cam.projection() * - math::make_scale_matrix4(0.5f, -0.5f) * + math::make_scale_matrix4(0.5f, 0.5f) * math::make_translation_matrix4(0.5f, 0.5f) * + math::make_scale_matrix4(cam.viewport().size) * + math::make_translation_matrix4(cam.viewport().position) * + math::make_scale_matrix4(1.f, -1.f) * + math::make_translation_matrix4(0.f, 1.f) * math::make_scale_matrix4(v2f(ImGui::GetIO().DisplaySize)); return true; diff --git a/sources/enduro2d/high/systems/render_system.cpp b/sources/enduro2d/high/systems/render_system.cpp index 0c57c0ce..06f43843 100644 --- a/sources/enduro2d/high/systems/render_system.cpp +++ b/sources/enduro2d/high/systems/render_system.cpp @@ -56,12 +56,11 @@ namespace e2d ~internal_state() noexcept = default; void process_render(const ecs::const_entity& cam_e, ecs::registry& owner) { - if ( !cam_e.valid() || !ecs::exists_all()(cam_e) ) { + if ( !cam_e.valid() || !cam_e.exists_component() ) { return; } drawer_.with( cam_e.get_component(), - cam_e.get_component().node(), [&owner](drawer::context& ctx){ for_all_scenes(ctx, owner); }); diff --git a/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp b/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp index 97ac41c2..52543879 100644 --- a/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp +++ b/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp @@ -42,7 +42,6 @@ namespace e2d::render_system_impl drawer::context::context( const camera& cam, - const const_node_iptr& cam_n, engine& engine, render& render, window& window, @@ -50,14 +49,7 @@ namespace e2d::render_system_impl : render_(render) , batcher_(batcher) { - const m4f& cam_w = cam_n - ? cam_n->world_matrix() - : m4f::identity(); - const std::pair cam_w_inv = math::inversed(cam_w); - - const m4f& m_v = cam_w_inv.second - ? cam_w_inv.first - : m4f::identity(); + const m4f& m_v = cam.view(); const m4f& m_p = cam.projection(); batcher_.flush() @@ -69,9 +61,20 @@ namespace e2d::render_system_impl .property(matrix_vp_property_hash, m_v * m_p) .property(time_property_hash, engine.time()); + const v2u target_size = cam.target() + ? cam.target()->size() + : window.framebuffer_size(); + + const b2f target_viewport = make_rect( + cam.viewport().position * target_size.cast_to(), + cam.viewport().size * target_size.cast_to()); + render.execute(render::command_block<3>() - .add_command(render::target_command(cam.target())) - .add_command(render::viewport_command(cam.viewport())) + .add_command(render::target_command( + cam.target())) + .add_command(render::viewport_command( + target_viewport.cast_to(), + target_viewport.cast_to())) .add_command(render::clear_command() .color_value(cam.background()))); } diff --git a/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.hpp b/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.hpp index 6c00c6d2..d3b50b03 100644 --- a/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.hpp +++ b/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.hpp @@ -33,7 +33,6 @@ namespace e2d::render_system_impl public: context( const camera& cam, - const const_node_iptr& cam_n, engine& engine, render& render, window& window, @@ -66,7 +65,7 @@ namespace e2d::render_system_impl drawer(engine& e, debug& d, render& r, window& w); template < typename F > - void with(const camera& cam, const const_node_iptr& cam_n, F&& f); + void with(const camera& cam, F&& f); private: engine& engine_; render& render_; @@ -78,8 +77,8 @@ namespace e2d::render_system_impl namespace e2d::render_system_impl { template < typename F > - void drawer::with(const camera& cam, const const_node_iptr& cam_n, F&& f) { - context ctx{cam, cam_n, engine_, render_, window_, batcher_}; + void drawer::with(const camera& cam, F&& f) { + context ctx{cam, engine_, render_, window_, batcher_}; std::forward(f)(ctx); ctx.flush(); } diff --git a/sources/enduro2d/utils/filesystem_impl/files.hpp b/sources/enduro2d/utils/filesystem_impl/files.hpp index f9753645..1e68dfcd 100644 --- a/sources/enduro2d/utils/filesystem_impl/files.hpp +++ b/sources/enduro2d/utils/filesystem_impl/files.hpp @@ -10,25 +10,6 @@ #include #include -#define E2D_FILES_MODE_POSIX 1 -#define E2D_FILES_MODE_WINAPI 2 - -#ifndef E2D_FILES_MODE -# if defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_IOS -# define E2D_FILES_MODE E2D_FILES_MODE_POSIX -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_LINUX -# define E2D_FILES_MODE E2D_FILES_MODE_POSIX -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_MACOSX -# define E2D_FILES_MODE E2D_FILES_MODE_POSIX -# elif defined(E2D_PLATFORM) && E2D_PLATFORM == E2D_PLATFORM_WINDOWS -# define E2D_FILES_MODE E2D_FILES_MODE_WINAPI -# endif -#endif - -#ifndef E2D_FILES_MODE -# error E2D_FILES_MODE not detected -#endif - namespace e2d::impl { read_file_uptr make_read_file(str_view path) noexcept; diff --git a/untests/sources/untests_math/mat4.cpp b/untests/sources/untests_math/mat4.cpp index ee4d6b5c..c86ca3f8 100644 --- a/untests/sources/untests_math/mat4.cpp +++ b/untests/sources/untests_math/mat4.cpp @@ -35,8 +35,11 @@ TEST_CASE("mat4") { REQUIRE(math::make_rotation_matrix4(make_rad(1.f),1.f,1.f,1.f) == math::make_rotation_matrix4(make_rad(1.f), v3f::unit())); REQUIRE(math::make_rotation_matrix4(make_rad(1.f),v3f(1.f,1.f,1.f)) == math::make_rotation_matrix4(make_rad(1.f), v3f::unit())); - REQUIRE(math::make_orthogonal_lh_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthogonal_lh_matrix4(v2f(640,480), 0.f, 1.f)); - REQUIRE(math::make_orthogonal_lh_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthogonal_lh_matrix4(v2d(640,480), 0.0, 1.0)); + REQUIRE(math::make_orthographic_lh_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthographic_lh_matrix4(v2f(640,480), 0.f, 1.f)); + REQUIRE(math::make_orthographic_lh_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthographic_lh_matrix4(v2d(640,480), 0.0, 1.0)); + + REQUIRE(math::make_orthographic_lh_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthographic_lh_matrix4(v2f(640,480), 0.f, 1.f)); + REQUIRE(math::make_orthographic_lh_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthographic_lh_matrix4(v2d(640,480), 0.0, 1.0)); } { REQUIRE(m4f(m4f::identity()) == m4f::identity());