- Setup EGL context for Wayland. Test window now opens as black rectangle.

This commit is contained in:
2025-12-15 13:20:08 -05:00
parent 5dcb58f53c
commit 1acf00138a
36 changed files with 992 additions and 80 deletions

View File

@@ -84,7 +84,9 @@ add_library(fennec STATIC
# CORE ================================================================================================================= # CORE =================================================================================================================
include/fennec/core/engine.h source/core/engine.cpp include/fennec/core/engine.h source/core/engine.cpp
include/fennec/core/event.h source/core/event.cpp include/fennec/core/event.h source/core/event.cpp
include/fennec/core/logger.h source/core/logger.cpp
include/fennec/core/version.h
include/fennec/core/system.h include/fennec/core/system.h
@@ -273,9 +275,9 @@ add_library(fennec STATIC
# PLATFORM ============================================================================================================= # PLATFORM =============================================================================================================
include/fennec/platform/interface/fwd.h include/fennec/platform/interface/fwd.h
include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp
include/fennec/platform/interface/display_server.h include/fennec/platform/interface/display_server.h
include/fennec/platform/interface/window.h include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp
include/fennec/platform/interface/window.h source/platform/interface/window.cpp
# GRAPHICS ============================================================================================================= # GRAPHICS =============================================================================================================
@@ -284,11 +286,7 @@ add_library(fennec STATIC
# EXTRA SOURCES ======================================================================================================== # EXTRA SOURCES ========================================================================================================
${FENNEC_EXTRA_SOURCES} ${FENNEC_EXTRA_SOURCES}
source/platform/linux/wayland/window.cpp
source/platform/interface/window.cpp
include/fennec/core/logger.h
source/core/log.cpp
source/core/logger.cpp
) )
add_dependencies(fennec metaprogramming fennec-dependencies) add_dependencies(fennec metaprogramming fennec-dependencies)

View File

@@ -16,19 +16,31 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# ====================================================================================================================== # ======================================================================================================================
find_package(OpenGL)
if(FENNEC_GRAPHICS_WANT_EGL) if(FENNEC_GRAPHICS_WANT_EGL)
find_package(OpenGL REQUIRED COMPONENTS EGL) find_package(OpenGL REQUIRED COMPONENTS EGL)
find_package(GLEW REQUIRED)
message(STATUS "EGL Requested") message(STATUS "EGL Requested")
else()
find_package(OpenGL) fennec_add_link_libraries(OpenGL::EGL)
find_package(GLEW REQUIRED)
fennec_add_sources(
include/fennec/platform/opengl/egl/fwd.h
include/fennec/platform/opengl/egl/context.h source/platform/opengl/egl/context.cpp
include/fennec/platform/opengl/egl/surface.h source/platform/opengl/egl/surface.cpp
)
endif() endif()
find_package(GLEW REQUIRED)
if(TARGET OpenGL::GL AND TARGET GLEW::GLEW) if(TARGET OpenGL::GL AND TARGET GLEW::GLEW)
message(STATUS "Found OpenGL: ${OPENGL_gl_LIBRARY}") message(STATUS "Found OpenGL: ${OPENGL_gl_LIBRARY}")
fennec_add_link_libraries(OpenGL::GL GLEW::GLEW) fennec_add_link_libraries(OpenGL::GL GLEW::GLEW)
fennec_add_definitions(FENNEC_GRAPHICS_OPENGL=1) fennec_add_definitions(FENNEC_GRAPHICS_OPENGL=1)
fennec_add_sources(
include/fennec/renderers/opengl/glcontext.h source/renderers/opengl/glcontext.cpp
)
else() else()
message(FATAL_ERROR "No Suitable OpenGL implementation found.") message(FATAL_ERROR "No Suitable OpenGL implementation found.")
endif() endif()

View File

@@ -109,8 +109,13 @@ macro(fennec_check_wayland)
include/fennec/platform/linux/wayland/lib/loader.h source/platform/linux/wayland/lib/loader.cpp include/fennec/platform/linux/wayland/lib/loader.h source/platform/linux/wayland/lib/loader.cpp
# Fennec Files # Fennec Files
include/fennec/platform/linux/wayland/window.h include/fennec/platform/linux/wayland/fwd.h
include/fennec/platform/linux/wayland/server.h source/platform/linux/wayland/server.cpp include/fennec/platform/linux/wayland/server.h source/platform/linux/wayland/server.cpp
include/fennec/platform/linux/wayland/window.h source/platform/linux/wayland/window.cpp
# EGL
include/fennec/platform/linux/wayland/egl/context.h source/platform/linux/wayland/egl/context.cpp
include/fennec/platform/linux/wayland/egl/surface.h source/platform/linux/wayland/egl/surface.cpp
) )
fennec_add_definitions( fennec_add_definitions(

View File

@@ -16,23 +16,33 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
#ifndef FENNEC_TEST_LANG_SEQUENCES_H ///
#define FENNEC_TEST_LANG_SEQUENCES_H /// \file version.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#include <fennec/lang/const_sequences.h>
namespace fennec::test #ifndef FENNEC_CORE_VERSION_H
#define FENNEC_CORE_VERSION_H
#include <fennec/lang/types.h>
#include <fennec/string/string.h>
namespace fennec
{ {
inline void test_sequences() struct version {
{ uint32_t major, minor, patch;
static_assert(fennec::is_same_v<make_index_sequence_t<2>, const_index_sequence<0, 1>>); string str;
static_assert(fennec::is_same_v<make_index_sequence_t<3>, const_index_sequence<0, 1, 2>>); };
static_assert(fennec::is_same_v<make_index_sequence_t<4>, const_index_sequence<0, 1, 2, 3>>);
// TODO
}
} }
#endif // FENNEC_TEST_LANG_SEQUENCES_H #endif // FENNEC_CORE_VERSION_H

View File

@@ -133,6 +133,13 @@ namespace fennec::detail
template<typename T> template<typename T>
auto _is_mappable(...) -> false_type; auto _is_mappable(...) -> false_type;
template<typename B> auto _ptr_conv(const volatile B*) -> true_type;
template<typename> auto _ptr_conv(const volatile void*) -> false_type;
template<typename B, typename D> auto _is_base_of(int) -> decltype(detail::_ptr_conv<B>(static_cast<D*>(nullptr)));
template<typename, typename> auto _is_base_of(...) -> false_type;
} }
#endif // FENNEC_LANG_DETAIL_TYPE_TRAITS_H #endif // FENNEC_LANG_DETAIL_TYPE_TRAITS_H

