mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-15 00:11:55 +07:00
Merge pull request #111 from enduro2d/hotfix/camera_viewport
Hotfix/camera viewport
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace e2d
|
||||
class spine_player;
|
||||
class sprite_renderer;
|
||||
|
||||
class camera_system;
|
||||
class flipbook_system;
|
||||
class frame_system;
|
||||
class gizmos_system;
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
|
||||
26
headers/enduro2d/high/systems/camera_system.hpp
Normal file
26
headers/enduro2d/high/systems/camera_system.hpp
Normal file
@@ -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<ecs::after<systems::update_event>> {
|
||||
public:
|
||||
camera_system();
|
||||
~camera_system() noexcept;
|
||||
|
||||
void process(
|
||||
ecs::registry& owner,
|
||||
const ecs::after<systems::update_event>& trigger) override;
|
||||
private:
|
||||
class internal_state;
|
||||
std::unique_ptr<internal_state> state_;
|
||||
};
|
||||
}
|
||||
@@ -517,23 +517,25 @@ 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
|
||||
//
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_orthogonal_lh_matrix4(T width, T height, T znear, T zfar) noexcept {
|
||||
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 * sz;
|
||||
const T tz = -znear / (zfar - znear);
|
||||
return {
|
||||
sx, T(0), T(0), T(0),
|
||||
T(0), sy, T(0), T(0),
|
||||
@@ -543,24 +545,56 @@ namespace e2d::math
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_orthogonal_lh_matrix4(const vec2<T>& 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<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_orthogonal_rh_matrix4(T width, T height, T znear, T zfar) noexcept {
|
||||
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(1) / (znear - zfar);
|
||||
const T tz = znear * sz;
|
||||
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<std::is_floating_point_v<T>, mat4<T>>
|
||||
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<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_orthographic_lh_matrix4(const vec2<T>& 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<std::is_floating_point_v<T>, mat4<T>>
|
||||
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),
|
||||
@@ -570,24 +604,56 @@ namespace e2d::math
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_orthogonal_rh_matrix4(const vec2<T>& size, T znear, T zfar) {
|
||||
return make_orthogonal_rh_matrix4(size.x, size.y, znear, zfar);
|
||||
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<std::is_floating_point_v<T>, mat4<T>>
|
||||
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<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_orthographic_rh_matrix4(const vec2<T>& 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<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_perspective_lh_matrix4(const unit<T, AngleTag>& fov, T aspect, T znear, T zfar) noexcept {
|
||||
make_perspective_lh_zo_matrix4(const unit<T, AngleTag>& 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<T, AngleTag>::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);
|
||||
const T tz = -(zfar * znear) / (zfar - znear);
|
||||
return {
|
||||
sx, T(0), T(0), T(0),
|
||||
T(0), sy, T(0), T(0),
|
||||
@@ -595,20 +661,52 @@ namespace e2d::math
|
||||
T(0), T(0), tz, T(0)};
|
||||
}
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_perspective_lh_no_matrix4(const unit<T, AngleTag>& 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<T, AngleTag>::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<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_perspective_lh_matrix4(const unit<T, AngleTag>& fov, T aspect, T znear, T zfar) noexcept {
|
||||
#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<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_perspective_rh_matrix4(const unit<T, AngleTag>& fov, T aspect, T znear, T zfar) noexcept {
|
||||
make_perspective_rh_zo_matrix4(const unit<T, AngleTag>& 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<T, AngleTag>::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);
|
||||
const T tz = -(zfar * znear) / (zfar - znear);
|
||||
return {
|
||||
sx, T(0), T(0), T(0),
|
||||
T(0), sy, T(0), T(0),
|
||||
@@ -616,6 +714,36 @@ namespace e2d::math
|
||||
T(0), T(0), tz, T(0)};
|
||||
}
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_perspective_rh_no_matrix4(const unit<T, AngleTag>& 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<T, AngleTag>::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<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_perspective_rh_matrix4(const unit<T, AngleTag>& fov, T aspect, T znear, T zfar) noexcept {
|
||||
#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
|
||||
}
|
||||
|
||||
//
|
||||
// approximately
|
||||
//
|
||||
|
||||
84
samples/bin/library/prefabs/background_prefab.json
Normal file
84
samples/bin/library/prefabs/background_prefab.json
Normal file
@@ -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"
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
@@ -4,7 +4,10 @@
|
||||
"renderer" : {
|
||||
"materials" : [
|
||||
"../models/gnome/gnome_material.json"
|
||||
]
|
||||
],
|
||||
"transform" : {
|
||||
"translation" : [0,0,5]
|
||||
}
|
||||
},
|
||||
"model_renderer" : {
|
||||
"model" : "../models/gnome/gnome_model.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" : {
|
||||
|
||||
@@ -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" : {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
3
samples/bin/library/sprites/background.png
Executable file
3
samples/bin/library/sprites/background.png
Executable file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d0739fc3ed0d3c14226ba7cb58d3afec1564f7a5101b1544f8b372e7d5ac18a5
|
||||
size 3132
|
||||
5
samples/bin/library/sprites/background_sprite.json
Normal file
5
samples/bin/library/sprites/background_sprite.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"texture" : "background.png",
|
||||
"pivot" : { "x" : 0, "y" : 0 },
|
||||
"texrect" : { "x" : 0, "y" : 0, "w" : 256, "h" : 256 }
|
||||
}
|
||||
@@ -184,7 +184,7 @@ namespace
|
||||
|
||||
void frame_render() final {
|
||||
const auto framebuffer_size = the<window>().real_size().cast_to<f32>();
|
||||
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<render>().execute(render::command_block<64>()
|
||||
.add_command(render::viewport_command(
|
||||
the<window>().framebuffer_size()))
|
||||
the<window>().framebuffer_size().cast_to<i32>()))
|
||||
.add_command(render::clear_command()
|
||||
.color_value({1.f, 0.4f, 0.f, 1.f}))
|
||||
.add_command(render::draw_command(material_, geometry_)));
|
||||
|
||||
@@ -254,7 +254,7 @@ namespace
|
||||
|
||||
the<render>().execute(render::command_block<64>()
|
||||
.add_command(render::viewport_command(
|
||||
the<window>().framebuffer_size()))
|
||||
the<window>().framebuffer_size().cast_to<i32>()))
|
||||
.add_command(render::clear_command()
|
||||
.color_value({1.f, 0.4f, 0.f, 1.f}))
|
||||
.add_command(render::draw_command(material_, geometry_)));
|
||||
|
||||
@@ -224,7 +224,7 @@ namespace
|
||||
|
||||
the<render>().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<i32>()))
|
||||
.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<window>().framebuffer_size())
|
||||
.scissor_rect(make_rect(v2u{100u}, the<window>().framebuffer_size() - 200u)))
|
||||
.add_command(render::viewport_command(the<window>().framebuffer_size().cast_to<i32>())
|
||||
.scissor_rect(make_rect(v2i{100}, the<window>().framebuffer_size().cast_to<i32>() - 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_)));
|
||||
|
||||
@@ -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<camera>(
|
||||
[](const ecs::const_entity&, camera& cam){
|
||||
if ( !cam.target() ) {
|
||||
cam.viewport(
|
||||
the<window>().framebuffer_size());
|
||||
cam.projection(math::make_orthogonal_lh_matrix4(
|
||||
the<window>().real_size().cast_to<f32>(), 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>(named()
|
||||
.name("camera"))
|
||||
.component<camera>(camera()
|
||||
.background({1.f, 0.4f, 0.f, 1.f}));
|
||||
.background({1.f, 0.4f, 0.f, 1.f}))
|
||||
.component<camera::gizmos>();
|
||||
|
||||
the<world>().instantiate(
|
||||
prefab,
|
||||
@@ -114,8 +98,12 @@ namespace
|
||||
{
|
||||
prefab prefab;
|
||||
prefab.prototype()
|
||||
.component<named>(named()
|
||||
.name("gnome"))
|
||||
.component<renderer_rotator>(v3f::unit_y())
|
||||
.component<renderer>(renderer().materials({model_mat}))
|
||||
.component<renderer>(renderer()
|
||||
.materials({model_mat})
|
||||
.translation({0.f, 0.f, 5.f}))
|
||||
.component<model_renderer>(model_res);
|
||||
|
||||
the<world>().instantiate(
|
||||
@@ -127,6 +115,8 @@ namespace
|
||||
{
|
||||
prefab prefab;
|
||||
prefab.prototype()
|
||||
.component<named>(named()
|
||||
.name("ship"))
|
||||
.component<node_rotator>()
|
||||
.component<renderer>()
|
||||
.component<sprite_renderer>(sprite_renderer(sprite_res)
|
||||
@@ -141,6 +131,8 @@ namespace
|
||||
{
|
||||
prefab prefab_a;
|
||||
prefab_a.prototype()
|
||||
.component<named>(named()
|
||||
.name("cube"))
|
||||
.component<node_rotator>()
|
||||
.component<renderer>()
|
||||
.component<sprite_renderer>(sprite_renderer()
|
||||
@@ -182,8 +174,7 @@ namespace
|
||||
ecs::registry_filler(the<world>().registry())
|
||||
.feature<struct game_feature>(ecs::feature()
|
||||
.add_system<game_system>()
|
||||
.add_system<rotator_system>()
|
||||
.add_system<camera_system>());
|
||||
.add_system<rotator_system>());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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<camera>(
|
||||
[](const ecs::const_entity&, camera& cam){
|
||||
if ( !cam.target() ) {
|
||||
cam.viewport(
|
||||
the<window>().framebuffer_size());
|
||||
cam.projection(math::make_orthogonal_lh_matrix4(
|
||||
the<window>().real_size().cast_to<f32>(), 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<world>().registry())
|
||||
.feature<struct game_feature>(ecs::feature()
|
||||
.add_system<game_system>()
|
||||
.add_system<camera_system>());
|
||||
.add_system<game_system>());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace
|
||||
void frame_render() final {
|
||||
the<render>().execute(render::command_block<64>()
|
||||
.add_command(render::viewport_command(
|
||||
the<window>().framebuffer_size()))
|
||||
the<window>().framebuffer_size().cast_to<i32>()))
|
||||
.add_command(render::clear_command()
|
||||
.color_value({1.f, 0.4f, 0.f, 1.f})));
|
||||
}
|
||||
|
||||
@@ -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<camera>(
|
||||
[](const ecs::const_entity&, camera& cam){
|
||||
if ( !cam.target() ) {
|
||||
cam.viewport(
|
||||
the<window>().framebuffer_size());
|
||||
cam.projection(math::make_orthogonal_lh_matrix4(
|
||||
the<window>().real_size().cast_to<f32>(), 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<world>().registry())
|
||||
.feature<struct game_feature>(ecs::feature()
|
||||
.add_system<game_system>()
|
||||
.add_system<camera_system>());
|
||||
.add_system<game_system>());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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<camera>(
|
||||
[](const ecs::const_entity&, camera& cam){
|
||||
if ( !cam.target() ) {
|
||||
cam.viewport(
|
||||
the<window>().framebuffer_size());
|
||||
cam.projection(math::make_orthogonal_lh_matrix4(
|
||||
the<window>().real_size().cast_to<f32>(), 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<world>().registry())
|
||||
.feature<struct game_feature>(ecs::feature()
|
||||
.add_system<game_system>()
|
||||
.add_system<camera_system>());
|
||||
.add_system<game_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<starter>(argc, argv, starter_params).start<game>();
|
||||
|
||||
@@ -9,22 +9,3 @@
|
||||
#include <enduro2d/core/audio.hpp>
|
||||
#include <enduro2d/core/debug.hpp>
|
||||
#include <enduro2d/core/profiler.hpp>
|
||||
|
||||
#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
|
||||
|
||||
@@ -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<u32>(),
|
||||
clip_r.cast_to<u32>()))
|
||||
framebuffer_size.cast_to<i32>(),
|
||||
clip_r.cast_to<i32>()))
|
||||
.add_command(render::draw_command(material_, geometry, mprops_)
|
||||
.index_range(first_index, pcmd.ElemCount)));
|
||||
}
|
||||
|
||||
@@ -8,28 +8,6 @@
|
||||
|
||||
#include <enduro2d/core/platform.hpp>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -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<platform_internal_state_impl_none>();
|
||||
return std::make_unique<platform_internal_state_impl_android>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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 <windows.h>
|
||||
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,25 +10,3 @@
|
||||
#include <enduro2d/core/profiler.hpp>
|
||||
#include <enduro2d/core/render.hpp>
|
||||
#include <enduro2d/core/window.hpp>
|
||||
|
||||
#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
|
||||
|
||||
@@ -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<GLint>(viewport.position.x),
|
||||
math::numeric_cast<GLint>(viewport.position.y),
|
||||
@@ -1040,7 +1040,7 @@ namespace e2d
|
||||
math::numeric_cast<GLsizei>(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<GLint>(scissor.position.x),
|
||||
math::numeric_cast<GLint>(scissor.position.y),
|
||||
|
||||
@@ -9,22 +9,3 @@
|
||||
#include <enduro2d/core/debug.hpp>
|
||||
#include <enduro2d/core/profiler.hpp>
|
||||
#include <enduro2d/core/window.hpp>
|
||||
|
||||
#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
|
||||
|
||||
@@ -58,12 +58,44 @@ namespace e2d::bindings::high
|
||||
c->depth(v);
|
||||
}),
|
||||
|
||||
"mode", sol::property(
|
||||
[](const gcomponent<camera>& c) -> camera::modes {
|
||||
return c->mode();
|
||||
},
|
||||
[](gcomponent<camera>& c, camera::modes v){
|
||||
c->mode(v);
|
||||
}),
|
||||
|
||||
"znear", sol::property(
|
||||
[](const gcomponent<camera>& c) -> f32 {
|
||||
return c->znear();
|
||||
},
|
||||
[](gcomponent<camera>& c, f32 v){
|
||||
c->znear(v);
|
||||
}),
|
||||
|
||||
"zfar", sol::property(
|
||||
[](const gcomponent<camera>& c) -> f32 {
|
||||
return c->zfar();
|
||||
},
|
||||
[](gcomponent<camera>& c, f32 v){
|
||||
c->zfar(v);
|
||||
}),
|
||||
|
||||
"view", sol::property(
|
||||
[](const gcomponent<camera>& c) -> m4f {
|
||||
return c->view();
|
||||
},
|
||||
[](gcomponent<camera>& c, const m4f& v){
|
||||
c->view(v);
|
||||
}),
|
||||
|
||||
"viewport", sol::property(
|
||||
[](const gcomponent<camera>& c) -> b2f {
|
||||
return c->viewport().cast_to<f32>();
|
||||
return c->viewport();
|
||||
},
|
||||
[](gcomponent<camera>& c, const b2f& v){
|
||||
c->viewport(v.cast_to<u32>());
|
||||
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<sol::table>()
|
||||
.new_enum<camera::modes>("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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,13 +66,13 @@ namespace
|
||||
"make_look_at_rh", sol::resolve<
|
||||
mat4<T>(const vec3<T>&,const vec3<T>&,const vec3<T>&)>(&math::make_look_at_rh_matrix4),
|
||||
|
||||
"make_orthogonal_lh", sol::overload(
|
||||
sol::resolve<mat4<T>(T,T,T,T)>(&math::make_orthogonal_lh_matrix4),
|
||||
sol::resolve<mat4<T>(const vec2<T>&,T,T)>(&math::make_orthogonal_lh_matrix4)),
|
||||
"make_orthographic_lh", sol::overload(
|
||||
sol::resolve<mat4<T>(T,T,T,T)>(&math::make_orthographic_lh_matrix4),
|
||||
sol::resolve<mat4<T>(const vec2<T>&,T,T)>(&math::make_orthographic_lh_matrix4)),
|
||||
|
||||
"make_orthogonal_rh", sol::overload(
|
||||
sol::resolve<mat4<T>(T,T,T,T)>(&math::make_orthogonal_rh_matrix4),
|
||||
sol::resolve<mat4<T>(const vec2<T>&,T,T)>(&math::make_orthogonal_rh_matrix4)),
|
||||
"make_orthographic_rh", sol::overload(
|
||||
sol::resolve<mat4<T>(T,T,T,T)>(&math::make_orthographic_rh_matrix4),
|
||||
sol::resolve<mat4<T>(const vec2<T>&,T,T)>(&math::make_orthographic_rh_matrix4)),
|
||||
|
||||
"make_perspective_lh", [](T angle, T aspect, T znear, T zfar) -> mat4<T> {
|
||||
return math::make_perspective_lh_matrix4(make_rad(angle), aspect, znear, zfar);
|
||||
|
||||
@@ -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<debug>().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<debug>().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<debug>().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<debug>().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<debug>().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<debug>().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<debug>().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<debug>().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<f32>::max()) )
|
||||
{
|
||||
c->viewport(viewport);
|
||||
}
|
||||
}
|
||||
|
||||
///TODO(BlackMat): add 'projection' inspector
|
||||
///TODO(BlackMat): add 'target' inspector
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace e2d
|
||||
|
||||
void component_inspector<renderer>::operator()(gcomponent<renderer>& c) const {
|
||||
if ( v3f translation = c->translation();
|
||||
ImGui::DragFloat3("translation", translation.data(), 1.f) )
|
||||
ImGui::DragFloat3("translation", translation.data(), 0.01f) )
|
||||
{
|
||||
c->translation(translation);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <enduro2d/high/components/spine_player.hpp>
|
||||
#include <enduro2d/high/components/sprite_renderer.hpp>
|
||||
|
||||
#include <enduro2d/high/systems/camera_system.hpp>
|
||||
#include <enduro2d/high/systems/flipbook_system.hpp>
|
||||
#include <enduro2d/high/systems/frame_system.hpp>
|
||||
#include <enduro2d/high/systems/gizmos_system.hpp>
|
||||
@@ -55,6 +56,8 @@ namespace
|
||||
|
||||
bool initialize() final {
|
||||
ecs::registry_filler(the<world>().registry())
|
||||
.feature<struct camera_feature>(ecs::feature()
|
||||
.add_system<camera_system>())
|
||||
.feature<struct flipbook_feature>(ecs::feature()
|
||||
.add_system<flipbook_system>())
|
||||
.feature<struct frame_feature>(ecs::feature()
|
||||
|
||||
126
sources/enduro2d/high/systems/camera_system.cpp
Normal file
126
sources/enduro2d/high/systems/camera_system.cpp
Normal file
@@ -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 <enduro2d/high/systems/camera_system.hpp>
|
||||
|
||||
#include <enduro2d/high/components/actor.hpp>
|
||||
#include <enduro2d/high/components/camera.hpp>
|
||||
|
||||
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<f32>());
|
||||
|
||||
const v2u target_size = camera.target()
|
||||
? camera.target()->size()
|
||||
: window.real_size();
|
||||
|
||||
const v2f virtual_size = window.virtual_size().cast_to<f32>();
|
||||
const v2f viewport_size = target_size.cast_to<f32>() * 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<camera, actor>([](
|
||||
const ecs::const_entity&,
|
||||
camera& c,
|
||||
const actor& a)
|
||||
{
|
||||
c.view(make_camera_view(a));
|
||||
});
|
||||
|
||||
owner.for_each_component<camera>([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<window>())) {}
|
||||
camera_system::~camera_system() noexcept = default;
|
||||
|
||||
void camera_system::process(
|
||||
ecs::registry& owner,
|
||||
const ecs::after<systems::update_event>& trigger)
|
||||
{
|
||||
E2D_UNUSED(trigger);
|
||||
E2D_PROFILER_SCOPE("camera_system.process_update");
|
||||
state_->process_update(owner);
|
||||
}
|
||||
}
|
||||
@@ -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<i32>()))
|
||||
.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<systems::pre_render_event>(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<engine>())) {}
|
||||
: state_(new internal_state(the<engine>(), the<render>(), the<window>())) {}
|
||||
frame_system::~frame_system() noexcept = default;
|
||||
|
||||
void frame_system::process(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<actor, camera>()(cam_e) ) {
|
||||
if ( !cam_e.valid() || !cam_e.exists_component<camera>() ) {
|
||||
return;
|
||||
}
|
||||
drawer_.with(
|
||||
cam_e.get_component<camera>(),
|
||||
cam_e.get_component<actor>().node(),
|
||||
[&owner](drawer::context& ctx){
|
||||
for_all_scenes(ctx, owner);
|
||||
});
|
||||
|
||||
@@ -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<m4f, bool> 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<f32>(),
|
||||
cam.viewport().size * target_size.cast_to<f32>());
|
||||
|
||||
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<i32>(),
|
||||
target_viewport.cast_to<i32>()))
|
||||
.add_command(render::clear_command()
|
||||
.color_value(cam.background())));
|
||||
}
|
||||
|
||||
@@ -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>(f)(ctx);
|
||||
ctx.flush();
|
||||
}
|
||||
|
||||
@@ -10,25 +10,6 @@
|
||||
#include <enduro2d/utils/strings.hpp>
|
||||
#include <enduro2d/utils/filesystem.hpp>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user