mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-14 16:09:06 +07:00
more flexible orthographic matrix
This commit is contained in:
@@ -534,57 +534,61 @@ namespace e2d::math
|
|||||||
{
|
{
|
||||||
template < typename T >
|
template < typename T >
|
||||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
||||||
make_orthographic_lh_zo_matrix4(T width, T height, T znear, T zfar) noexcept {
|
make_orthographic_lh_zo_matrix4(T left, T right, T bottom, T top, T znear, T zfar) noexcept {
|
||||||
E2D_ASSERT(!math::is_near_zero(width, T(0)));
|
E2D_ASSERT(!math::approximately(left, right, T(0)));
|
||||||
E2D_ASSERT(!math::is_near_zero(height, T(0)));
|
E2D_ASSERT(!math::approximately(bottom, top, T(0)));
|
||||||
E2D_ASSERT(!math::approximately(znear, zfar, T(0)));
|
E2D_ASSERT(!math::approximately(znear, zfar, T(0)));
|
||||||
const T sx = T(2) / width;
|
|
||||||
const T sy = T(2) / height;
|
const T sx = T(2) / (right - left);
|
||||||
|
const T sy = T(2) / (top - bottom);
|
||||||
const T sz = T(1) / (zfar - znear);
|
const T sz = T(1) / (zfar - znear);
|
||||||
const T tz = -znear / (zfar - znear);
|
|
||||||
|
const T tx = - (right + left) / (right - left);
|
||||||
|
const T ty = - (top + bottom) / (top - bottom);
|
||||||
|
const T tz = - znear / (zfar - znear);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sx, T(0), T(0), T(0),
|
sx, T(0), T(0), T(0),
|
||||||
T(0), sy, T(0), T(0),
|
T(0), sy, T(0), T(0),
|
||||||
T(0), T(0), sz, T(0),
|
T(0), T(0), sz, T(0),
|
||||||
T(0), T(0), tz, T(1)};
|
tx, ty, tz, T(1)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
||||||
make_orthographic_lh_no_matrix4(T width, T height, T znear, T zfar) noexcept {
|
make_orthographic_lh_no_matrix4(T left, T right, T bottom, T top, T znear, T zfar) noexcept {
|
||||||
E2D_ASSERT(!math::is_near_zero(width, T(0)));
|
E2D_ASSERT(!math::approximately(left, right, T(0)));
|
||||||
E2D_ASSERT(!math::is_near_zero(height, T(0)));
|
E2D_ASSERT(!math::approximately(bottom, top, T(0)));
|
||||||
E2D_ASSERT(!math::approximately(znear, zfar, T(0)));
|
E2D_ASSERT(!math::approximately(znear, zfar, T(0)));
|
||||||
const T sx = T(2) / width;
|
|
||||||
const T sy = T(2) / height;
|
const T sx = T(2) / (right - left);
|
||||||
|
const T sy = T(2) / (top - bottom);
|
||||||
const T sz = T(2) / (zfar - znear);
|
const T sz = T(2) / (zfar - znear);
|
||||||
const T tz = -(zfar + znear) / (zfar - znear);
|
|
||||||
|
const T tx = - (right + left) / (right - left);
|
||||||
|
const T ty = - (top + bottom) / (top - bottom);
|
||||||
|
const T tz = - (zfar + znear) / (zfar - znear);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sx, T(0), T(0), T(0),
|
sx, T(0), T(0), T(0),
|
||||||
T(0), sy, T(0), T(0),
|
T(0), sy, T(0), T(0),
|
||||||
T(0), T(0), sz, T(0),
|
T(0), T(0), sz, T(0),
|
||||||
T(0), T(0), tz, T(1)};
|
tx, ty, tz, T(1)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<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 {
|
make_orthographic_lh_matrix4(T left, T right, T bottom, T top, T znear, T zfar) noexcept {
|
||||||
#if defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_ZO
|
#if defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_ZO
|
||||||
return impl::make_orthographic_lh_zo_matrix4(width, height, znear, zfar);
|
return impl::make_orthographic_lh_zo_matrix4(left, right, bottom, top, znear, zfar);
|
||||||
#elif defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_NO
|
#elif defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_NO
|
||||||
return impl::make_orthographic_lh_no_matrix4(width, height, znear, zfar);
|
return impl::make_orthographic_lh_no_matrix4(left, right, bottom, top, znear, zfar);
|
||||||
#else
|
#else
|
||||||
# error "E2D_CLIPPING_MODE not detected"
|
# error "E2D_CLIPPING_MODE not detected"
|
||||||
#endif
|
#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
|
// make_orthographic_rh_matrix4
|
||||||
//
|
//
|
||||||
@@ -593,57 +597,61 @@ namespace e2d::math
|
|||||||
{
|
{
|
||||||
template < typename T >
|
template < typename T >
|
||||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<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 {
|
make_orthographic_rh_zo_matrix4(T left, T right, T bottom, T top, T znear, T zfar) noexcept {
|
||||||
E2D_ASSERT(!math::is_near_zero(width, T(0)));
|
E2D_ASSERT(!math::approximately(left, right, T(0)));
|
||||||
E2D_ASSERT(!math::is_near_zero(height, T(0)));
|
E2D_ASSERT(!math::approximately(bottom, top, T(0)));
|
||||||
E2D_ASSERT(!math::approximately(znear, zfar, T(0)));
|
E2D_ASSERT(!math::approximately(znear, zfar, T(0)));
|
||||||
const T sx = T(2) / width;
|
|
||||||
const T sy = T(2) / height;
|
const T sx = T(2) / (right - left);
|
||||||
|
const T sy = T(2) / (top - bottom);
|
||||||
const T sz = T(-1) / (zfar - znear);
|
const T sz = T(-1) / (zfar - znear);
|
||||||
const T tz = -znear / (zfar - znear);
|
|
||||||
|
const T tx = - (right + left) / (right - left);
|
||||||
|
const T ty = - (top + bottom) / (top - bottom);
|
||||||
|
const T tz = - znear / (zfar - znear);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sx, T(0), T(0), T(0),
|
sx, T(0), T(0), T(0),
|
||||||
T(0), sy, T(0), T(0),
|
T(0), sy, T(0), T(0),
|
||||||
T(0), T(0), sz, T(0),
|
T(0), T(0), sz, T(0),
|
||||||
T(0), T(0), tz, T(1)};
|
tx, ty, tz, T(1)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
||||||
make_orthographic_rh_no_matrix4(T width, T height, T znear, T zfar) noexcept {
|
make_orthographic_rh_no_matrix4(T left, T right, T bottom, T top, T znear, T zfar) noexcept {
|
||||||
E2D_ASSERT(!math::is_near_zero(width, T(0)));
|
E2D_ASSERT(!math::approximately(left, right, T(0)));
|
||||||
E2D_ASSERT(!math::is_near_zero(height, T(0)));
|
E2D_ASSERT(!math::approximately(bottom, top, T(0)));
|
||||||
E2D_ASSERT(!math::approximately(znear, zfar, T(0)));
|
E2D_ASSERT(!math::approximately(znear, zfar, T(0)));
|
||||||
const T sx = T(2) / width;
|
|
||||||
const T sy = T(2) / height;
|
const T sx = T(2) / (right - left);
|
||||||
|
const T sy = T(2) / (top - bottom);
|
||||||
const T sz = T(-2) / (zfar - znear);
|
const T sz = T(-2) / (zfar - znear);
|
||||||
const T tz = -(zfar + znear) / (zfar - znear);
|
|
||||||
|
const T tx = - (right + left) / (right - left);
|
||||||
|
const T ty = - (top + bottom) / (top - bottom);
|
||||||
|
const T tz = - (zfar + znear) / (zfar - znear);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sx, T(0), T(0), T(0),
|
sx, T(0), T(0), T(0),
|
||||||
T(0), sy, T(0), T(0),
|
T(0), sy, T(0), T(0),
|
||||||
T(0), T(0), sz, T(0),
|
T(0), T(0), sz, T(0),
|
||||||
T(0), T(0), tz, T(1)};
|
tx, ty, tz, T(1)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<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 {
|
make_orthographic_rh_matrix4(T left, T right, T bottom, T top, T znear, T zfar) noexcept {
|
||||||
#if defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_ZO
|
#if defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_ZO
|
||||||
return impl::make_orthographic_rh_zo_matrix4(width, height, znear, zfar);
|
return impl::make_orthographic_rh_zo_matrix4(left, right, bottom, top, znear, zfar);
|
||||||
#elif defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_NO
|
#elif defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_NO
|
||||||
return impl::make_orthographic_rh_no_matrix4(width, height, znear, zfar);
|
return impl::make_orthographic_rh_no_matrix4(left, right, bottom, top, znear, zfar);
|
||||||
#else
|
#else
|
||||||
# error "E2D_CLIPPING_MODE not detected"
|
# error "E2D_CLIPPING_MODE not detected"
|
||||||
#endif
|
#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
|
// make_perspective_lh_matrix4
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -50,15 +50,23 @@ function m4f.make_look_at_lh(eye, at, up) end
|
|||||||
---@return m4f
|
---@return m4f
|
||||||
function m4f.make_look_at_rh(eye, at, up) end
|
function m4f.make_look_at_rh(eye, at, up) end
|
||||||
|
|
||||||
---@overload fun(width: number, height: number, znear: number, zfar: number): m4f
|
---@param left number
|
||||||
---@overload fun(size: v2f, znear: number, zfar: number): m4f
|
---@param right number
|
||||||
|
---@param bottom number
|
||||||
|
---@param top number
|
||||||
|
---@param znear number
|
||||||
|
---@param zfar number
|
||||||
---@return m4f
|
---@return m4f
|
||||||
function m4f.make_orthographic_lh(...) end
|
function m4f.make_orthographic_lh(left, right, bottom, top, znear, zfar) end
|
||||||
|
|
||||||
---@overload fun(width: number, height: number, znear: number, zfar: number): m4f
|
---@param left number
|
||||||
---@overload fun(size: v2f, znear: number, zfar: number): m4f
|
---@param right number
|
||||||
|
---@param bottom number
|
||||||
|
---@param top number
|
||||||
|
---@param znear number
|
||||||
|
---@param zfar number
|
||||||
---@return m4f
|
---@return m4f
|
||||||
function m4f.make_orthographic_rh(...) end
|
function m4f.make_orthographic_rh(left, right, bottom, top, znear, zfar) end
|
||||||
|
|
||||||
---@param angle number
|
---@param angle number
|
||||||
---@param aspect number
|
---@param aspect number
|
||||||
|
|||||||
@@ -128,9 +128,10 @@ namespace e2d
|
|||||||
const v2f display_size = draw_data->DisplaySize;
|
const v2f display_size = draw_data->DisplaySize;
|
||||||
const v2f framebuffer_size = display_size * v2f(draw_data->FramebufferScale);
|
const v2f framebuffer_size = display_size * v2f(draw_data->FramebufferScale);
|
||||||
|
|
||||||
const m4f projection =
|
const m4f projection = math::make_orthographic_lh_matrix4(
|
||||||
math::make_orthographic_lh_matrix4(display_size, 0.f, 1.f) *
|
0.f, display_size.x,
|
||||||
math::make_translation_matrix4(-1.f, 1.f);
|
display_size.y, 0.f,
|
||||||
|
-1.f, 1.f);
|
||||||
|
|
||||||
for ( int i = 0; i < draw_data->CmdListsCount; ++i ) {
|
for ( int i = 0; i < draw_data->CmdListsCount; ++i ) {
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[i];
|
const ImDrawList* cmd_list = draw_data->CmdLists[i];
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace
|
|||||||
void main(){
|
void main(){
|
||||||
v_color = a_color;
|
v_color = a_color;
|
||||||
v_uv = a_uv;
|
v_uv = a_uv;
|
||||||
gl_Position = vec4(a_position.x, -a_position.y, 0.0, 1.0) * u_MVP;
|
gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0) * u_MVP;
|
||||||
}
|
}
|
||||||
)glsl";
|
)glsl";
|
||||||
|
|
||||||
|
|||||||
@@ -67,12 +67,10 @@ namespace
|
|||||||
mat4<T>(const vec3<T>&,const vec3<T>&,const vec3<T>&)>(&math::make_look_at_rh_matrix4),
|
mat4<T>(const vec3<T>&,const vec3<T>&,const vec3<T>&)>(&math::make_look_at_rh_matrix4),
|
||||||
|
|
||||||
"make_orthographic_lh", sol::overload(
|
"make_orthographic_lh", sol::overload(
|
||||||
sol::resolve<mat4<T>(T,T,T,T)>(&math::make_orthographic_lh_matrix4),
|
sol::resolve<mat4<T>(T,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_orthographic_rh", sol::overload(
|
"make_orthographic_rh", sol::overload(
|
||||||
sol::resolve<mat4<T>(T,T,T,T)>(&math::make_orthographic_rh_matrix4),
|
sol::resolve<mat4<T>(T,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> {
|
"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);
|
return math::make_perspective_lh_matrix4(make_rad(angle), aspect, znear, zfar);
|
||||||
|
|||||||
@@ -19,6 +19,14 @@ namespace
|
|||||||
: m4f::identity();
|
: m4f::identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m4f make_camera_orthographic(const v2f& size, f32 znear, f32 zfar) noexcept {
|
||||||
|
return
|
||||||
|
math::make_orthographic_lh_matrix4(
|
||||||
|
-0.5f * size.x, 0.5f * size.x,
|
||||||
|
-0.5f * size.y, 0.5f * size.y,
|
||||||
|
znear, zfar);
|
||||||
|
}
|
||||||
|
|
||||||
m4f make_camera_projection(const camera& camera, const window& window) noexcept {
|
m4f make_camera_projection(const camera& camera, const window& window) noexcept {
|
||||||
const f32 ortho_znear = camera.znear();
|
const f32 ortho_znear = camera.znear();
|
||||||
const f32 ortho_zfar = math::max(
|
const f32 ortho_zfar = math::max(
|
||||||
@@ -45,24 +53,24 @@ namespace
|
|||||||
case camera::modes::manual:
|
case camera::modes::manual:
|
||||||
return camera.projection();
|
return camera.projection();
|
||||||
case camera::modes::stretch:
|
case camera::modes::stretch:
|
||||||
return math::make_orthographic_lh_matrix4(
|
return make_camera_orthographic(
|
||||||
virtual_size,
|
virtual_size,
|
||||||
ortho_znear,
|
ortho_znear,
|
||||||
ortho_zfar);
|
ortho_zfar);
|
||||||
case camera::modes::flexible:
|
case camera::modes::flexible:
|
||||||
return math::make_orthographic_lh_matrix4(
|
return make_camera_orthographic(
|
||||||
viewport_size,
|
viewport_size,
|
||||||
ortho_znear,
|
ortho_znear,
|
||||||
ortho_zfar);
|
ortho_zfar);
|
||||||
case camera::modes::fixed_fit:
|
case camera::modes::fixed_fit:
|
||||||
return math::make_orthographic_lh_matrix4(
|
return make_camera_orthographic(
|
||||||
viewport_aspect < virtual_aspect
|
viewport_aspect < virtual_aspect
|
||||||
? v2f(virtual_size.x, virtual_size.y * (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),
|
: v2f(virtual_size.x * (viewport_aspect / virtual_aspect), virtual_size.y),
|
||||||
ortho_znear,
|
ortho_znear,
|
||||||
ortho_zfar);
|
ortho_zfar);
|
||||||
case camera::modes::fixed_crop:
|
case camera::modes::fixed_crop:
|
||||||
return math::make_orthographic_lh_matrix4(
|
return make_camera_orthographic(
|
||||||
virtual_aspect < viewport_aspect
|
virtual_aspect < viewport_aspect
|
||||||
? v2f(virtual_size.x, virtual_size.y * (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),
|
: v2f(virtual_size.x * (viewport_aspect / virtual_aspect), virtual_size.y),
|
||||||
|
|||||||
@@ -27,15 +27,12 @@ namespace
|
|||||||
, inspector_(i) {}
|
, inspector_(i) {}
|
||||||
|
|
||||||
bool setup_camera(const ecs::const_entity& cam_e) {
|
bool setup_camera(const ecs::const_entity& cam_e) {
|
||||||
if ( !cam_e.valid() || !ecs::exists_all<actor, camera, camera::gizmos>()(cam_e) ) {
|
if ( !cam_e.valid() || !ecs::exists_all<camera, camera::gizmos>()(cam_e) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const camera& cam = cam_e.get_component<camera>();
|
const camera& cam = cam_e.get_component<camera>();
|
||||||
const actor& cam_a = cam_e.get_component<actor>();
|
if ( cam.target() ) {
|
||||||
|
|
||||||
const const_node_iptr& cam_n = cam_a.node();
|
|
||||||
if ( !cam_n ) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user