View File

@@ -790,6 +790,25 @@ template<typename T> struct is_same<T, T> : true_type {};
/// \tparam T1 second type to check /// \tparam T1 second type to check
template<typename T0, typename T1> constexpr bool_t is_same_v = is_same<T0, T1> {}; template<typename T0, typename T1> constexpr bool_t is_same_v = is_same<T0, T1> {};
// fennec::is_base_of =====================================================================================================
///
/// \brief Check if `Derived` has a base type of `Base`
///
/// \details Checks if `Base` is a base type of `Derived` and stores it in `is_base_of::value`
/// \tparam Base base type to check
/// \tparam Derived derived type to check
template<typename Base, typename Derived> struct is_base_of : bool_constant<
is_class_v<Base> and is_class_v<Derived> and decltype(detail::_is_base_of<Base, Derived>(0))::value
> {};
///
/// \brief Shorthand for ```is_base_of<T0, T1>::value```
/// \tparam Base base type to check
/// \tparam Derived derived type to check
template<typename Base, typename Derived> constexpr bool_t is_base_of_v = is_base_of<Base, Derived> {};
// fennec::is_complete ============================================================================================== // fennec::is_complete ==============================================================================================
/// ///

View File

@@ -128,7 +128,7 @@ public:
/// ///
/// \brief Default Constructor, if it owns a resource, it deletes it using `delete_t` /// \brief Default Constructor, if it owns a resource, it deletes it using `delete_t`
constexpr ~unique_ptr() { constexpr ~unique_ptr() {
if(_handle) _delete(_handle); reset();
} }
constexpr unique_ptr& operator=(const unique_ptr&) = delete; constexpr unique_ptr& operator=(const unique_ptr&) = delete;
@@ -140,6 +140,20 @@ public:
return *this; return *this;
} }
void reset(pointer_t ptr) {
if(_handle) {
_delete(_handle);
_handle = ptr;
}
}
void reset(nullptr_t = nullptr) {
if(_handle) {
_delete(_handle);
_handle = nullptr;
}
}
pointer_t release() { pointer_t release() {
pointer_t retval = _handle; pointer_t retval = _handle;
_handle = nullptr; _handle = nullptr;

View File

@@ -40,6 +40,16 @@
namespace fennec namespace fennec
{ {
class display_server;
///
/// \brief Interface resembling the API for a display server of an operating system, e.g. Linux X11/Wayland
///
/// \details An implementation for a display server should inherit `display_server_base` and note the following:
///
/// For a server type `DisplayT`; any `gfxcontext` implementation that wishes to implement `DisplayT`
/// must provide a constructor that accepts a `DisplayT*`. `DisplayT::ctx_registry::register_type` must then be
/// called for the `gfxcontext` implementation.
class display_server : public type_registry<display_server, platform*> { class display_server : public type_registry<display_server, platform*> {
// Typedefs/Constants/Enums ============================================================================================ // Typedefs/Constants/Enums ============================================================================================
public: public:
@@ -99,6 +109,9 @@ enum feature_ : uint32_t {
return features.test(feature); return features.test(feature);
} }
gfxcontext* get_gfx_context() {
return gfx_context;
}
virtual window* create_window(const window::config& conf) = 0; virtual window* create_window(const window::config& conf) = 0;
@@ -110,16 +123,31 @@ enum feature_ : uint32_t {
virtual void disconnect() = 0; virtual void disconnect() = 0;
virtual bool connected() const = 0; virtual bool connected() const = 0;
virtual void dispatch() = 0;
virtual void* get_native_handle() = 0;
protected: protected:
featureset_t features; featureset_t features;
object_pool<window*> windows; object_pool<window*> windows;
gfxcontext* gfx_context;
FENNEC_RTTI_CLASS_ENABLE() { FENNEC_RTTI_CLASS_ENABLE() {
} }
}; };
template<typename DisplayT, typename WindowT>
class display_server_base : public display_server, public type_registry<gfxcontext, DisplayT*> {
public:
display_server_base(fennec::platform* p)
: display_server(p) {
}
using ctx_registry = type_registry<gfxcontext, DisplayT*>;
using window_t = WindowT;
};
} }
#endif // FENNEC_PLATFORM_INTERFACE_DISPLAY_SERVER_H #endif // FENNEC_PLATFORM_INTERFACE_DISPLAY_SERVER_H

View File

@@ -25,7 +25,9 @@ namespace fennec
class platform; class platform;
class display_server; // The display server used by the OS, e.g. WDM, Wayland, X11, etc. class display_server; // The display server used by the OS, e.g. WDM, Wayland, X11, etc.
class gfxcontext; // Handles the GFX API context of a display server, e.g. OpenGL, Vulkan, etc.
class window; // Handles window surfaces of the display protocol class window; // Handles window surfaces of the display protocol
class gfxsurface; // Handles the GFX surface of a window for a specific gfxcontext
} }

View File

@@ -105,6 +105,10 @@ public:
window* get_parent() const; window* get_parent() const;
const ivec2& get_size() const { return cfg.size; }
int get_width() const { return cfg.size.x; }
int get_height() const { return cfg.size.y; }
bool get_flag(uint8_t flag) const { return cfg.flags.test(flag); } bool get_flag(uint8_t flag) const { return cfg.flags.test(flag); }
bool is_always_on_top() const { return get_flag(flag_always_on_top); } bool is_always_on_top() const { return get_flag(flag_always_on_top); }
@@ -120,6 +124,7 @@ public:
bool is_running() const { return get_flag(flag_running); } bool is_running() const { return get_flag(flag_running); }
bool is_no_focus() const { return get_flag(flag_no_focus); } bool is_no_focus() const { return get_flag(flag_no_focus); }
virtual bool set_flag(uint8_t flag, bool val) = 0; virtual bool set_flag(uint8_t flag, bool val) = 0;
bool set_always_on_top(bool val) { return set_flag(flag_always_on_top, val); } bool set_always_on_top(bool val) { return set_flag(flag_always_on_top, val); }
@@ -135,13 +140,27 @@ public:
virtual void show() = 0; virtual void show() = 0;
virtual void hide() = 0; virtual void hide() = 0;
virtual void dispatch() = 0; virtual void begin_frame();
virtual void end_frame();
virtual void* get_native_handle() = 0;
protected: protected:
display_server* const server; display_server* const server;
const size_t id; const size_t id;
config cfg; config cfg;
window* root; window* root;
gfxsurface* gfx_surface;
};
template<typename DisplayT>
class window_base : public window {
public:
window_base(display_server* display, size_t id, const config& conf)
: window(display, id, conf) {
}
using display_t = DisplayT;
}; };
} }

View File

@@ -0,0 +1,55 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file context.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_EGL_CONTEXT_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_EGL_CONTEXT_H
#include <fennec/platform/opengl/egl/context.h>
namespace fennec
{
class wayland_eglcontext : public eglcontext {
public:
explicit wayland_eglcontext(display_server* display);
~wayland_eglcontext();
gfxsurface* create_surface(window* window) override;
private:
FENNEC_RTTI_CLASS_ENABLE(eglcontext) {
wayland_server::ctx_registry::register_type<wayland_eglcontext>();
}
};
}
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_EGL_CONTEXT_H

View File

@@ -0,0 +1,53 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file surface.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef LATFORM_LINUX_WAYLAND_EGL_SURFACE_H
#define LATFORM_LINUX_WAYLAND_EGL_SURFACE_H
#include <fennec/platform/opengl/egl/surface.h>
#include <fennec/platform/linux/wayland/fwd.h>
namespace fennec
{
class wayland_eglsurface : public eglsurface {
public:
wayland_eglsurface(wayland_window* win, eglcontext* ctx);
~wayland_eglsurface();
void resize(const ivec2& size) override;
private:
};
}
#endif // LATFORM_LINUX_WAYLAND_EGL_SURFACE_H

View File

@@ -0,0 +1,43 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file fwd.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H
namespace fennec
{
class wayland_server;
class wayland_window;
}
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H

View File

@@ -31,6 +31,7 @@
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_SERVER_H #ifndef FENNEC_PLATFORM_LINUX_WAYLAND_SERVER_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_SERVER_H #define FENNEC_PLATFORM_LINUX_WAYLAND_SERVER_H
#include <fennec/platform/linux/wayland/fwd.h>
#include <fennec/platform/interface/display_server.h> #include <fennec/platform/interface/display_server.h>
// forward defs to avoid flooding global namespace // forward defs to avoid flooding global namespace
@@ -46,7 +47,9 @@ struct xdg_wm_base;
namespace fennec namespace fennec
{ {
class wayland_server : public display_server { ///
/// \brief Class for handling the Wayland Display Server
class wayland_server : public display_server_base<wayland_server, wayland_window> {
public: public:
explicit wayland_server(fennec::platform* p); explicit wayland_server(fennec::platform* p);
~wayland_server() override; ~wayland_server() override;
@@ -55,8 +58,12 @@ public:
void disconnect() override; void disconnect() override;
bool connected() const override; bool connected() const override;
void dispatch() override;
window* create_window(const window::config& conf) override; window* create_window(const window::config& conf) override;
void* get_native_handle() override { return display; }
private: private:
wl_display* display; wl_display* display;
wl_registry* registry; wl_registry* registry;

View File

@@ -31,6 +31,7 @@
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H #ifndef FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H #define FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
#include <fennec/platform/linux/wayland/fwd.h>
#include <fennec/platform/interface/window.h> #include <fennec/platform/interface/window.h>
struct wl_array; struct wl_array;
@@ -44,7 +45,7 @@ struct xdg_toplevel;
namespace fennec namespace fennec
{ {
class wayland_window : public window { class wayland_window : public window_base<wayland_server> {
public: public:
wayland_window(display_server* server, uint32_t id, const config& cfg); wayland_window(display_server* server, uint32_t id, const config& cfg);
~wayland_window(); ~wayland_window();
@@ -52,7 +53,7 @@ public:
void show() override; void show() override;
void hide() override; void hide() override;
void dispatch() override; void* get_native_handle() override;
bool set_flag(uint8_t flag, bool val) override; bool set_flag(uint8_t flag, bool val) override;

View File

@@ -0,0 +1,65 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file context.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_OPENGL_EGLCONTEXT_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_OPENGL_EGLCONTEXT_H
#include <EGL/egl.h>
#include <fennec/platform/linux/wayland/server.h>
#include <fennec/renderers/opengl/glcontext.h>
namespace fennec
{
class eglcontext : public glcontext {
public:
eglcontext(display_server* display);
~eglcontext();
bool is_valid() override;
private:
EGLDisplay _egldisplay;
EGLContext _eglcontext;
EGLConfig _eglconfig;
EGLint _eglvmajor, _eglvminor, _eglctype;
cstring _extensions;
FENNEC_RTTI_CLASS_ENABLE(glcontext) {
}
friend class eglsurface;
};
}
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_OPENGL_EGLCONTEXT_H

View File

@@ -17,7 +17,7 @@
// ===================================================================================================================== // =====================================================================================================================
/// ///
/// \file log.h /// \file fwd.h
/// \brief /// \brief
/// ///
/// ///
@@ -26,4 +26,18 @@
/// ///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) /// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
/// ///
/// ///
#ifndef FENNEC_PLATFORM_OPENGL_EGL_FWD_H
#define FENNEC_PLATFORM_OPENGL_EGL_FWD_H
namespace fennec
{
class eglcontext;
class eglsurface;
}
#endif // FENNEC_PLATFORM_OPENGL_EGL_FWD_H

View File

@@ -0,0 +1,58 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file surface.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H
#define FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H
#include <EGL/egl.h>
#include <fennec/platform/opengl/egl/fwd.h>
#include <fennec/renderers/interface/gfxsurface.h>
namespace fennec
{
class eglsurface : public gfxsurface {
public:
eglsurface(fennec::window* win, eglcontext* ctx, EGLNativeWindowType eglwindow);
~eglsurface();
void make_current() override;
void swap() override;
protected:
EGLNativeWindowType _eglwindow;
EGLSurface _eglsurface;
};
} // fennec
#endif // FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H

View File

@@ -31,7 +31,9 @@
#ifndef FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H #ifndef FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H
#define FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H #define FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H
#include <fennec/core/version.h>
#include <fennec/lang/types.h> #include <fennec/lang/types.h>
#include <fennec/platform/interface/display_server.h>
#include <fennec/string/string.h> #include <fennec/string/string.h>
#include <fennec/renderers/interface/forward.h> #include <fennec/renderers/interface/forward.h>
#include <fennec/renderers/interface/gfxresourcepool.h> #include <fennec/renderers/interface/gfxresourcepool.h>
@@ -55,22 +57,31 @@ public:
using handle_t = uint32_t; using handle_t = uint32_t;
struct version_t {
uint8_t major, minor, patch;
string str;
};
const version_t version;
gfxresourcepool resources; gfxresourcepool resources;
gfxcontext(display_server* display)
: display(display)
, version(0, 0, 0, string("")) {
}
virtual ~gfxcontext() = default;
gfxcontext& operator=(const gfxcontext&) = delete; gfxcontext& operator=(const gfxcontext&) = delete;
gfxcontext& operator=(gfxcontext&&) = delete; gfxcontext& operator=(gfxcontext&&) = delete;
virtual gfxpass* create_pass() = 0; virtual bool is_valid() = 0;
virtual gfxsurface* create_surface(window* window) = 0;
virtual gfxpass* create_pass() = 0;
virtual const version& get_version() const { return version; };
protected: protected:
display_server* display;
version version;
private: FENNEC_RTTI_CLASS_ENABLE() {
}
}; };
} }

View File

@@ -0,0 +1,60 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file gfxcontext.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_RENDERERS_INTERFACE_GFXSURFACE_H
#define FENNEC_RENDERERS_INTERFACE_GFXSURFACE_H
#include <fennec/platform/interface/window.h>
namespace fennec
{
class gfxsurface {
public:
virtual ~gfxsurface() = default;
gfxsurface(window* win, gfxcontext* ctx)
: window(win), context(ctx) {
}
virtual void make_current() = 0;
virtual void swap() = 0;
virtual void resize(const ivec2& size) = 0;
protected:
window* window;
gfxcontext* context;
};
}
#endif // FENNEC_RENDERERS_INTERFACE_GFXSURFACE_H

View File

@@ -0,0 +1,54 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file glcontext.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_RENDERERS_OPENGL_GLCONTEXT_H
#define FENNEC_RENDERERS_OPENGL_GLCONTEXT_H
#include <fennec/renderers/interface/gfxcontext.h>
namespace fennec
{
class glcontext : public gfxcontext {
public:
explicit glcontext(display_server* display)
: gfxcontext(display) {
}
gfxpass* create_pass() override;
private:
FENNEC_RTTI_CLASS_ENABLE(gfxcontext) {
}
};
}
#endif // FENNEC_RENDERERS_OPENGL_GLCONTEXT_H

View File

@@ -30,7 +30,11 @@
#ifndef FENNEC_RTTI_TYPE_REGISTRY_H #ifndef FENNEC_RTTI_TYPE_REGISTRY_H
#define FENNEC_RTTI_TYPE_REGISTRY_H #define FENNEC_RTTI_TYPE_REGISTRY_H
#include <fennec/containers/priority_queue.h> #include <fennec/containers/priority_queue.h>
#include <fennec/lang/type_traits.h>
#include <fennec/rtti/type.h> #include <fennec/rtti/type.h>
namespace fennec namespace fennec
@@ -89,12 +93,12 @@ public:
using entrylist_t = priority_queue<entry, compare>; using entrylist_t = priority_queue<entry, compare>;
template<typename T> template<typename DerivedT> requires(is_base_of_v<BaseT, DerivedT>)
static void register_type(size_t priority = 0) { static void register_type(size_t priority = 0) {
_global_list().emplace( _global_list().emplace(
priority, priority,
type::get<T>(), type::get<DerivedT>(),
_constructor_helper<T> _constructor_helper<DerivedT>
); );
} }

View File

@@ -84,6 +84,9 @@ public:
/// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present /// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present
/// \param str the buffer to wrap /// \param str the buffer to wrap
/// \tparam n the number of characters in the buffer including the null-terminator, if present /// \tparam n the number of characters in the buffer including the null-terminator, if present
///
/// \details This constructor is explicit because we want to be explicit about when we are allocating memory for
/// a string.
template<size_t n> template<size_t n>
explicit constexpr _string(const char (&str)[n]) explicit constexpr _string(const char (&str)[n])
: _str(str[n - 1] != '\0' ? n + 1 : n) { : _str(str[n - 1] != '\0' ? n + 1 : n) {

View File

@@ -46,7 +46,7 @@ void platform::initialize() {
} }
void platform::shutdown() { void platform::shutdown() {
display.reset();
} }
} }

View File

@@ -30,6 +30,7 @@
#include <fennec/platform/interface/window.h> #include <fennec/platform/interface/window.h>
#include <fennec/platform/interface/display_server.h> #include <fennec/platform/interface/display_server.h>
#include <fennec/renderers/interface/gfxsurface.h>
namespace fennec namespace fennec
{ {
@@ -38,4 +39,12 @@ window* window::get_parent() const {
return server->get_window(cfg.parent); return server->get_window(cfg.parent);
} }
void window::begin_frame() {
gfx_surface->make_current();
}
void window::end_frame() {
gfx_surface->swap();
}
} }

View File

@@ -0,0 +1,38 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/linux/wayland/window.h>
#include <fennec/platform/linux/wayland/egl/context.h>
#include <fennec/platform/linux/wayland/egl/surface.h>
namespace fennec
{
wayland_eglcontext::wayland_eglcontext(display_server* display)
: eglcontext(display) {
}
wayland_eglcontext::~wayland_eglcontext() {
}
gfxsurface* wayland_eglcontext::create_surface(window* window) {
return new wayland_eglsurface(static_cast<wayland_window*>(window), this);
}
}

View File

@@ -0,0 +1,46 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/linux/wayland/window.h>
#include <fennec/platform/linux/wayland/egl/surface.h>
#include <fennec/platform/linux/wayland/lib/wayland.h>
namespace fennec
{
wayland_eglsurface::wayland_eglsurface(wayland_window* win, eglcontext* ctx)
: eglsurface(win, ctx,
reinterpret_cast<EGLNativeWindowType>(
wl_egl_window_create(
static_cast<wl_surface*>(win->get_native_handle()), win->get_size().x, win->get_size().y
)
)
) {
}
wayland_eglsurface::~wayland_eglsurface() {
wl_egl_window_destroy(reinterpret_cast<wl_egl_window*>(_eglwindow));
}
void wayland_eglsurface::resize(const ivec2& size) {
wl_egl_window_resize(reinterpret_cast<wl_egl_window*>(_eglwindow), size.x, size.y, 0, 0);
}
}

View File

@@ -16,30 +16,19 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
///
/// \file wayland_server.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#include <fennec/core/logger.h> #include <fennec/core/logger.h>
#include <fennec/platform/linux/wayland/server.h> #include <fennec/platform/linux/wayland/server.h>
#include <fennec/platform/linux/wayland/window.h> #include <fennec/platform/linux/wayland/window.h>
#include <fennec/platform/linux/wayland/lib/loader.h> #include <fennec/platform/linux/wayland/lib/loader.h>
#include <fennec/platform/linux/wayland/lib/wayland.h> #include <fennec/platform/linux/wayland/lib/wayland.h>
#include <fennec/platform/linux/wayland/lib/headers/xdg-shell-client-protocols.h> #include <fennec/platform/linux/wayland/lib/headers/xdg-shell-client-protocols.h>
#include <fennec/renderers/interface/gfxcontext.h>
namespace fennec namespace fennec
{ {
wayland_server::wayland_server(fennec::platform* p) wayland_server::wayland_server(fennec::platform* p)
: display_server(p) : display_server_base(p)
, display(nullptr), registry(nullptr), compositor(nullptr), seat(nullptr), fifo(false) { , display(nullptr), registry(nullptr), compositor(nullptr), seat(nullptr), fifo(false) {
// load shared lib // load shared lib
@@ -91,6 +80,22 @@ void wayland_server::connect() {
disconnect(); disconnect();
return; return;
} }
auto contexts = ctx_registry::get_type_list();
while (not contexts.empty()) {
const auto& ctx = contexts.front();
gfx_context = ctx.ctor(this);
if (gfx_context->is_valid()) {
break;
} else {
delete gfx_context;
gfx_context = nullptr;
contexts.pop();
}
}
assertf(gfx_context != nullptr, "Failed to create graphics context.");
} }
void wayland_server::disconnect() { void wayland_server::disconnect() {
@@ -100,6 +105,10 @@ void wayland_server::disconnect() {
return; return;
} }
// delete the gfx context
delete gfx_context;
// check compositor // check compositor
if (compositor) { if (compositor) {
wl_compositor_destroy(compositor); wl_compositor_destroy(compositor);
@@ -115,7 +124,8 @@ void wayland_server::disconnect() {
wl_display_disconnect(display); wl_display_disconnect(display);
// clear vars // clear vars
display = nullptr; gfx_context = nullptr;
display = nullptr;
registry = nullptr; registry = nullptr;
compositor = nullptr; compositor = nullptr;
seat = nullptr; seat = nullptr;
@@ -126,6 +136,10 @@ bool wayland_server::connected() const {
return display != nullptr; return display != nullptr;
} }
void wayland_server::dispatch() {
wl_display_dispatch_pending(display);
}
window* wayland_server::create_window(const window::config& conf) { window* wayland_server::create_window(const window::config& conf) {
size_t id = windows.insert(new wayland_window(this, windows.next_id(), conf)); size_t id = windows.insert(new wayland_window(this, windows.next_id(), conf));
return windows[id]; return windows[id];

View File

@@ -16,29 +16,18 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
///
/// \file window.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#include <fennec/platform/interface/display_server.h> #include <fennec/platform/interface/display_server.h>
#include <fennec/platform/linux/wayland/server.h> #include <fennec/platform/linux/wayland/server.h>
#include <fennec/platform/linux/wayland/window.h> #include <fennec/platform/linux/wayland/window.h>
#include <fennec/platform/linux/wayland/lib/wayland.h> #include <fennec/platform/linux/wayland/lib/wayland.h>
#include <fennec/platform/linux/wayland/lib/headers/xdg-shell-client-protocols.h> #include <fennec/platform/linux/wayland/lib/headers/xdg-shell-client-protocols.h>
#include <fennec/renderers/interface/gfxcontext.h>
using namespace fennec; using namespace fennec;
wayland_window::wayland_window(display_server* server, uint32_t id, const config& cfg) wayland_window::wayland_window(display_server* server, uint32_t id, const config& cfg)
: window(server, id, cfg) : window_base(server, id, cfg)
, surface(nullptr) , surface(nullptr)
, xdgsurface(nullptr) { , xdgsurface(nullptr) {
@@ -99,10 +88,12 @@ void wayland_window::show() {
cfg.flags.set(flag_visible); cfg.flags.set(flag_visible);
cfg.flags.set(flag_running); cfg.flags.set(flag_running);
gfx_surface = wl_server->get_gfx_context()->create_surface(this);
} }
void wayland_window::hide() { void wayland_window::hide() {
if (not is_visible()) { if (not is_running()) {
return; return;
} }
@@ -134,9 +125,8 @@ void wayland_window::hide() {
cfg.flags.clear(flag_running); cfg.flags.clear(flag_running);
} }
void wayland_window::dispatch() { void* wayland_window::get_native_handle() {
wayland_server* wl_server = static_cast<wayland_server*>(server); return surface;
wl_display_dispatch(wl_server->display);
} }
bool wayland_window::set_flag(uint8_t, bool) { bool wayland_window::set_flag(uint8_t, bool) {
@@ -156,5 +146,11 @@ void wayland_window::listen_xdg_surface_configure(void*, xdg_surface* xdg, uint3
void wayland_window::listen_xdg_toplevel_configure(void*, xdg_toplevel*, int32_t, int32_t, wl_array*) {} void wayland_window::listen_xdg_toplevel_configure(void*, xdg_toplevel*, int32_t, int32_t, wl_array*) {}
void wayland_window::listen_xdg_toplevel_configure_bounds(void*, xdg_toplevel*, int32_t, int32_t) {} void wayland_window::listen_xdg_toplevel_configure_bounds(void*, xdg_toplevel*, int32_t, int32_t) {}
void wayland_window::listen_xdg_toplevel_close(void*, xdg_toplevel*) {}
void wayland_window::listen_xdg_toplevel_close(void* data, xdg_toplevel*) {
wayland_window* window = static_cast<wayland_window*>(data);
window->hide();
}
void wayland_window::listen_xdg_toplevel_capabilities(void*, xdg_toplevel*, wl_array*) {} void wayland_window::listen_xdg_toplevel_capabilities(void*, xdg_toplevel*, wl_array*) {}

View File

@@ -0,0 +1,114 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/format/format.h>
#include <GL/gl.h>
#include <fennec/platform/opengl/egl/context.h>
namespace fennec
{
static const cstring& egl_translate_type(EGLint type) {
static constexpr cstring opengl = "OpenGL";
static constexpr cstring gles = "GLES";
static constexpr cstring openvg = "OpenVG"; // this should never be used
switch (type) {
default:
case EGL_OPENGL_API: return opengl;
case EGL_OPENGL_ES_API: return gles;
case EGL_OPENVG_API: return openvg;
}
}
eglcontext::eglcontext(display_server* display)
: glcontext(display) {
EGLint config_attrs[] = {
EGL_SURFACE_TYPE,
EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_BIT, // 4
EGL_NONE
};
EGLint context_attrs[] = {
EGL_NONE
};
// Get the EGL display from the display server
_egldisplay = eglGetDisplay(display->get_native_handle());
assertf(_egldisplay, "Failed to connect to egl display.");
// Initialize EGL
assertf(eglInitialize(_egldisplay, &_eglvmajor, &_eglvminor), "Failed to initialize egl.");
// Attempt to bind to OpenGL or GLES
if (not eglBindAPI(EGL_OPENGL_API)) {
config_attrs[4] = EGL_OPENGL_ES_BIT;
assertf(eglBindAPI(EGL_OPENGL_ES_API), "Failed to find suitable OpenGL API.");
}
// Select a configuration
EGLint n;
assertf(eglChooseConfig(_egldisplay, config_attrs, &_eglconfig, 1, &n), "Failed to find suitable OpenGL configuration.");
// Create a context from the configuration and display
_eglcontext = eglCreateContext(_egldisplay, _eglconfig, EGL_NO_CONTEXT, context_attrs);
assertf(_eglcontext, "Failed to create OpenGL Context.");
// Make the created context the current context to query some info
eglMakeCurrent(_egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, _eglcontext);
// Query version information
eglQueryContext(_egldisplay, _eglcontext, EGL_CONTEXT_CLIENT_TYPE, &_eglctype);
glGetIntegerv(GL_MAJOR_VERSION, &_eglvmajor);
glGetIntegerv(GL_MINOR_VERSION, &_eglvminor);
// Set the version fields
version.major = _eglvmajor;
version.minor = _eglvminor;
version.patch = 0;
version.str = format("{} v{}.{}", egl_translate_type(_eglctype), _eglvmajor, _eglvminor);
}
eglcontext::~eglcontext() {
eglMakeCurrent(_egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(_egldisplay, _eglcontext);
eglTerminate(_egldisplay);
eglReleaseThread();
_egldisplay = nullptr;
_eglconfig = nullptr;
_eglcontext = nullptr;
_eglvmajor = 0;
_eglvminor = 0;
version.major = 0;
version.minor = 0;
version.patch = 0;
version.str = "";
}
bool eglcontext::is_valid() {
return _egldisplay != nullptr;
}
}

View File

@@ -0,0 +1,55 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/opengl/egl/context.h>
#include <fennec/platform/opengl/egl/surface.h>
namespace fennec {
eglsurface::eglsurface(fennec::window* win, eglcontext* ctx, EGLNativeWindowType eglwindow)
: gfxsurface(win, ctx)
, _eglwindow(eglwindow)
, _eglsurface(nullptr) {
assertf(_eglwindow, "Failed to acquire EGL window!");
_eglsurface = eglCreateWindowSurface(
ctx->_egldisplay,
ctx->_eglconfig,
_eglwindow,
nullptr
);
assertf(_eglsurface, "Failed to create EGL surface!");
}
eglsurface::~eglsurface() {
eglcontext* ctx = static_cast<eglcontext*>(context);
eglDestroySurface(ctx->_egldisplay, _eglsurface);
}
void eglsurface::make_current() {
eglcontext* ctx = static_cast<eglcontext*>(context);
eglMakeCurrent(ctx->_egldisplay, _eglsurface, _eglsurface, ctx->_eglcontext);
}
void eglsurface::swap() {
eglcontext* ctx = static_cast<eglcontext*>(context);
eglSwapBuffers(ctx->_egldisplay, _eglsurface);
}
} // fennec

View File

@@ -0,0 +1,28 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/renderers/opengl/glcontext.h>
namespace fennec
{
gfxpass* glcontext::create_pass() {
return nullptr;
}
}

View File

@@ -6,6 +6,7 @@ set(CMAKE_C_STANDARD 23)
add_executable(fennec-test add_executable(fennec-test
main.cpp main.cpp
tests/lang/test_metaprogramming.h
) )
target_compile_definitions(fennec-test PUBLIC FENNEC_TEST_CWD="${CMAKE_SOURCE_DIR}/bin/${FENNEC_BUILD_NAME}" target_compile_definitions(fennec-test PUBLIC FENNEC_TEST_CWD="${CMAKE_SOURCE_DIR}/bin/${FENNEC_BUILD_NAME}"

View File

@@ -0,0 +1,61 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file test_metaprogramming.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_TEST_LANG_METAPROGRAMMING_H
#define FENNEC_TEST_LANG_METAPROGRAMMING_H
#include "../../test.h"
namespace fennec::test
{
struct metaprogramming_test {
};
struct metaprogramming_test_base {
};
struct metaprogramming_test_derived : metaprogramming_test_base {
};
inline void fennec_test_lang_metaprogramming() {
fennec_test_run((is_base_of_v<metaprogramming_test_base, metaprogramming_test_derived>), true);
fennec_test_run((is_base_of_v<metaprogramming_test, metaprogramming_test_derived>), false);
}
}
#endif // FENNEC_TEST_LANG_METAPROGRAMMING_H

View File

@@ -22,12 +22,12 @@
#include "lang/test_bits.h" #include "lang/test_bits.h"
#include "lang/test_conditional_types.h" #include "lang/test_conditional_types.h"
#include "lang/test_hashing.h" #include "lang/test_hashing.h"
#include "lang/test_metaprogramming.h"
namespace fennec::test namespace fennec::test
{ {
inline void fennec_test_lang() inline void fennec_test_lang() {
{
fennec_test_subheader("bit tests"); fennec_test_subheader("bit tests");
fennec_test_spacer(2); fennec_test_spacer(2);
fennec_test_lang_bits(); fennec_test_lang_bits();
@@ -36,6 +36,11 @@ namespace fennec::test
fennec_test_subheader("hashing tests"); fennec_test_subheader("hashing tests");
fennec_test_spacer(2); fennec_test_spacer(2);
fennec_test_lang_hashing(); fennec_test_lang_hashing();
fennec_test_spacer(3);
fennec_test_subheader("metaprogramming tests");
fennec_test_spacer(2);
fennec_test_lang_metaprogramming();
// TODO // TODO
} }

View File

@@ -48,7 +48,10 @@ inline void fennec_test_platform() {
window->show(); window->show();
while (window->is_running()) { while (window->is_running()) {
window->dispatch(); window->begin_frame();
window->end_frame();
display->dispatch();
} }
window->hide(); window->hide();