From 9e1e565ae1ef3cf43cf9305c6df0e9cc25c55f48 Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Sun, 18 Jan 2026 11:18:40 +0100 Subject: [PATCH 01/20] Feat: init 3d objects --- CMakeLists.txt | 15 +++++++- assets/config/default.json | 2 +- assets/shaders/glsl/texture.frag | 6 +-- assets/shaders/glsl/texture.vert | 16 +++++--- modules/Engine/include/Engine/Camera.hpp | 37 +++++++++++++++++-- modules/Engine/src/engine.cpp | 6 ++- .../include/Interfaces/Renderer/IRenderer.hpp | 10 ++++- plugins/Renderer/OpenGL/CMakeLists.txt | 16 +++++++- plugins/Renderer/OpenGL/include/OPGL/OPGL.hpp | 2 +- plugins/Renderer/OpenGL/src/opgl.cpp | 15 ++++++-- .../Renderer/Vulkan/include/VULKN/VULKN.hpp | 4 +- src/application.cpp | 23 +++++++++++- 12 files changed, 127 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 348c176..da5a54e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,13 +48,26 @@ FetchContent_Declare( GIT_PROGRESS TRUE ) FetchContent_MakeAvailable(nlohmann-json) +set(GLM_BUILD_TESTS OFF CACHE INTERNAL "") +set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "") + +FetchContent_Declare( + glm + GIT_REPOSITORY https://github.com/g-truc/glm.git + GIT_TAG 1.0.3 + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE +) + +FetchContent_MakeAvailable(glm) add_executable(${PROJECT_NAME} ${SOURCES}) add_dependencies(${PROJECT_NAME} cae-modules) -target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include") +target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ${glm_SOURCE_DIR}) target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules nlohmann_json::nlohmann_json + glm::glm ) if (NOT WIN32 AND NOT APPLE) set(WARNING_FLAGS diff --git a/assets/config/default.json b/assets/config/default.json index cd552e5..ab09240 100644 --- a/assets/config/default.json +++ b/assets/config/default.json @@ -13,7 +13,7 @@ "renderer": { "vsync": false, "frameRateLimit": 90, - "clearColor": [1.0, 1.0, 1.0, 1.0] + "clearColor": [0.2, 0.2, 0.2, 1.0] }, "user": { "name": "User" diff --git a/assets/shaders/glsl/texture.frag b/assets/shaders/glsl/texture.frag index 84a4c3e..ffb6c38 100644 --- a/assets/shaders/glsl/texture.frag +++ b/assets/shaders/glsl/texture.frag @@ -1,11 +1,9 @@ #version 450 core -layout(location = 0) in vec2 vUV; +layout(location = 0) in vec3 vColor; layout(location = 0) out vec4 FragColor; -layout(binding = 0) uniform sampler2D uTexture; - void main() { - FragColor = texture(uTexture, vUV); + FragColor = vec4(vColor, 1.0); } diff --git a/assets/shaders/glsl/texture.vert b/assets/shaders/glsl/texture.vert index 38120fc..52b3177 100644 --- a/assets/shaders/glsl/texture.vert +++ b/assets/shaders/glsl/texture.vert @@ -1,12 +1,18 @@ #version 450 core -layout(location = 0) in vec2 aPos; -layout(location = 1) in vec2 aUV; +layout(location = 0) in vec3 aPos; +layout(location = 1) in vec3 aColor; -layout(location = 0) out vec2 vUV; +layout(location = 0) out vec3 vColor; + +// Uniforms must be in a block +layout(set = 0, binding = 0) uniform Matrices +{ + mat4 uMVP; +}; void main() { - gl_Position = vec4(aPos, 0.0, 1.0); - vUV = aUV; + vColor = aColor; + gl_Position = uMVP * vec4(aPos, 1.0); } diff --git a/modules/Engine/include/Engine/Camera.hpp b/modules/Engine/include/Engine/Camera.hpp index 9c1c779..a30276d 100644 --- a/modules/Engine/include/Engine/Camera.hpp +++ b/modules/Engine/include/Engine/Camera.hpp @@ -8,7 +8,7 @@ #include "Engine/Common.hpp" -#include +#include #include @@ -51,12 +51,33 @@ namespace cae [[nodiscard]] const float &getNear() const { return m_near; } [[nodiscard]] const float &getFar() const { return m_far; } + [[nodiscard]] glm::mat4 getViewMatrix() const { + return glm::lookAt(m_position, m_position + m_direction, glm::vec3(0.0f, 1.0f, 0.0f)); + } + [[nodiscard]] glm::mat4 getProjectionMatrix(const float aspectRatio) const { + return glm::perspective(glm::radians(m_fov), aspectRatio, m_near, m_far); + } + [[nodiscard]] glm::mat4 getVP(const float aspectRatio) const { + return getProjectionMatrix(aspectRatio) * getViewMatrix(); + } + + void updateDirectionFromRotation() { + const float yaw = glm::radians(m_rotation.y); + const float pitch = glm::radians(m_rotation.x); + + m_direction.x = cos(pitch) * sin(yaw); + m_direction.y = std::sin(pitch); + m_direction.z = -cos(pitch) * cos(yaw); + m_direction = glm::normalize(m_direction); + } /// /// @param direction Direction to move the camera /// @param deltaTime Time delta for movement /// @brief Move the camera in a given direction /// - void move(const glm::vec3 &direction, float deltaTime); + void move(const glm::vec3 &direction, const float deltaTime) { + m_position += direction * m_moveSpeed * deltaTime; + } /// /// @param yawOffset Yaw offset to rotate the camera @@ -64,12 +85,20 @@ namespace cae /// @param deltaTime Time delta for rotation /// @brief Rotate the camera by given yaw and pitch offsets /// - void rotate(float yawOffset, float pitchOffset, float deltaTime); + void rotate(const float yawOffset, const float pitchOffset, const float deltaTime) { + m_rotation.y += yawOffset * m_lookSpeed * deltaTime; + m_rotation.x += pitchOffset * m_lookSpeed * deltaTime; + + m_rotation.x = std::min(m_rotation.x, 89.0f); + m_rotation.x = std::max(m_rotation.x, -89.0f); + + updateDirectionFromRotation(); + } private: std::string m_name = CAMERA::NAME; - glm::vec3 m_position = glm::vec3(0.0F, 0.0F, 0.0F); + glm::vec3 m_position = glm::vec3(1.0F, 1.0F, 7.0F); glm::vec3 m_rotation = glm::vec3(0.0F, 0.0F, 0.0F); glm::vec3 m_direction = glm::vec3(0.0F, 0.0F, -1.0F); diff --git a/modules/Engine/src/engine.cpp b/modules/Engine/src/engine.cpp index 3881032..ac8c138 100644 --- a/modules/Engine/src/engine.cpp +++ b/modules/Engine/src/engine.cpp @@ -64,7 +64,11 @@ void cae::Engine::run() const int fpsIndex = 0; while (!m_windowPlugin->shouldClose()) { - m_rendererPlugin->draw(m_windowPlugin->getWindowSize(), "basic"); + glm::mat4 model = glm::mat4(1.0f); + glm::mat4 mvp = + m_camera->getVP(float(m_windowPlugin->getWindowSize().width) / m_windowPlugin->getWindowSize().height) * + model; + m_rendererPlugin->draw(m_windowPlugin->getWindowSize(), "basic", mvp); m_windowPlugin->pollEvents(); if (m_logFps) { diff --git a/modules/Interfaces/include/Interfaces/Renderer/IRenderer.hpp b/modules/Interfaces/include/Interfaces/Renderer/IRenderer.hpp index 0332af3..97ed0d8 100644 --- a/modules/Interfaces/include/Interfaces/Renderer/IRenderer.hpp +++ b/modules/Interfaces/include/Interfaces/Renderer/IRenderer.hpp @@ -8,6 +8,7 @@ #include "Interfaces/IWindow.hpp" #include "Interfaces/Shader/IShaderFrontend.hpp" +#include "glm/fwd.hpp" namespace cae { @@ -25,6 +26,12 @@ namespace cae float a; }; + struct Vertex + { + float x, y, z; + float r, g, b; + }; + /// /// @interface IRenderer /// @brief Interface for renderer @@ -74,9 +81,10 @@ namespace cae /// /// @param windowSize Current window size /// @param shaderId Shader ID to use for drawing + /// @param mvp Model-View-Projection matrix /// @brief Draw the scene using the specified shader and window size /// - virtual void draw(const WindowSize &windowSize, const ShaderID &shaderId) = 0; + virtual void draw(const WindowSize &windowSize, const ShaderID &shaderId, glm::mat4 mvp) = 0; /// /// @param vertices Vertex data to create the mesh diff --git a/plugins/Renderer/OpenGL/CMakeLists.txt b/plugins/Renderer/OpenGL/CMakeLists.txt index 07dad22..37f5126 100644 --- a/plugins/Renderer/OpenGL/CMakeLists.txt +++ b/plugins/Renderer/OpenGL/CMakeLists.txt @@ -9,6 +9,19 @@ if (NOT OPENGL_FOUND) return() endif () +set(GLM_BUILD_TESTS OFF CACHE INTERNAL "") +set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "") + +FetchContent_Declare( + glm + GIT_REPOSITORY https://github.com/g-truc/glm.git + GIT_TAG 1.0.3 + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE +) + +FetchContent_MakeAvailable(glm) + include(FetchContent) FetchContent_Declare( glad @@ -41,12 +54,13 @@ add_library(${PROJECT_NAME} SHARED ${SOURCES}) target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ${OPENGL_INCLUDE_DIR} + ${glm_SOURCE_DIR} ) if (UNIX AND NOT APPLE) target_include_directories(${PROJECT_NAME} PRIVATE ${EGL_INCLUDE_DIRS}) endif () -set(PLATFORM_LIBS cae-modules OpenGL::GL glad) +set(PLATFORM_LIBS cae-modules OpenGL::GL glad glm::glm) if (UNIX AND NOT APPLE) list(APPEND PLATFORM_LIBS ${EGL_LIBRARIES}) elseif (APPLE) diff --git a/plugins/Renderer/OpenGL/include/OPGL/OPGL.hpp b/plugins/Renderer/OpenGL/include/OPGL/OPGL.hpp index dc7d9b7..0e787d1 100644 --- a/plugins/Renderer/OpenGL/include/OPGL/OPGL.hpp +++ b/plugins/Renderer/OpenGL/include/OPGL/OPGL.hpp @@ -56,7 +56,7 @@ namespace cae void initialize(const NativeWindowHandle &nativeWindowHandle, const Color &clearColor) override; void createPipeline(const ShaderID &id, const ShaderIRModule &vertex, const ShaderIRModule &fragment) override; - void draw(const WindowSize &windowSize, const ShaderID &shaderId) override; + void draw(const WindowSize &windowSize, const ShaderID &shaderId, glm::mat4 mvp) override; void createMesh(const std::vector &vertices) override; private: diff --git a/plugins/Renderer/OpenGL/src/opgl.cpp b/plugins/Renderer/OpenGL/src/opgl.cpp index a57fc02..8712106 100644 --- a/plugins/Renderer/OpenGL/src/opgl.cpp +++ b/plugins/Renderer/OpenGL/src/opgl.cpp @@ -1,4 +1,6 @@ #include "OPGL/OPGL.hpp" +#include "glm/ext/matrix_clip_space.hpp" +#include "glm/ext/matrix_transform.hpp" #ifdef __linux__ #include "OPGL/Context/EGLContextLinux.hpp" @@ -27,13 +29,20 @@ void cae::OPGL::initialize(const NativeWindowHandle &nativeWindowHandle, const C gl.ClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); } -void cae::OPGL::draw(const WindowSize &windowSize, const ShaderID &shaderId) +void cae::OPGL::draw(const WindowSize &windowSize, const ShaderID &shaderId, glm::mat4 mvp) { auto &gl = m_context->gl; gl.Viewport(0, 0, windowSize.width, windowSize.height); gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gl.UseProgram(m_programs.at(shaderId)); + GLuint ubo; + gl.GenBuffers(1, &ubo); + gl.BindBuffer(GL_UNIFORM_BUFFER, ubo); + gl.BufferData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), &mvp, GL_DYNAMIC_DRAW); + + // binding = 0 car dans le shader: layout(binding = 0) + gl.BindBufferBase(GL_UNIFORM_BUFFER, 0, ubo); gl.BindVertexArray(m_mesh.vao); gl.DrawArrays(GL_TRIANGLES, 0, m_mesh.vertexCount); gl.BindVertexArray(0); @@ -81,10 +90,10 @@ void cae::OPGL::createMesh(const std::vector &vertices) gl.BindBuffer(GL_ARRAY_BUFFER, mesh.vbo); gl.BufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW); - gl.VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), static_cast(0)); + gl.VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0); gl.EnableVertexAttribArray(0); - gl.VertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(2 * sizeof(float))); + gl.VertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float))); gl.EnableVertexAttribArray(1); gl.BindBuffer(GL_ARRAY_BUFFER, 0); diff --git a/plugins/Renderer/Vulkan/include/VULKN/VULKN.hpp b/plugins/Renderer/Vulkan/include/VULKN/VULKN.hpp index 40bd6a9..2c2c989 100644 --- a/plugins/Renderer/Vulkan/include/VULKN/VULKN.hpp +++ b/plugins/Renderer/Vulkan/include/VULKN/VULKN.hpp @@ -8,6 +8,8 @@ #include "Interfaces/Renderer/ARenderer.hpp" +#include + namespace cae { @@ -42,7 +44,7 @@ namespace cae const ShaderIRModule &fragment) override { } - void draw(const WindowSize &windowSize, const ShaderID &shaderId) override {} + void draw(const WindowSize &windowSize, const ShaderID &shaderId, glm::mat4 mvp) override {} void createMesh(const std::vector &vertices) override {} }; // class VULKN diff --git a/src/application.cpp b/src/application.cpp index d9c1e83..c10e4fa 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -119,6 +119,26 @@ void cae::Application::setupEngine(const std::string &rendererName, const std::s [windowPlugin]() { return windowPlugin; }); } +static const std::vector cubeVertices = { + // positions // colors + -0.5f, -0.5f, -0.5f, 1, 0, 0, 0.5f, -0.5f, -0.5f, 0, 1, 0, 0.5f, 0.5f, -0.5f, 0, 0, 1, + 0.5f, 0.5f, -0.5f, 0, 0, 1, -0.5f, 0.5f, -0.5f, 1, 1, 0, -0.5f, -0.5f, -0.5f, 1, 0, 0, + + -0.5f, -0.5f, 0.5f, 1, 0, 1, 0.5f, -0.5f, 0.5f, 0, 1, 1, 0.5f, 0.5f, 0.5f, 1, 1, 1, + 0.5f, 0.5f, 0.5f, 1, 1, 1, -0.5f, 0.5f, 0.5f, 0, 0, 0, -0.5f, -0.5f, 0.5f, 1, 0, 1, + + -0.5f, 0.5f, 0.5f, 1, 0, 0, -0.5f, 0.5f, -0.5f, 0, 1, 0, -0.5f, -0.5f, -0.5f, 0, 0, 1, + -0.5f, -0.5f, -0.5f, 0, 0, 1, -0.5f, -0.5f, 0.5f, 1, 1, 0, -0.5f, 0.5f, 0.5f, 1, 0, 0, + + 0.5f, 0.5f, 0.5f, 1, 0, 1, 0.5f, 0.5f, -0.5f, 0, 1, 1, 0.5f, -0.5f, -0.5f, 1, 1, 1, + 0.5f, -0.5f, -0.5f, 1, 1, 1, 0.5f, -0.5f, 0.5f, 0, 0, 0, 0.5f, 0.5f, 0.5f, 1, 0, 1, + + -0.5f, -0.5f, -0.5f, 1, 0, 0, 0.5f, -0.5f, -0.5f, 0, 1, 0, 0.5f, -0.5f, 0.5f, 0, 0, 1, + 0.5f, -0.5f, 0.5f, 0, 0, 1, -0.5f, -0.5f, 0.5f, 1, 1, 0, -0.5f, -0.5f, -0.5f, 1, 0, 0, + + -0.5f, 0.5f, -0.5f, 1, 0, 1, 0.5f, 0.5f, -0.5f, 0, 1, 1, 0.5f, 0.5f, 0.5f, 1, 1, 1, + 0.5f, 0.5f, 0.5f, 1, 1, 1, -0.5f, 0.5f, 0.5f, 0, 0, 0, -0.5f, 0.5f, -0.5f, 1, 0, 1}; + void cae::Application::start() const { static const std::vector shaderSources = { @@ -132,8 +152,7 @@ void cae::Application::start() const .source = utl::fileToString(utl::Path::resolveRelativeToExe("assets/shaders/glsl/texture.frag")), .stage = ShaderStage::FRAGMENT}, }; - m_engine->initializeRenderResources( - shaderSources, std::vector{-0.5F, -0.5F, 1.F, 0.F, 0.F, 0.5F, -0.5F, 0.F, 1.F, 0.F, 0.F, 0.5F, 0.F, 0.F, 1.F}); + m_engine->initializeRenderResources(shaderSources, cubeVertices); m_engine->run(); } From b9cc89a45716c59eb2d39c7604d28f1eb9a7727d Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Sun, 18 Jan 2026 16:47:24 +0100 Subject: [PATCH 02/20] Fix: opengl only one ubo --- .../OpenGL/include/OPGL/Context/IContext.hpp | 18 ++++++++- plugins/Renderer/OpenGL/include/OPGL/OPGL.hpp | 5 +-- .../OpenGL/src/context/WGLContextWindows.cpp | 4 +- plugins/Renderer/OpenGL/src/opgl.cpp | 37 ++++++++++--------- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/plugins/Renderer/OpenGL/include/OPGL/Context/IContext.hpp b/plugins/Renderer/OpenGL/include/OPGL/Context/IContext.hpp index 467ed96..13c1588 100644 --- a/plugins/Renderer/OpenGL/include/OPGL/Context/IContext.hpp +++ b/plugins/Renderer/OpenGL/include/OPGL/Context/IContext.hpp @@ -22,14 +22,30 @@ namespace cae public: virtual ~IContext() = default; + /// + /// @param window The native window handle + /// @brief Initialize the OpenGL context with the given window + /// virtual void initialize(const NativeWindowHandle &window) = 0; + /// + /// @brief Swap the front and back buffers + /// virtual void swapBuffers() = 0; + /// + /// @param enabled Whether VSync should be enabled + /// @brief Enable or disable VSync + /// virtual void setVSyncEnabled(bool enabled) = 0; + + /// + /// @return Whether VSync is enabled + /// @brief Check if VSync is enabled + /// [[nodiscard]] virtual bool isVSyncEnabled() const = 0; - GladGLContext gl{0}; + GladGLContext gl{nullptr}; }; // interface IContext diff --git a/plugins/Renderer/OpenGL/include/OPGL/OPGL.hpp b/plugins/Renderer/OpenGL/include/OPGL/OPGL.hpp index 0e787d1..cd881d0 100644 --- a/plugins/Renderer/OpenGL/include/OPGL/OPGL.hpp +++ b/plugins/Renderer/OpenGL/include/OPGL/OPGL.hpp @@ -64,9 +64,8 @@ namespace cae std::unordered_map m_programs; Mesh m_mesh; - GladGLContext m_device{}; - - static GLuint createGLShader(GLenum type, const ShaderIRModule &data, GladGLContext gl); + GLuint m_ubo; + static GLuint createGLShader(GLenum type, const ShaderIRModule &data, const GladGLContext &gl); }; // class OPGL diff --git a/plugins/Renderer/OpenGL/src/context/WGLContextWindows.cpp b/plugins/Renderer/OpenGL/src/context/WGLContextWindows.cpp index c3a8e5e..e989c75 100644 --- a/plugins/Renderer/OpenGL/src/context/WGLContextWindows.cpp +++ b/plugins/Renderer/OpenGL/src/context/WGLContextWindows.cpp @@ -36,7 +36,7 @@ static void *win32GetGLProc(const char *name) { auto *proc = (void *)wglGetProcAddress(name); - if (proc == nullptr || proc == (void *)0x1 || proc == (void *)0x2 || proc == (void *)0x3 || proc == (void *)-1) + if (proc == nullptr || proc == reinterpret_cast(0x1) || proc == reinterpret_cast(0x2) || proc == reinterpret_cast(0x3) || proc == reinterpret_cast(-1)) { if (g_opengl32 == nullptr) { @@ -134,7 +134,7 @@ void cae::WGLContextWindows::initialize(const NativeWindowHandle &window) { throw std::runtime_error("Current WGL context is not the one just created"); } - if (const int version = gladLoadGLContext(&gl, GLADloadfunc(win32GetGLProc)); version == 0) + if (const int version = gladLoadGLContext(&gl, reinterpret_cast(win32GetGLProc)); version == 0) { throw std::runtime_error("Failed to initialize GLAD MX (Windows)"); } diff --git a/plugins/Renderer/OpenGL/src/opgl.cpp b/plugins/Renderer/OpenGL/src/opgl.cpp index 8712106..d1ec723 100644 --- a/plugins/Renderer/OpenGL/src/opgl.cpp +++ b/plugins/Renderer/OpenGL/src/opgl.cpp @@ -1,6 +1,4 @@ #include "OPGL/OPGL.hpp" -#include "glm/ext/matrix_clip_space.hpp" -#include "glm/ext/matrix_transform.hpp" #ifdef __linux__ #include "OPGL/Context/EGLContextLinux.hpp" @@ -10,6 +8,8 @@ #include "OPGL/Context/NSGLContextMac.hpp" #endif +#include + #include void cae::OPGL::initialize(const NativeWindowHandle &nativeWindowHandle, const Color &clearColor) @@ -23,26 +23,29 @@ void cae::OPGL::initialize(const NativeWindowHandle &nativeWindowHandle, const C #endif m_context->initialize(nativeWindowHandle); - auto &gl = m_context->gl; + const auto &gl = m_context->gl; gl.Enable(GL_DEPTH_TEST); gl.ClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); + + gl.GenBuffers(1, &m_ubo); + gl.BindBuffer(GL_UNIFORM_BUFFER, m_ubo); + gl.BufferData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), nullptr, GL_DYNAMIC_DRAW); + gl.BindBufferBase(GL_UNIFORM_BUFFER, 0, m_ubo); + gl.BindBuffer(GL_UNIFORM_BUFFER, 0); } -void cae::OPGL::draw(const WindowSize &windowSize, const ShaderID &shaderId, glm::mat4 mvp) +void cae::OPGL::draw(const WindowSize &windowSize, const ShaderID &shaderId, const glm::mat4 mvp) { - auto &gl = m_context->gl; + const auto &gl = m_context->gl; gl.Viewport(0, 0, windowSize.width, windowSize.height); gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gl.UseProgram(m_programs.at(shaderId)); - GLuint ubo; - gl.GenBuffers(1, &ubo); - gl.BindBuffer(GL_UNIFORM_BUFFER, ubo); - gl.BufferData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), &mvp, GL_DYNAMIC_DRAW); + gl.BindBuffer(GL_UNIFORM_BUFFER, m_ubo); + gl.BufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), &mvp); // binding = 0 car dans le shader: layout(binding = 0) - gl.BindBufferBase(GL_UNIFORM_BUFFER, 0, ubo); gl.BindVertexArray(m_mesh.vao); gl.DrawArrays(GL_TRIANGLES, 0, m_mesh.vertexCount); gl.BindVertexArray(0); @@ -52,11 +55,11 @@ void cae::OPGL::draw(const WindowSize &windowSize, const ShaderID &shaderId, glm void cae::OPGL::createPipeline(const ShaderID &id, const ShaderIRModule &vertex, const ShaderIRModule &fragment) { - auto &gl = m_context->gl; + const auto &gl = m_context->gl; const GLuint program = gl.CreateProgram(); - GLuint vs = createGLShader(GL_VERTEX_SHADER, vertex, gl); - GLuint fs = createGLShader(GL_FRAGMENT_SHADER, fragment, gl); + const GLuint vs = createGLShader(GL_VERTEX_SHADER, vertex, gl); + const GLuint fs = createGLShader(GL_FRAGMENT_SHADER, fragment, gl); gl.AttachShader(program, vs); gl.AttachShader(program, fs); @@ -79,7 +82,7 @@ void cae::OPGL::createPipeline(const ShaderID &id, const ShaderIRModule &vertex, void cae::OPGL::createMesh(const std::vector &vertices) { - auto &gl = m_context->gl; + const auto &gl = m_context->gl; Mesh mesh{}; mesh.vertexCount = static_cast(vertices.size() / 5); @@ -90,10 +93,10 @@ void cae::OPGL::createMesh(const std::vector &vertices) gl.BindBuffer(GL_ARRAY_BUFFER, mesh.vbo); gl.BufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW); - gl.VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0); + gl.VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), static_cast(0)); gl.EnableVertexAttribArray(0); - gl.VertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float))); + gl.VertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), reinterpret_cast(3 * sizeof(float))); gl.EnableVertexAttribArray(1); gl.BindBuffer(GL_ARRAY_BUFFER, 0); @@ -102,7 +105,7 @@ void cae::OPGL::createMesh(const std::vector &vertices) m_mesh = mesh; } -GLuint cae::OPGL::createGLShader(const GLenum type, const ShaderIRModule &data, GladGLContext gl) +GLuint cae::OPGL::createGLShader(const GLenum type, const ShaderIRModule &data, const GladGLContext &gl) { const GLuint shader = gl.CreateShader(type); From 1b36d4004dd9dc42d6a4221e2b5502b3f021c179 Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Sun, 18 Jan 2026 18:01:52 +0100 Subject: [PATCH 03/20] Feat: handle window inputs and camera movements --- modules/Engine/include/Engine/Common.hpp | 2 +- modules/Engine/include/Engine/Engine.hpp | 4 +- modules/Engine/src/engine.cpp | 53 +++++++- .../Interfaces/include/Interfaces/IWindow.hpp | 33 +++++ plugins/Window/GLFW/include/GLFW/GLFW.hpp | 11 +- plugins/Window/GLFW/src/glfw.cpp | 120 +++++++++++++++++- plugins/Window/Win32/include/Win32/Win32.hpp | 5 + plugins/Window/Win32/src/win32.cpp | 93 ++++++++++++-- src/application.cpp | 2 +- 9 files changed, 304 insertions(+), 19 deletions(-) diff --git a/modules/Engine/include/Engine/Common.hpp b/modules/Engine/include/Engine/Common.hpp index 4df2287..79510a9 100644 --- a/modules/Engine/include/Engine/Common.hpp +++ b/modules/Engine/include/Engine/Common.hpp @@ -26,7 +26,7 @@ namespace cae { inline constexpr auto NAME = "Default name"; inline constexpr auto MOVE_SPEED = 2.5F; - inline constexpr auto LOOK_SPEED = 100.F; + inline constexpr auto LOOK_SPEED = 10.0F; inline constexpr auto FOV = 45.F; inline constexpr auto NEAR_PLANE = 0.1F; inline constexpr auto FAR_PLANE = 100.F; diff --git a/modules/Engine/include/Engine/Engine.hpp b/modules/Engine/include/Engine/Engine.hpp index 5b77189..1315d8a 100644 --- a/modules/Engine/include/Engine/Engine.hpp +++ b/modules/Engine/include/Engine/Engine.hpp @@ -90,7 +90,7 @@ namespace cae /// /// @brief Run the engine main loop /// - void run() const; + void run(); /// /// @brief Stop the engine @@ -108,6 +108,8 @@ namespace cae std::unique_ptr m_shaderManager = nullptr; std::unique_ptr m_camera = nullptr; + std::unordered_map m_keyState; + bool m_logFps = false; /// diff --git a/modules/Engine/src/engine.cpp b/modules/Engine/src/engine.cpp index ac8c138..c2c0714 100644 --- a/modules/Engine/src/engine.cpp +++ b/modules/Engine/src/engine.cpp @@ -58,18 +58,63 @@ void cae::Engine::initializeRenderResources(const std::vector m_rendererPlugin->createMesh(vertices); } -void cae::Engine::run() const +void cae::Engine::run() { std::array fpsBuffer{}; int fpsIndex = 0; while (!m_windowPlugin->shouldClose()) { - glm::mat4 model = glm::mat4(1.0f); - glm::mat4 mvp = - m_camera->getVP(float(m_windowPlugin->getWindowSize().width) / m_windowPlugin->getWindowSize().height) * + auto model = glm::mat4(1.0f); + const glm::mat4 mvp = + m_camera->getVP(static_cast(m_windowPlugin->getWindowSize().width) / m_windowPlugin->getWindowSize().height) * model; m_rendererPlugin->draw(m_windowPlugin->getWindowSize(), "basic", mvp); m_windowPlugin->pollEvents(); + WindowEvent e; + while (m_windowPlugin->pollEvent(e)) + { + if (e.type == WindowEventType::KeyDown) + { + m_keyState[e.key.key] = true; + } + else if (e.type == WindowEventType::KeyUp) + { + m_keyState[e.key.key] = false; + } + } + glm::vec3 moveDir(0.0f); + glm::vec2 lookDir(0.0f); + + // Rotation + if (m_keyState[KeyCode::Up]) lookDir.y += 1.0f; + if (m_keyState[KeyCode::Down]) lookDir.y -= 1.0f; + if (m_keyState[KeyCode::Left]) lookDir.x -= 1.0f; + if (m_keyState[KeyCode::Right]) lookDir.x += 1.0f; + + // Appliquer la rotation + if (glm::length(lookDir) > 0.0f) + { + lookDir *= m_camera->getLookSpeed() * m_clock->getDeltaSeconds(); + m_camera->rotate(lookDir.x, lookDir.y, 1.0f); // deltaTime déjà appliqué dans lookDir + } + + glm::vec3 forward = glm::normalize(glm::vec3(m_camera->getDirection().x, 0.0f, m_camera->getDirection().z)); + glm::vec3 right = glm::normalize(glm::cross(forward, glm::vec3(0.0f, 1.0f, 0.0f))); + + if (m_keyState[KeyCode::W]) moveDir += forward; + if (m_keyState[KeyCode::S]) moveDir -= forward; + if (m_keyState[KeyCode::A]) moveDir -= right; + if (m_keyState[KeyCode::D]) moveDir += right; + + if (glm::length(moveDir) > 0.0f) + { + moveDir = glm::normalize(moveDir); + m_camera->move(moveDir, m_clock->getDeltaSeconds()); + } + + if (m_keyState[KeyCode::LCtrl]) m_camera->move(glm::vec3(0.0f, -1.0f, 0.0f), m_clock->getDeltaSeconds()); + if (m_keyState[KeyCode::Space]) m_camera->move(glm::vec3(0.0f, 1.0f, 0.0f), m_clock->getDeltaSeconds()); + if (m_logFps) { printFps(fpsBuffer, fpsIndex, m_clock->getDeltaSeconds()); diff --git a/modules/Interfaces/include/Interfaces/IWindow.hpp b/modules/Interfaces/include/Interfaces/IWindow.hpp index 4b261a3..dcb49a7 100644 --- a/modules/Interfaces/include/Interfaces/IWindow.hpp +++ b/modules/Interfaces/include/Interfaces/IWindow.hpp @@ -6,6 +6,8 @@ #pragma once +#include "Input/Key/Keyboard.hpp" +#include "Input/Key/Mouse.hpp" #include "Utils/Interfaces/IPlugin.hpp" namespace cae @@ -33,6 +35,30 @@ namespace cae void *display; }; + enum class WindowEventType { + KeyDown, + KeyUp, + MouseMove, + MouseButtonDown, + MouseButtonUp, + MouseScroll, + Resize, + Focus, + Close + }; + + struct WindowEvent { + WindowEventType type; + + union { + struct { KeyCode key; } key; + struct { int x, y; } mouseMove; + struct { MouseButton button; } mouseButton; + struct { float x, y; } scroll; + struct { uint16_t w, h; } resize; + }; + }; + /// /// @interface IWindow /// @brief Interface for window @@ -87,6 +113,13 @@ namespace cae /// virtual void pollEvents() = 0; + /// + /// @param outEvent Event to be filled + /// @return True if an event was polled + /// @brief Poll window events into outEvent + /// + virtual bool pollEvent(WindowEvent& outEvent) = 0; + /// /// @return True if the window was resized /// @brief Check if the window was resized diff --git a/plugins/Window/GLFW/include/GLFW/GLFW.hpp b/plugins/Window/GLFW/include/GLFW/GLFW.hpp index 8d8acd6..ef6a0ec 100644 --- a/plugins/Window/GLFW/include/GLFW/GLFW.hpp +++ b/plugins/Window/GLFW/include/GLFW/GLFW.hpp @@ -17,6 +17,8 @@ #endif #include +#include + namespace cae { @@ -51,12 +53,19 @@ namespace cae [[nodiscard]] bool shouldClose() const override { return glfwWindowShouldClose(m_window) != 0; } void pollEvents() override { glfwPollEvents(); } + bool pollEvent(WindowEvent &event) override; [[nodiscard]] bool wasResized() const override { return m_frameBufferResized; } void resetResizedFlag() override { m_frameBufferResized = false; } private: - static void frameBufferResizeCallback(GLFWwindow *window, int width, int height); + static void frameBufferResizeCallback(GLFWwindow* window, int width, int height); + static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); + static void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods); + static void cursorPosCallback(GLFWwindow* window, double x, double y); + static void scrollCallback(GLFWwindow* window, double xoffset, double yoffset); + + std::queue m_eventQueue; GLFWwindow *m_window = nullptr; WindowSize m_frameBufferSize{}; diff --git a/plugins/Window/GLFW/src/glfw.cpp b/plugins/Window/GLFW/src/glfw.cpp index ba33822..79bbeb2 100644 --- a/plugins/Window/GLFW/src/glfw.cpp +++ b/plugins/Window/GLFW/src/glfw.cpp @@ -4,12 +4,113 @@ #include "Utils/Logger.hpp" #include +#include + +static cae::KeyCode translateKey(const int key) +{ + static const std::unordered_map keyMap = { + {GLFW_KEY_A, cae::KeyCode::A}, {GLFW_KEY_B, cae::KeyCode::B}, {GLFW_KEY_C, cae::KeyCode::C}, + {GLFW_KEY_D, cae::KeyCode::D}, {GLFW_KEY_E, cae::KeyCode::E}, {GLFW_KEY_F, cae::KeyCode::F}, + {GLFW_KEY_G, cae::KeyCode::G}, {GLFW_KEY_H, cae::KeyCode::H}, {GLFW_KEY_I, cae::KeyCode::I}, + {GLFW_KEY_J, cae::KeyCode::J}, {GLFW_KEY_K, cae::KeyCode::K}, {GLFW_KEY_L, cae::KeyCode::L}, + {GLFW_KEY_M, cae::KeyCode::M}, {GLFW_KEY_N, cae::KeyCode::N}, {GLFW_KEY_O, cae::KeyCode::O}, + {GLFW_KEY_P, cae::KeyCode::P}, {GLFW_KEY_Q, cae::KeyCode::Q}, {GLFW_KEY_R, cae::KeyCode::R}, + {GLFW_KEY_S, cae::KeyCode::S}, {GLFW_KEY_T, cae::KeyCode::T}, {GLFW_KEY_U, cae::KeyCode::U}, + {GLFW_KEY_V, cae::KeyCode::V}, {GLFW_KEY_W, cae::KeyCode::W}, {GLFW_KEY_X, cae::KeyCode::X}, + {GLFW_KEY_Y, cae::KeyCode::Y}, {GLFW_KEY_Z, cae::KeyCode::Z}, + + {GLFW_KEY_0, cae::KeyCode::Num0}, {GLFW_KEY_1, cae::KeyCode::Num1}, {GLFW_KEY_2, cae::KeyCode::Num2}, + {GLFW_KEY_3, cae::KeyCode::Num3}, {GLFW_KEY_4, cae::KeyCode::Num4}, {GLFW_KEY_5, cae::KeyCode::Num5}, + {GLFW_KEY_6, cae::KeyCode::Num6}, {GLFW_KEY_7, cae::KeyCode::Num7}, {GLFW_KEY_8, cae::KeyCode::Num8}, + {GLFW_KEY_9, cae::KeyCode::Num9}, + {GLFW_KEY_ESCAPE, cae::KeyCode::Escape}, + {GLFW_KEY_LEFT, cae::KeyCode::Left}, {GLFW_KEY_RIGHT, cae::KeyCode::Right}, + {GLFW_KEY_UP, cae::KeyCode::Up}, {GLFW_KEY_DOWN, cae::KeyCode::Down}, + {GLFW_KEY_SPACE, cae::KeyCode::Space}, {GLFW_KEY_ENTER, cae::KeyCode::Enter}, + {GLFW_KEY_BACKSPACE, cae::KeyCode::Backspace}, {GLFW_KEY_TAB, cae::KeyCode::Tab}, + {GLFW_KEY_LEFT_SHIFT, cae::KeyCode::LShift}, {GLFW_KEY_LEFT_CONTROL, cae::KeyCode::LCtrl}, + {GLFW_KEY_LEFT_ALT, cae::KeyCode::LAlt} + // ... + }; + const auto it = keyMap.find(key); + return it != keyMap.end() ? it->second : cae::KeyCode::Count; +} + +void cae::GLFW::keyCallback(GLFWwindow* window, const int key, int, const int action, int) +{ + auto* self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) return; + + WindowEvent e{}; + if (action == GLFW_PRESS) + e.type = WindowEventType::KeyDown; + else if (action == GLFW_RELEASE) + e.type = WindowEventType::KeyUp; + else + return; + + e.key.key = translateKey(key); + self->m_eventQueue.push(e); +} + +void cae::GLFW::mouseButtonCallback(GLFWwindow* window, int button, const int action, int) +{ + auto* self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) return; + + WindowEvent e{}; + e.type = (action == GLFW_PRESS) + ? WindowEventType::MouseButtonDown + : WindowEventType::MouseButtonUp; + + e.mouseButton.button = static_cast(button); + self->m_eventQueue.push(e); +} + +void cae::GLFW::cursorPosCallback(GLFWwindow* window, const double x, const double y) +{ + auto* self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) return; + + WindowEvent e{}; + e.type = WindowEventType::MouseMove; + e.mouseMove.x = static_cast(x); + e.mouseMove.y = static_cast(y); + + self->m_eventQueue.push(e); +} + +void cae::GLFW::scrollCallback(GLFWwindow* window, const double xoffset, const double yoffset) +{ + auto* self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) return; + + WindowEvent e{}; + e.type = WindowEventType::MouseScroll; + e.scroll.x = static_cast(xoffset); + e.scroll.y = static_cast(yoffset); + + self->m_eventQueue.push(e); +} + void cae::GLFW::frameBufferResizeCallback(GLFWwindow *window, const int width, const int height) { - auto *const self = static_cast(glfwGetWindowUserPointer(window)); + auto* self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) return; + self->m_frameBufferResized = true; - self->m_frameBufferSize = {.width = static_cast(width), .height = static_cast(height)}; + self->m_frameBufferSize = { + static_cast(width), + static_cast(height) + }; + + WindowEvent e{}; + e.type = WindowEventType::Resize; + e.resize.w = self->m_frameBufferSize.width; + e.resize.h = self->m_frameBufferSize.height; + + self->m_eventQueue.push(e); } bool cae::GLFW::create(const std::string &name, const WindowSize size) @@ -31,7 +132,12 @@ bool cae::GLFW::create(const std::string &name, const WindowSize size) return false; } glfwSetWindowUserPointer(m_window, this); + glfwSetFramebufferSizeCallback(m_window, frameBufferResizeCallback); + glfwSetKeyCallback(m_window, keyCallback); + glfwSetMouseButtonCallback(m_window, mouseButtonCallback); + glfwSetCursorPosCallback(m_window, cursorPosCallback); + glfwSetScrollCallback(m_window, scrollCallback); return true; } @@ -80,3 +186,13 @@ bool cae::GLFW::setIcon(const std::string &path) const glfwSetWindowIcon(m_window, 1, &appIcon); return true; } + +bool cae::GLFW::pollEvent(WindowEvent &event) +{ + if (m_eventQueue.empty()) + return false; + + event = m_eventQueue.front(); + m_eventQueue.pop(); + return true; +} diff --git a/plugins/Window/Win32/include/Win32/Win32.hpp b/plugins/Window/Win32/include/Win32/Win32.hpp index 97c340d..84dba29 100644 --- a/plugins/Window/Win32/include/Win32/Win32.hpp +++ b/plugins/Window/Win32/include/Win32/Win32.hpp @@ -10,6 +10,8 @@ #include +#include + namespace cae { @@ -44,12 +46,15 @@ namespace cae [[nodiscard]] bool shouldClose() const override { return m_shouldClose; } void pollEvents() override; + bool pollEvent(WindowEvent &event) override; bool wasResized() const override { return m_frameBufferResized; } void resetResizedFlag() override { m_frameBufferResized = false; } private: static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + static KeyCode mapWinKey(WPARAM key); + std::queue m_eventQueue; std::wstring m_title; HWND m_hwnd = nullptr; diff --git a/plugins/Window/Win32/src/win32.cpp b/plugins/Window/Win32/src/win32.cpp index 4067c09..c519812 100644 --- a/plugins/Window/Win32/src/win32.cpp +++ b/plugins/Window/Win32/src/win32.cpp @@ -3,42 +3,97 @@ #include "Utils/Image.hpp" #include "Utils/Logger.hpp" +#include + #include +#include constexpr wchar_t WINDOW_CLASS_NAME[] = L"CAE_WindowsWindowClass"; +cae::KeyCode cae::Win32::mapWinKey(const WPARAM key) +{ + static const std::unordered_map keyMap = { + {'A', KeyCode::A}, {'B', KeyCode::B}, {'C', KeyCode::C}, + {'D', KeyCode::D}, {'E', KeyCode::E}, {'F', KeyCode::F}, + {'G', KeyCode::G}, {'H', KeyCode::H}, {'I', KeyCode::I}, + {'J', KeyCode::J}, {'K', KeyCode::K}, {'L', KeyCode::L}, + {'M', KeyCode::M}, {'N', KeyCode::N}, {'O', KeyCode::O}, + {'P', KeyCode::P}, {'Q', KeyCode::Q}, {'R', KeyCode::R}, + {'S', KeyCode::S}, {'T', KeyCode::T}, {'U', KeyCode::U}, + {'V', KeyCode::V}, {'W', KeyCode::W}, {'X', KeyCode::X}, + {'Y', KeyCode::Y}, {'Z', KeyCode::Z}, + + {'0', KeyCode::Num0}, {'1', KeyCode::Num1}, {'2', KeyCode::Num2}, + {'3', KeyCode::Num3}, {'4', KeyCode::Num4}, {'5', KeyCode::Num5}, + {'6', KeyCode::Num6}, {'7', KeyCode::Num7}, {'8', KeyCode::Num8}, {'9', KeyCode::Num9}, + + {VK_ESCAPE, KeyCode::Escape}, + {VK_LEFT, KeyCode::Left}, {VK_RIGHT, KeyCode::Right}, + {VK_UP, KeyCode::Up}, {VK_DOWN, KeyCode::Down}, + {VK_SPACE, KeyCode::Space}, {VK_RETURN, KeyCode::Enter}, + {VK_BACK, KeyCode::Backspace}, {VK_TAB, KeyCode::Tab}, + {VK_SHIFT, KeyCode::LShift}, {VK_CONTROL, KeyCode::LCtrl}, {VK_MENU, KeyCode::LAlt} + // ... + }; + + const auto it = keyMap.find(key); + return it != keyMap.end() ? it->second : KeyCode::Count; +} + + LRESULT CALLBACK cae::Win32::WindowProc(const HWND hwnd, const UINT msg, const WPARAM wParam, const LPARAM lParam) { Win32 *self = nullptr; if (msg == WM_NCCREATE) { - auto *cs = reinterpret_cast(lParam); + const auto *cs = reinterpret_cast(lParam); self = static_cast(cs->lpCreateParams); SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast(self)); return TRUE; } self = reinterpret_cast(GetWindowLongPtrW(hwnd, GWLP_USERDATA)); + if (!self) return DefWindowProcW(hwnd, msg, wParam, lParam); + WindowEvent e{}; switch (msg) { case WM_SIZE: - if (self != nullptr) - { - self->m_frameBufferResized = true; - self->m_frameBufferSize = {.width = LOWORD(lParam), .height = HIWORD(lParam)}; - } + self->m_frameBufferResized = true; + self->m_frameBufferSize = {.width = LOWORD(lParam), .height = HIWORD(lParam)}; + e.type = WindowEventType::Resize; + e.resize = {LOWORD(lParam), HIWORD(lParam)}; + self->m_eventQueue.push(e); return 0; case WM_DESTROY: PostQuitMessage(0); + e.type = WindowEventType::Close; + self->m_eventQueue.push(e); + return 0; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + e.type = WindowEventType::KeyDown; + e.key.key = mapWinKey(wParam); + self->m_eventQueue.push(e); return 0; - default: - return DefWindowProcW(hwnd, msg, wParam, lParam); + + case WM_KEYUP: + case WM_SYSKEYUP: + e.type = WindowEventType::KeyUp; + e.key.key = mapWinKey(wParam); + self->m_eventQueue.push(e); + return 0; + + // souris, scroll, etc } + + return DefWindowProcW(hwnd, msg, wParam, lParam); } + bool cae::Win32::create(const std::string &name, const WindowSize size) { m_hInstance = GetModuleHandleW(nullptr); @@ -75,7 +130,7 @@ bool cae::Win32::create(const std::string &name, const WindowSize size) } classRegistered = true; } - m_hwnd = CreateWindowExW(0, WINDOW_CLASS_NAME, L"TEST TITLE VISIBLE", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, + m_hwnd = CreateWindowExW(0, WINDOW_CLASS_NAME, L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, size.width, size.height, nullptr, nullptr, m_hInstance, this); if (m_hwnd == nullptr) @@ -187,3 +242,23 @@ void cae::Win32::pollEvents() DispatchMessage(&msg); } } + +bool cae::Win32::pollEvent(WindowEvent &event) +{ + MSG msg{}; + while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + if (!m_eventQueue.empty()) + { + event = m_eventQueue.front(); + m_eventQueue.pop(); + return true; + } + + return false; +} + diff --git a/src/application.cpp b/src/application.cpp index c10e4fa..b7de6fa 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -53,7 +53,7 @@ cae::Application::Application(const ArgsConfig &argsConfig, const EnvConfig &env { m_appConfig.engineConfig = parseEngineConf(argsConfig.config_path); } - setupEngine(PLUGINS::NAME::RENDERER::OPENGL, PLUGINS::NAME::WINDOW::GLFW, PLUGINS::NAME::SHADER::FRONTEND::GLSL, + setupEngine(PLUGINS::NAME::RENDERER::OPENGL, PLUGINS::NAME::WINDOW::WIN32_, PLUGINS::NAME::SHADER::FRONTEND::GLSL, PLUGINS::NAME::SHADER::IR::SPIRV); } catch (const std::exception &e) From 0fe0d66cce1ac7cac926df07bbb65c852aa03de1 Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Sun, 18 Jan 2026 18:52:54 +0100 Subject: [PATCH 04/20] Feat: x11 impl --- plugins/Window/X11/include/X11/X11.hpp | 6 ++ plugins/Window/X11/src/x11.cpp | 107 +++++++++++++++++++------ src/application.cpp | 2 +- 3 files changed, 91 insertions(+), 24 deletions(-) diff --git a/plugins/Window/X11/include/X11/X11.hpp b/plugins/Window/X11/include/X11/X11.hpp index fcc4033..cbde4ad 100644 --- a/plugins/Window/X11/include/X11/X11.hpp +++ b/plugins/Window/X11/include/X11/X11.hpp @@ -10,6 +10,8 @@ #include +#include + namespace cae { @@ -47,11 +49,15 @@ namespace cae [[nodiscard]] bool shouldClose() const override; void pollEvents() override; + bool pollEvent(WindowEvent& outEvent) override; bool wasResized() const override { return m_frameBufferResized; } void resetResizedFlag() override { m_frameBufferResized = false; } private: + + std::queue m_eventQueue; + WindowSize m_frameBufferSize; mutable bool m_frameBufferResized = false; diff --git a/plugins/Window/X11/src/x11.cpp b/plugins/Window/X11/src/x11.cpp index df7b946..8920ce4 100644 --- a/plugins/Window/X11/src/x11.cpp +++ b/plugins/Window/X11/src/x11.cpp @@ -3,9 +3,33 @@ #include "Utils/Image.hpp" #include "Utils/Logger.hpp" +#include +#include + #include #include +static cae::KeyCode translateKey(const KeySym keysym) +{ + switch (keysym) + { + case XK_w: return cae::KeyCode::W; + case XK_a: return cae::KeyCode::A; + case XK_s: return cae::KeyCode::S; + case XK_d: return cae::KeyCode::D; + case XK_Up: return cae::KeyCode::Up; + case XK_Down: return cae::KeyCode::Down; + case XK_Left: return cae::KeyCode::Left; + case XK_Right: return cae::KeyCode::Right; + case XK_Escape: return cae::KeyCode::Escape; + case XK_space: return cae::KeyCode::Space; + case XK_Control_L: return cae::KeyCode::LCtrl; + case XK_Shift_L: return cae::KeyCode::LShift; + case XK_Alt_L: return cae::KeyCode::LAlt; + default: return cae::KeyCode::Count; + } +} + bool cae::X11::create(const std::string &name, const WindowSize size) { m_display = XOpenDisplay(nullptr); @@ -29,8 +53,10 @@ bool cae::X11::create(const std::string &name, const WindowSize size) XStoreName(m_display, m_window, name.c_str()); - XSelectInput(m_display, m_window, ExposureMask | KeyPressMask | StructureNotifyMask); - + XSelectInput(m_display, m_window, + ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask | + PointerMotionMask | ButtonPressMask | ButtonReleaseMask + ); m_wmDeleteMessage = XInternAtom(m_display, "WM_DELETE_WINDOW", False); XSetWMProtocols(m_display, m_window, &m_wmDeleteMessage, 1); @@ -117,48 +143,83 @@ bool cae::X11::shouldClose() const { return m_shouldClose; } void cae::X11::pollEvents() { - while (XPending(m_display) != 0) +} + +bool cae::X11::pollEvent(WindowEvent &outEvent) +{ + if (m_eventQueue.empty() && XPending(m_display) == 0) + return false; + + // vider la queue X11 et remplir m_eventQueue + while (XPending(m_display) > 0) { XEvent event; XNextEvent(m_display, &event); + WindowEvent e{}; switch (event.type) { - case Expose: - { - XGCValues gcValues; - GC gc = XCreateGC(m_display, m_window, 0, &gcValues); - - XColor color; - const Colormap colormap = DefaultColormap(m_display, DefaultScreen(m_display)); - color.red = 0x0000; - color.green = 0x0000; - color.blue = 0x0000; - color.flags = DoRed | DoGreen | DoBlue; - XAllocColor(m_display, colormap, &color); - - XSetForeground(m_display, gc, color.pixel); - - XFillRectangle(m_display, m_window, gc, 0, 0, m_frameBufferSize.width, m_frameBufferSize.height); + case KeyPress: + e.type = WindowEventType::KeyDown; + e.key.key = translateKey(XLookupKeysym(&event.xkey, 0)); + m_eventQueue.push(e); + break; - XFreeGC(m_display, gc); + case KeyRelease: + e.type = WindowEventType::KeyUp; + e.key.key = translateKey(XLookupKeysym(&event.xkey, 0)); + m_eventQueue.push(e); break; - } + case ConfigureNotify: m_frameBufferResized = true; m_frameBufferSize.width = event.xconfigure.width; m_frameBufferSize.height = event.xconfigure.height; + e.type = WindowEventType::Resize; + e.resize.w = event.xconfigure.width; + e.resize.h = event.xconfigure.height; + m_eventQueue.push(e); break; + case ClientMessage: - if (std::cmp_equal(event.xclient.data.l[0], m_wmDeleteMessage)) + if (static_cast(event.xclient.data.l[0]) == m_wmDeleteMessage) { m_shouldClose = true; + e.type = WindowEventType::Close; + m_eventQueue.push(e); } break; + + case MotionNotify: + e.type = WindowEventType::MouseMove; + e.mouseMove.x = event.xmotion.x; + e.mouseMove.y = event.xmotion.y; + m_eventQueue.push(e); + break; + + case ButtonPress: + case ButtonRelease: + e.type = (event.type == ButtonPress) ? WindowEventType::MouseButtonDown : WindowEventType::MouseButtonUp; + e.mouseButton.button = static_cast(event.xbutton.button); + m_eventQueue.push(e); + break; + + case Expose: + // Tu peux gérer le repaint ici ou laisser le moteur appeler draw + break; + default: break; } } - XFlush(m_display); + if (!m_eventQueue.empty()) + { + outEvent = m_eventQueue.front(); + m_eventQueue.pop(); + return true; + } + + return false; } + diff --git a/src/application.cpp b/src/application.cpp index b7de6fa..d9d71ad 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -53,7 +53,7 @@ cae::Application::Application(const ArgsConfig &argsConfig, const EnvConfig &env { m_appConfig.engineConfig = parseEngineConf(argsConfig.config_path); } - setupEngine(PLUGINS::NAME::RENDERER::OPENGL, PLUGINS::NAME::WINDOW::WIN32_, PLUGINS::NAME::SHADER::FRONTEND::GLSL, + setupEngine(PLUGINS::NAME::RENDERER::OPENGL, PLUGINS::NAME::WINDOW::X11, PLUGINS::NAME::SHADER::FRONTEND::GLSL, PLUGINS::NAME::SHADER::IR::SPIRV); } catch (const std::exception &e) From 301e668c6a8d87dafa76d81355caf487f88fe7a2 Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Sun, 18 Jan 2026 19:47:33 +0100 Subject: [PATCH 05/20] Build, duplicated fetch glm --- CMakeLists.txt | 12 +++++------- assets/shaders/glsl/texture.vert | 1 - modules/Engine/CMakeLists.txt | 15 --------------- modules/Engine/include/Engine/Engine.hpp | 1 - modules/Engine/src/engine.cpp | 2 -- modules/Interfaces/include/Interfaces/IWindow.hpp | 10 ++++++++++ .../include/Interfaces/Renderer/IRenderer.hpp | 9 ++------- plugins/Renderer/OpenGL/CMakeLists.txt | 13 ------------- plugins/Window/X11/include/X11/X11.hpp | 7 ++----- plugins/Window/X11/src/x11.cpp | 3 --- 10 files changed, 19 insertions(+), 54 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index da5a54e..33de981 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,10 +35,6 @@ include(ClangTidy) include(ClangFormat) include(CopyAssets) -add_subdirectory(modules) -add_subdirectory(plugins) -add_subdirectory(tests) - include(FetchContent) FetchContent_Declare( nlohmann-json @@ -50,17 +46,19 @@ FetchContent_Declare( FetchContent_MakeAvailable(nlohmann-json) set(GLM_BUILD_TESTS OFF CACHE INTERNAL "") set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "") - FetchContent_Declare( glm - GIT_REPOSITORY https://github.com/g-truc/glm.git + GIT_REPOSITORY "https://github.com/g-truc/glm.git" GIT_TAG 1.0.3 GIT_SHALLOW TRUE GIT_PROGRESS TRUE ) - FetchContent_MakeAvailable(glm) +add_subdirectory(modules) +add_subdirectory(plugins) +add_subdirectory(tests) + add_executable(${PROJECT_NAME} ${SOURCES}) add_dependencies(${PROJECT_NAME} cae-modules) target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ${glm_SOURCE_DIR}) diff --git a/assets/shaders/glsl/texture.vert b/assets/shaders/glsl/texture.vert index 52b3177..46a8288 100644 --- a/assets/shaders/glsl/texture.vert +++ b/assets/shaders/glsl/texture.vert @@ -5,7 +5,6 @@ layout(location = 1) in vec3 aColor; layout(location = 0) out vec3 vColor; -// Uniforms must be in a block layout(set = 0, binding = 0) uniform Matrices { mat4 uMVP; diff --git a/modules/Engine/CMakeLists.txt b/modules/Engine/CMakeLists.txt index 0ce80b0..cca2c57 100644 --- a/modules/Engine/CMakeLists.txt +++ b/modules/Engine/CMakeLists.txt @@ -4,21 +4,6 @@ project(cae-engine LANGUAGES CXX ) -include(FetchContent) - -set(GLM_BUILD_TESTS OFF CACHE INTERNAL "") -set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "") - -FetchContent_Declare( - glm - GIT_REPOSITORY https://github.com/g-truc/glm.git - GIT_TAG 1.0.3 - GIT_SHALLOW TRUE - GIT_PROGRESS TRUE -) - -FetchContent_MakeAvailable(glm) - set(SRC_DIR "${PROJECT_SOURCE_DIR}/src") set(INCLUDE_DIR "${PROJECT_SOURCE_DIR}/include") diff --git a/modules/Engine/include/Engine/Engine.hpp b/modules/Engine/include/Engine/Engine.hpp index 1315d8a..65de25b 100644 --- a/modules/Engine/include/Engine/Engine.hpp +++ b/modules/Engine/include/Engine/Engine.hpp @@ -109,7 +109,6 @@ namespace cae std::unique_ptr m_camera = nullptr; std::unordered_map m_keyState; - bool m_logFps = false; /// diff --git a/modules/Engine/src/engine.cpp b/modules/Engine/src/engine.cpp index c2c0714..0b97e3c 100644 --- a/modules/Engine/src/engine.cpp +++ b/modules/Engine/src/engine.cpp @@ -85,13 +85,11 @@ void cae::Engine::run() glm::vec3 moveDir(0.0f); glm::vec2 lookDir(0.0f); - // Rotation if (m_keyState[KeyCode::Up]) lookDir.y += 1.0f; if (m_keyState[KeyCode::Down]) lookDir.y -= 1.0f; if (m_keyState[KeyCode::Left]) lookDir.x -= 1.0f; if (m_keyState[KeyCode::Right]) lookDir.x += 1.0f; - // Appliquer la rotation if (glm::length(lookDir) > 0.0f) { lookDir *= m_camera->getLookSpeed() * m_clock->getDeltaSeconds(); diff --git a/modules/Interfaces/include/Interfaces/IWindow.hpp b/modules/Interfaces/include/Interfaces/IWindow.hpp index dcb49a7..ddd7239 100644 --- a/modules/Interfaces/include/Interfaces/IWindow.hpp +++ b/modules/Interfaces/include/Interfaces/IWindow.hpp @@ -35,6 +35,11 @@ namespace cae void *display; }; + /// + /// @enum WindowEventType + /// @brief Enum for window event types + /// @namespace cae + /// enum class WindowEventType { KeyDown, KeyUp, @@ -47,6 +52,11 @@ namespace cae Close }; + /// + /// @struct WindowEvent + /// @brief Struct for window events + /// @namespace cae + /// struct WindowEvent { WindowEventType type; diff --git a/modules/Interfaces/include/Interfaces/Renderer/IRenderer.hpp b/modules/Interfaces/include/Interfaces/Renderer/IRenderer.hpp index 97ed0d8..dcb739b 100644 --- a/modules/Interfaces/include/Interfaces/Renderer/IRenderer.hpp +++ b/modules/Interfaces/include/Interfaces/Renderer/IRenderer.hpp @@ -8,7 +8,8 @@ #include "Interfaces/IWindow.hpp" #include "Interfaces/Shader/IShaderFrontend.hpp" -#include "glm/fwd.hpp" + +#include namespace cae { @@ -26,12 +27,6 @@ namespace cae float a; }; - struct Vertex - { - float x, y, z; - float r, g, b; - }; - /// /// @interface IRenderer /// @brief Interface for renderer diff --git a/plugins/Renderer/OpenGL/CMakeLists.txt b/plugins/Renderer/OpenGL/CMakeLists.txt index 37f5126..81b687b 100644 --- a/plugins/Renderer/OpenGL/CMakeLists.txt +++ b/plugins/Renderer/OpenGL/CMakeLists.txt @@ -9,19 +9,6 @@ if (NOT OPENGL_FOUND) return() endif () -set(GLM_BUILD_TESTS OFF CACHE INTERNAL "") -set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "") - -FetchContent_Declare( - glm - GIT_REPOSITORY https://github.com/g-truc/glm.git - GIT_TAG 1.0.3 - GIT_SHALLOW TRUE - GIT_PROGRESS TRUE -) - -FetchContent_MakeAvailable(glm) - include(FetchContent) FetchContent_Declare( glad diff --git a/plugins/Window/X11/include/X11/X11.hpp b/plugins/Window/X11/include/X11/X11.hpp index cbde4ad..446fd9b 100644 --- a/plugins/Window/X11/include/X11/X11.hpp +++ b/plugins/Window/X11/include/X11/X11.hpp @@ -55,14 +55,11 @@ namespace cae void resetResizedFlag() override { m_frameBufferResized = false; } private: - std::queue m_eventQueue; - - WindowSize m_frameBufferSize; - mutable bool m_frameBufferResized = false; - Display *m_display = nullptr; Window m_window = 0; + WindowSize m_frameBufferSize; + mutable bool m_frameBufferResized = false; Atom m_wmDeleteMessage = 0; bool m_shouldClose = false; diff --git a/plugins/Window/X11/src/x11.cpp b/plugins/Window/X11/src/x11.cpp index 8920ce4..8d0834f 100644 --- a/plugins/Window/X11/src/x11.cpp +++ b/plugins/Window/X11/src/x11.cpp @@ -6,7 +6,6 @@ #include #include -#include #include static cae::KeyCode translateKey(const KeySym keysym) @@ -150,7 +149,6 @@ bool cae::X11::pollEvent(WindowEvent &outEvent) if (m_eventQueue.empty() && XPending(m_display) == 0) return false; - // vider la queue X11 et remplir m_eventQueue while (XPending(m_display) > 0) { XEvent event; @@ -205,7 +203,6 @@ bool cae::X11::pollEvent(WindowEvent &outEvent) break; case Expose: - // Tu peux gérer le repaint ici ou laisser le moteur appeler draw break; default: From beb306a8471639ac0c9b3cdf6bfdaedf432f5943 Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Sun, 18 Jan 2026 22:32:20 +0100 Subject: [PATCH 06/20] Fix: camera handled in config --- assets/config/default.json | 13 ++- modules/Engine/include/Engine/Camera.hpp | 28 +++-- modules/Engine/include/Engine/Engine.hpp | 11 ++ modules/Engine/src/engine.cpp | 73 ++++++++---- .../Interfaces/include/Interfaces/IWindow.hpp | 42 +++++-- .../OpenGL/src/context/WGLContextWindows.cpp | 3 +- plugins/Window/GLFW/include/GLFW/GLFW.hpp | 10 +- plugins/Window/GLFW/src/glfw.cpp | 109 +++++++++++------- plugins/Window/Win32/src/win32.cpp | 76 ++++++++---- plugins/Window/X11/include/X11/X11.hpp | 2 +- plugins/Window/X11/src/x11.cpp | 55 +++++---- src/conf.cpp | 54 +++++++++ 12 files changed, 340 insertions(+), 136 deletions(-) diff --git a/assets/config/default.json b/assets/config/default.json index ab09240..ddb9af1 100644 --- a/assets/config/default.json +++ b/assets/config/default.json @@ -3,6 +3,16 @@ "masterVolume": 0.8, "muted": false }, + "camera": { + "position": [0.0, 1.0, 5.0], + "rotation": [0.0, 0.0, 0.0], + "direction": [0.0, 0.0, -1.0], + "movementSpeed": 2.5, + "rotationSpeed": 10.0, + "fov": 45, + "nearPlane": 0.1, + "farPlane": 1000.0 + }, "log": { "fps": false }, @@ -15,9 +25,6 @@ "frameRateLimit": 90, "clearColor": [0.2, 0.2, 0.2, 1.0] }, - "user": { - "name": "User" - }, "window": { "name": "CAE - Cross API Engine", "width": 1920, diff --git a/modules/Engine/include/Engine/Camera.hpp b/modules/Engine/include/Engine/Camera.hpp index a30276d..bbedfda 100644 --- a/modules/Engine/include/Engine/Camera.hpp +++ b/modules/Engine/include/Engine/Camera.hpp @@ -31,6 +31,14 @@ namespace cae Camera(Camera &&) = delete; Camera &operator=(Camera &&) = delete; + Camera(glm::vec3 position, glm::vec3 rotation, glm::vec3 direction, float moveSpeed = CAMERA::MOVE_SPEED, + float lookSpeed = CAMERA::LOOK_SPEED, float fov = CAMERA::FOV, float nearPlane = CAMERA::NEAR_PLANE, + float farPlane = CAMERA::FAR_PLANE) + : m_position(position), m_rotation(rotation), m_direction(direction), m_moveSpeed(moveSpeed), + m_lookSpeed(lookSpeed), m_fov(fov), m_near(nearPlane), m_far(farPlane) + { + } + void setName(const std::string &name) { m_name = name; } void setPosition(const glm::vec3 &position) { m_position = position; } void setRotation(const glm::vec3 &rotation) { m_rotation = rotation; } @@ -51,17 +59,21 @@ namespace cae [[nodiscard]] const float &getNear() const { return m_near; } [[nodiscard]] const float &getFar() const { return m_far; } - [[nodiscard]] glm::mat4 getViewMatrix() const { + [[nodiscard]] glm::mat4 getViewMatrix() const + { return glm::lookAt(m_position, m_position + m_direction, glm::vec3(0.0f, 1.0f, 0.0f)); } - [[nodiscard]] glm::mat4 getProjectionMatrix(const float aspectRatio) const { + [[nodiscard]] glm::mat4 getProjectionMatrix(const float aspectRatio) const + { return glm::perspective(glm::radians(m_fov), aspectRatio, m_near, m_far); } - [[nodiscard]] glm::mat4 getVP(const float aspectRatio) const { + [[nodiscard]] glm::mat4 getViewProjection(const float aspectRatio) const + { return getProjectionMatrix(aspectRatio) * getViewMatrix(); } - void updateDirectionFromRotation() { + void updateDirectionFromRotation() + { const float yaw = glm::radians(m_rotation.y); const float pitch = glm::radians(m_rotation.x); @@ -75,7 +87,8 @@ namespace cae /// @param deltaTime Time delta for movement /// @brief Move the camera in a given direction /// - void move(const glm::vec3 &direction, const float deltaTime) { + void move(const glm::vec3 &direction, const float deltaTime) + { m_position += direction * m_moveSpeed * deltaTime; } @@ -85,7 +98,8 @@ namespace cae /// @param deltaTime Time delta for rotation /// @brief Rotate the camera by given yaw and pitch offsets /// - void rotate(const float yawOffset, const float pitchOffset, const float deltaTime) { + void rotate(const float yawOffset, const float pitchOffset, const float deltaTime) + { m_rotation.y += yawOffset * m_lookSpeed * deltaTime; m_rotation.x += pitchOffset * m_lookSpeed * deltaTime; @@ -98,7 +112,7 @@ namespace cae private: std::string m_name = CAMERA::NAME; - glm::vec3 m_position = glm::vec3(1.0F, 1.0F, 7.0F); + glm::vec3 m_position = glm::vec3(1.0F, 1.0F, 5.0F); glm::vec3 m_rotation = glm::vec3(0.0F, 0.0F, 0.0F); glm::vec3 m_direction = glm::vec3(0.0F, 0.0F, -1.0F); diff --git a/modules/Engine/include/Engine/Engine.hpp b/modules/Engine/include/Engine/Engine.hpp index 65de25b..ce905e7 100644 --- a/modules/Engine/include/Engine/Engine.hpp +++ b/modules/Engine/include/Engine/Engine.hpp @@ -15,6 +15,8 @@ #include "Interfaces/Renderer/IRenderer.hpp" #include "Utils/Clock.hpp" +#include + namespace cae { @@ -28,6 +30,15 @@ namespace cae float audio_master_volume = AUDIO::VOLUME; bool audio_muted = AUDIO::MUTED; + glm::vec3 camera_position = glm::vec3(0.0F, 0.0F, 5.0F); + glm::vec3 camera_rotation = glm::vec3(0.0F, 0.0F, -1.0F); + glm::vec3 camera_direction = glm::vec3(0.0F, 0.0F, -1.0F); + float camera_move_speed = CAMERA::MOVE_SPEED; + float camera_look_speed = CAMERA::LOOK_SPEED; + float camera_fov = CAMERA::FOV; + float camera_near_plane = CAMERA::NEAR_PLANE; + float camera_far_plane = CAMERA::FAR_PLANE; + bool log_fps = LOG::LOG_FPS; std::string network_host = NETWORK::HOST; diff --git a/modules/Engine/src/engine.cpp b/modules/Engine/src/engine.cpp index 0b97e3c..b65f0a5 100644 --- a/modules/Engine/src/engine.cpp +++ b/modules/Engine/src/engine.cpp @@ -26,7 +26,10 @@ cae::Engine::Engine(const EngineConfig &config, const std::function()), m_shaderManager(std::make_unique(shaderFrontendFactories, shaderIRFactory)), - m_camera(std::make_unique()), m_logFps(config.log_fps) + m_camera(std::make_unique(config.camera_position, config.camera_rotation, config.camera_direction, + config.camera_move_speed, config.camera_look_speed, config.camera_fov, + config.camera_near_plane, config.camera_far_plane)), + m_logFps(config.log_fps) { constexpr auto boolToStr = [](const bool b) { return b ? "true" : "false"; }; std::ostringstream msg; @@ -62,15 +65,15 @@ void cae::Engine::run() { std::array fpsBuffer{}; int fpsIndex = 0; + WindowEvent e{}; + constexpr auto model = glm::mat4(1.0F); while (!m_windowPlugin->shouldClose()) { - auto model = glm::mat4(1.0f); - const glm::mat4 mvp = - m_camera->getVP(static_cast(m_windowPlugin->getWindowSize().width) / m_windowPlugin->getWindowSize().height) * - model; + const glm::mat4 mvp = m_camera->getViewProjection(static_cast(m_windowPlugin->getWindowSize().width) / + m_windowPlugin->getWindowSize().height) * + model; m_rendererPlugin->draw(m_windowPlugin->getWindowSize(), "basic", mvp); m_windowPlugin->pollEvents(); - WindowEvent e; while (m_windowPlugin->pollEvent(e)) { if (e.type == WindowEventType::KeyDown) @@ -82,27 +85,51 @@ void cae::Engine::run() m_keyState[e.key.key] = false; } } - glm::vec3 moveDir(0.0f); - glm::vec2 lookDir(0.0f); + glm::vec3 moveDir(0.0F); + glm::vec2 lookDir(0.0F); - if (m_keyState[KeyCode::Up]) lookDir.y += 1.0f; - if (m_keyState[KeyCode::Down]) lookDir.y -= 1.0f; - if (m_keyState[KeyCode::Left]) lookDir.x -= 1.0f; - if (m_keyState[KeyCode::Right]) lookDir.x += 1.0f; + if (m_keyState[KeyCode::Up]) + { + lookDir.y += 1.0f; + } + if (m_keyState[KeyCode::Down]) + { + lookDir.y -= 1.0f; + } + if (m_keyState[KeyCode::Left]) + { + lookDir.x -= 1.0f; + } + if (m_keyState[KeyCode::Right]) + { + lookDir.x += 1.0f; + } if (glm::length(lookDir) > 0.0f) { lookDir *= m_camera->getLookSpeed() * m_clock->getDeltaSeconds(); - m_camera->rotate(lookDir.x, lookDir.y, 1.0f); // deltaTime déjà appliqué dans lookDir + m_camera->rotate(lookDir.x, lookDir.y, 1.0f); } glm::vec3 forward = glm::normalize(glm::vec3(m_camera->getDirection().x, 0.0f, m_camera->getDirection().z)); - glm::vec3 right = glm::normalize(glm::cross(forward, glm::vec3(0.0f, 1.0f, 0.0f))); + glm::vec3 right = glm::normalize(glm::cross(forward, glm::vec3(0.0f, 1.0f, 0.0f))); - if (m_keyState[KeyCode::W]) moveDir += forward; - if (m_keyState[KeyCode::S]) moveDir -= forward; - if (m_keyState[KeyCode::A]) moveDir -= right; - if (m_keyState[KeyCode::D]) moveDir += right; + if (m_keyState[KeyCode::W]) + { + moveDir += forward; + } + if (m_keyState[KeyCode::S]) + { + moveDir -= forward; + } + if (m_keyState[KeyCode::A]) + { + moveDir -= right; + } + if (m_keyState[KeyCode::D]) + { + moveDir += right; + } if (glm::length(moveDir) > 0.0f) { @@ -110,8 +137,14 @@ void cae::Engine::run() m_camera->move(moveDir, m_clock->getDeltaSeconds()); } - if (m_keyState[KeyCode::LCtrl]) m_camera->move(glm::vec3(0.0f, -1.0f, 0.0f), m_clock->getDeltaSeconds()); - if (m_keyState[KeyCode::Space]) m_camera->move(glm::vec3(0.0f, 1.0f, 0.0f), m_clock->getDeltaSeconds()); + if (m_keyState[KeyCode::LCtrl]) + { + m_camera->move(glm::vec3(0.0f, -1.0f, 0.0f), m_clock->getDeltaSeconds()); + } + if (m_keyState[KeyCode::Space]) + { + m_camera->move(glm::vec3(0.0f, 1.0f, 0.0f), m_clock->getDeltaSeconds()); + } if (m_logFps) { diff --git a/modules/Interfaces/include/Interfaces/IWindow.hpp b/modules/Interfaces/include/Interfaces/IWindow.hpp index ddd7239..86d4780 100644 --- a/modules/Interfaces/include/Interfaces/IWindow.hpp +++ b/modules/Interfaces/include/Interfaces/IWindow.hpp @@ -40,7 +40,8 @@ namespace cae /// @brief Enum for window event types /// @namespace cae /// - enum class WindowEventType { + enum class WindowEventType + { KeyDown, KeyUp, MouseMove, @@ -57,16 +58,33 @@ namespace cae /// @brief Struct for window events /// @namespace cae /// - struct WindowEvent { - WindowEventType type; - - union { - struct { KeyCode key; } key; - struct { int x, y; } mouseMove; - struct { MouseButton button; } mouseButton; - struct { float x, y; } scroll; - struct { uint16_t w, h; } resize; - }; + struct WindowEvent + { + WindowEventType type; + + union + { + struct + { + KeyCode key; + } key; + struct + { + int x, y; + } mouseMove; + struct + { + MouseButton button; + } mouseButton; + struct + { + float x, y; + } scroll; + struct + { + uint16_t w, h; + } resize; + }; }; /// @@ -128,7 +146,7 @@ namespace cae /// @return True if an event was polled /// @brief Poll window events into outEvent /// - virtual bool pollEvent(WindowEvent& outEvent) = 0; + virtual bool pollEvent(WindowEvent &outEvent) = 0; /// /// @return True if the window was resized diff --git a/plugins/Renderer/OpenGL/src/context/WGLContextWindows.cpp b/plugins/Renderer/OpenGL/src/context/WGLContextWindows.cpp index e989c75..0b56da4 100644 --- a/plugins/Renderer/OpenGL/src/context/WGLContextWindows.cpp +++ b/plugins/Renderer/OpenGL/src/context/WGLContextWindows.cpp @@ -36,7 +36,8 @@ static void *win32GetGLProc(const char *name) { auto *proc = (void *)wglGetProcAddress(name); - if (proc == nullptr || proc == reinterpret_cast(0x1) || proc == reinterpret_cast(0x2) || proc == reinterpret_cast(0x3) || proc == reinterpret_cast(-1)) + if (proc == nullptr || proc == reinterpret_cast(0x1) || proc == reinterpret_cast(0x2) || + proc == reinterpret_cast(0x3) || proc == reinterpret_cast(-1)) { if (g_opengl32 == nullptr) { diff --git a/plugins/Window/GLFW/include/GLFW/GLFW.hpp b/plugins/Window/GLFW/include/GLFW/GLFW.hpp index ef6a0ec..9e7bfaf 100644 --- a/plugins/Window/GLFW/include/GLFW/GLFW.hpp +++ b/plugins/Window/GLFW/include/GLFW/GLFW.hpp @@ -59,11 +59,11 @@ namespace cae void resetResizedFlag() override { m_frameBufferResized = false; } private: - static void frameBufferResizeCallback(GLFWwindow* window, int width, int height); - static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); - static void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods); - static void cursorPosCallback(GLFWwindow* window, double x, double y); - static void scrollCallback(GLFWwindow* window, double xoffset, double yoffset); + static void frameBufferResizeCallback(GLFWwindow *window, int width, int height); + static void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); + static void mouseButtonCallback(GLFWwindow *window, int button, int action, int mods); + static void cursorPosCallback(GLFWwindow *window, double x, double y); + static void scrollCallback(GLFWwindow *window, double xoffset, double yoffset); std::queue m_eventQueue; diff --git a/plugins/Window/GLFW/src/glfw.cpp b/plugins/Window/GLFW/src/glfw.cpp index 79bbeb2..c9957b7 100644 --- a/plugins/Window/GLFW/src/glfw.cpp +++ b/plugins/Window/GLFW/src/glfw.cpp @@ -8,27 +8,55 @@ static cae::KeyCode translateKey(const int key) { - static const std::unordered_map keyMap = { - {GLFW_KEY_A, cae::KeyCode::A}, {GLFW_KEY_B, cae::KeyCode::B}, {GLFW_KEY_C, cae::KeyCode::C}, - {GLFW_KEY_D, cae::KeyCode::D}, {GLFW_KEY_E, cae::KeyCode::E}, {GLFW_KEY_F, cae::KeyCode::F}, - {GLFW_KEY_G, cae::KeyCode::G}, {GLFW_KEY_H, cae::KeyCode::H}, {GLFW_KEY_I, cae::KeyCode::I}, - {GLFW_KEY_J, cae::KeyCode::J}, {GLFW_KEY_K, cae::KeyCode::K}, {GLFW_KEY_L, cae::KeyCode::L}, - {GLFW_KEY_M, cae::KeyCode::M}, {GLFW_KEY_N, cae::KeyCode::N}, {GLFW_KEY_O, cae::KeyCode::O}, - {GLFW_KEY_P, cae::KeyCode::P}, {GLFW_KEY_Q, cae::KeyCode::Q}, {GLFW_KEY_R, cae::KeyCode::R}, - {GLFW_KEY_S, cae::KeyCode::S}, {GLFW_KEY_T, cae::KeyCode::T}, {GLFW_KEY_U, cae::KeyCode::U}, - {GLFW_KEY_V, cae::KeyCode::V}, {GLFW_KEY_W, cae::KeyCode::W}, {GLFW_KEY_X, cae::KeyCode::X}, - {GLFW_KEY_Y, cae::KeyCode::Y}, {GLFW_KEY_Z, cae::KeyCode::Z}, - - {GLFW_KEY_0, cae::KeyCode::Num0}, {GLFW_KEY_1, cae::KeyCode::Num1}, {GLFW_KEY_2, cae::KeyCode::Num2}, - {GLFW_KEY_3, cae::KeyCode::Num3}, {GLFW_KEY_4, cae::KeyCode::Num4}, {GLFW_KEY_5, cae::KeyCode::Num5}, - {GLFW_KEY_6, cae::KeyCode::Num6}, {GLFW_KEY_7, cae::KeyCode::Num7}, {GLFW_KEY_8, cae::KeyCode::Num8}, + static const std::unordered_map keyMap = { + {GLFW_KEY_A, cae::KeyCode::A}, + {GLFW_KEY_B, cae::KeyCode::B}, + {GLFW_KEY_C, cae::KeyCode::C}, + {GLFW_KEY_D, cae::KeyCode::D}, + {GLFW_KEY_E, cae::KeyCode::E}, + {GLFW_KEY_F, cae::KeyCode::F}, + {GLFW_KEY_G, cae::KeyCode::G}, + {GLFW_KEY_H, cae::KeyCode::H}, + {GLFW_KEY_I, cae::KeyCode::I}, + {GLFW_KEY_J, cae::KeyCode::J}, + {GLFW_KEY_K, cae::KeyCode::K}, + {GLFW_KEY_L, cae::KeyCode::L}, + {GLFW_KEY_M, cae::KeyCode::M}, + {GLFW_KEY_N, cae::KeyCode::N}, + {GLFW_KEY_O, cae::KeyCode::O}, + {GLFW_KEY_P, cae::KeyCode::P}, + {GLFW_KEY_Q, cae::KeyCode::Q}, + {GLFW_KEY_R, cae::KeyCode::R}, + {GLFW_KEY_S, cae::KeyCode::S}, + {GLFW_KEY_T, cae::KeyCode::T}, + {GLFW_KEY_U, cae::KeyCode::U}, + {GLFW_KEY_V, cae::KeyCode::V}, + {GLFW_KEY_W, cae::KeyCode::W}, + {GLFW_KEY_X, cae::KeyCode::X}, + {GLFW_KEY_Y, cae::KeyCode::Y}, + {GLFW_KEY_Z, cae::KeyCode::Z}, + + {GLFW_KEY_0, cae::KeyCode::Num0}, + {GLFW_KEY_1, cae::KeyCode::Num1}, + {GLFW_KEY_2, cae::KeyCode::Num2}, + {GLFW_KEY_3, cae::KeyCode::Num3}, + {GLFW_KEY_4, cae::KeyCode::Num4}, + {GLFW_KEY_5, cae::KeyCode::Num5}, + {GLFW_KEY_6, cae::KeyCode::Num6}, + {GLFW_KEY_7, cae::KeyCode::Num7}, + {GLFW_KEY_8, cae::KeyCode::Num8}, {GLFW_KEY_9, cae::KeyCode::Num9}, {GLFW_KEY_ESCAPE, cae::KeyCode::Escape}, - {GLFW_KEY_LEFT, cae::KeyCode::Left}, {GLFW_KEY_RIGHT, cae::KeyCode::Right}, - {GLFW_KEY_UP, cae::KeyCode::Up}, {GLFW_KEY_DOWN, cae::KeyCode::Down}, - {GLFW_KEY_SPACE, cae::KeyCode::Space}, {GLFW_KEY_ENTER, cae::KeyCode::Enter}, - {GLFW_KEY_BACKSPACE, cae::KeyCode::Backspace}, {GLFW_KEY_TAB, cae::KeyCode::Tab}, - {GLFW_KEY_LEFT_SHIFT, cae::KeyCode::LShift}, {GLFW_KEY_LEFT_CONTROL, cae::KeyCode::LCtrl}, + {GLFW_KEY_LEFT, cae::KeyCode::Left}, + {GLFW_KEY_RIGHT, cae::KeyCode::Right}, + {GLFW_KEY_UP, cae::KeyCode::Up}, + {GLFW_KEY_DOWN, cae::KeyCode::Down}, + {GLFW_KEY_SPACE, cae::KeyCode::Space}, + {GLFW_KEY_ENTER, cae::KeyCode::Enter}, + {GLFW_KEY_BACKSPACE, cae::KeyCode::Backspace}, + {GLFW_KEY_TAB, cae::KeyCode::Tab}, + {GLFW_KEY_LEFT_SHIFT, cae::KeyCode::LShift}, + {GLFW_KEY_LEFT_CONTROL, cae::KeyCode::LCtrl}, {GLFW_KEY_LEFT_ALT, cae::KeyCode::LAlt} // ... }; @@ -36,10 +64,11 @@ static cae::KeyCode translateKey(const int key) return it != keyMap.end() ? it->second : cae::KeyCode::Count; } -void cae::GLFW::keyCallback(GLFWwindow* window, const int key, int, const int action, int) +void cae::GLFW::keyCallback(GLFWwindow *window, const int key, int, const int action, int) { - auto* self = static_cast(glfwGetWindowUserPointer(window)); - if (!self) return; + auto *self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) + return; WindowEvent e{}; if (action == GLFW_PRESS) @@ -53,24 +82,24 @@ void cae::GLFW::keyCallback(GLFWwindow* window, const int key, int, const int ac self->m_eventQueue.push(e); } -void cae::GLFW::mouseButtonCallback(GLFWwindow* window, int button, const int action, int) +void cae::GLFW::mouseButtonCallback(GLFWwindow *window, int button, const int action, int) { - auto* self = static_cast(glfwGetWindowUserPointer(window)); - if (!self) return; + auto *self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) + return; WindowEvent e{}; - e.type = (action == GLFW_PRESS) - ? WindowEventType::MouseButtonDown - : WindowEventType::MouseButtonUp; + e.type = (action == GLFW_PRESS) ? WindowEventType::MouseButtonDown : WindowEventType::MouseButtonUp; e.mouseButton.button = static_cast(button); self->m_eventQueue.push(e); } -void cae::GLFW::cursorPosCallback(GLFWwindow* window, const double x, const double y) +void cae::GLFW::cursorPosCallback(GLFWwindow *window, const double x, const double y) { - auto* self = static_cast(glfwGetWindowUserPointer(window)); - if (!self) return; + auto *self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) + return; WindowEvent e{}; e.type = WindowEventType::MouseMove; @@ -80,10 +109,11 @@ void cae::GLFW::cursorPosCallback(GLFWwindow* window, const double x, const doub self->m_eventQueue.push(e); } -void cae::GLFW::scrollCallback(GLFWwindow* window, const double xoffset, const double yoffset) +void cae::GLFW::scrollCallback(GLFWwindow *window, const double xoffset, const double yoffset) { - auto* self = static_cast(glfwGetWindowUserPointer(window)); - if (!self) return; + auto *self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) + return; WindowEvent e{}; e.type = WindowEventType::MouseScroll; @@ -93,17 +123,14 @@ void cae::GLFW::scrollCallback(GLFWwindow* window, const double xoffset, const d self->m_eventQueue.push(e); } - void cae::GLFW::frameBufferResizeCallback(GLFWwindow *window, const int width, const int height) { - auto* self = static_cast(glfwGetWindowUserPointer(window)); - if (!self) return; + auto *self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) + return; self->m_frameBufferResized = true; - self->m_frameBufferSize = { - static_cast(width), - static_cast(height) - }; + self->m_frameBufferSize = {static_cast(width), static_cast(height)}; WindowEvent e{}; e.type = WindowEventType::Resize; diff --git a/plugins/Window/Win32/src/win32.cpp b/plugins/Window/Win32/src/win32.cpp index c519812..bd1346c 100644 --- a/plugins/Window/Win32/src/win32.cpp +++ b/plugins/Window/Win32/src/win32.cpp @@ -13,26 +13,56 @@ constexpr wchar_t WINDOW_CLASS_NAME[] = L"CAE_WindowsWindowClass"; cae::KeyCode cae::Win32::mapWinKey(const WPARAM key) { static const std::unordered_map keyMap = { - {'A', KeyCode::A}, {'B', KeyCode::B}, {'C', KeyCode::C}, - {'D', KeyCode::D}, {'E', KeyCode::E}, {'F', KeyCode::F}, - {'G', KeyCode::G}, {'H', KeyCode::H}, {'I', KeyCode::I}, - {'J', KeyCode::J}, {'K', KeyCode::K}, {'L', KeyCode::L}, - {'M', KeyCode::M}, {'N', KeyCode::N}, {'O', KeyCode::O}, - {'P', KeyCode::P}, {'Q', KeyCode::Q}, {'R', KeyCode::R}, - {'S', KeyCode::S}, {'T', KeyCode::T}, {'U', KeyCode::U}, - {'V', KeyCode::V}, {'W', KeyCode::W}, {'X', KeyCode::X}, - {'Y', KeyCode::Y}, {'Z', KeyCode::Z}, - - {'0', KeyCode::Num0}, {'1', KeyCode::Num1}, {'2', KeyCode::Num2}, - {'3', KeyCode::Num3}, {'4', KeyCode::Num4}, {'5', KeyCode::Num5}, - {'6', KeyCode::Num6}, {'7', KeyCode::Num7}, {'8', KeyCode::Num8}, {'9', KeyCode::Num9}, + {'A', KeyCode::A}, + {'B', KeyCode::B}, + {'C', KeyCode::C}, + {'D', KeyCode::D}, + {'E', KeyCode::E}, + {'F', KeyCode::F}, + {'G', KeyCode::G}, + {'H', KeyCode::H}, + {'I', KeyCode::I}, + {'J', KeyCode::J}, + {'K', KeyCode::K}, + {'L', KeyCode::L}, + {'M', KeyCode::M}, + {'N', KeyCode::N}, + {'O', KeyCode::O}, + {'P', KeyCode::P}, + {'Q', KeyCode::Q}, + {'R', KeyCode::R}, + {'S', KeyCode::S}, + {'T', KeyCode::T}, + {'U', KeyCode::U}, + {'V', KeyCode::V}, + {'W', KeyCode::W}, + {'X', KeyCode::X}, + {'Y', KeyCode::Y}, + {'Z', KeyCode::Z}, + + {'0', KeyCode::Num0}, + {'1', KeyCode::Num1}, + {'2', KeyCode::Num2}, + {'3', KeyCode::Num3}, + {'4', KeyCode::Num4}, + {'5', KeyCode::Num5}, + {'6', KeyCode::Num6}, + {'7', KeyCode::Num7}, + {'8', KeyCode::Num8}, + {'9', KeyCode::Num9}, {VK_ESCAPE, KeyCode::Escape}, - {VK_LEFT, KeyCode::Left}, {VK_RIGHT, KeyCode::Right}, - {VK_UP, KeyCode::Up}, {VK_DOWN, KeyCode::Down}, - {VK_SPACE, KeyCode::Space}, {VK_RETURN, KeyCode::Enter}, - {VK_BACK, KeyCode::Backspace}, {VK_TAB, KeyCode::Tab}, - {VK_SHIFT, KeyCode::LShift}, {VK_CONTROL, KeyCode::LCtrl}, {VK_MENU, KeyCode::LAlt} + {VK_LEFT, KeyCode::Left}, + {VK_RIGHT, KeyCode::Right}, + {VK_UP, KeyCode::Up}, + {VK_DOWN, KeyCode::Down}, + {VK_SPACE, KeyCode::Space}, + {VK_RETURN, KeyCode::Enter}, + {VK_BACK, KeyCode::Backspace}, + {VK_TAB, KeyCode::Tab}, + {VK_SHIFT, KeyCode::LShift}, + {VK_CONTROL, KeyCode::LCtrl}, + {VK_MENU, KeyCode::LAlt} // ... }; @@ -40,7 +70,6 @@ cae::KeyCode cae::Win32::mapWinKey(const WPARAM key) return it != keyMap.end() ? it->second : KeyCode::Count; } - LRESULT CALLBACK cae::Win32::WindowProc(const HWND hwnd, const UINT msg, const WPARAM wParam, const LPARAM lParam) { Win32 *self = nullptr; @@ -54,7 +83,8 @@ LRESULT CALLBACK cae::Win32::WindowProc(const HWND hwnd, const UINT msg, const W } self = reinterpret_cast(GetWindowLongPtrW(hwnd, GWLP_USERDATA)); - if (!self) return DefWindowProcW(hwnd, msg, wParam, lParam); + if (!self) + return DefWindowProcW(hwnd, msg, wParam, lParam); WindowEvent e{}; switch (msg) @@ -93,7 +123,6 @@ LRESULT CALLBACK cae::Win32::WindowProc(const HWND hwnd, const UINT msg, const W return DefWindowProcW(hwnd, msg, wParam, lParam); } - bool cae::Win32::create(const std::string &name, const WindowSize size) { m_hInstance = GetModuleHandleW(nullptr); @@ -130,8 +159,8 @@ bool cae::Win32::create(const std::string &name, const WindowSize size) } classRegistered = true; } - m_hwnd = CreateWindowExW(0, WINDOW_CLASS_NAME, L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, - CW_USEDEFAULT, size.width, size.height, nullptr, nullptr, m_hInstance, this); + m_hwnd = CreateWindowExW(0, WINDOW_CLASS_NAME, L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, size.width, + size.height, nullptr, nullptr, m_hInstance, this); if (m_hwnd == nullptr) { @@ -261,4 +290,3 @@ bool cae::Win32::pollEvent(WindowEvent &event) return false; } - diff --git a/plugins/Window/X11/include/X11/X11.hpp b/plugins/Window/X11/include/X11/X11.hpp index 446fd9b..86eb5b7 100644 --- a/plugins/Window/X11/include/X11/X11.hpp +++ b/plugins/Window/X11/include/X11/X11.hpp @@ -49,7 +49,7 @@ namespace cae [[nodiscard]] bool shouldClose() const override; void pollEvents() override; - bool pollEvent(WindowEvent& outEvent) override; + bool pollEvent(WindowEvent &outEvent) override; bool wasResized() const override { return m_frameBufferResized; } void resetResizedFlag() override { m_frameBufferResized = false; } diff --git a/plugins/Window/X11/src/x11.cpp b/plugins/Window/X11/src/x11.cpp index 8d0834f..635b4de 100644 --- a/plugins/Window/X11/src/x11.cpp +++ b/plugins/Window/X11/src/x11.cpp @@ -12,20 +12,34 @@ static cae::KeyCode translateKey(const KeySym keysym) { switch (keysym) { - case XK_w: return cae::KeyCode::W; - case XK_a: return cae::KeyCode::A; - case XK_s: return cae::KeyCode::S; - case XK_d: return cae::KeyCode::D; - case XK_Up: return cae::KeyCode::Up; - case XK_Down: return cae::KeyCode::Down; - case XK_Left: return cae::KeyCode::Left; - case XK_Right: return cae::KeyCode::Right; - case XK_Escape: return cae::KeyCode::Escape; - case XK_space: return cae::KeyCode::Space; - case XK_Control_L: return cae::KeyCode::LCtrl; - case XK_Shift_L: return cae::KeyCode::LShift; - case XK_Alt_L: return cae::KeyCode::LAlt; - default: return cae::KeyCode::Count; + case XK_w: + return cae::KeyCode::W; + case XK_a: + return cae::KeyCode::A; + case XK_s: + return cae::KeyCode::S; + case XK_d: + return cae::KeyCode::D; + case XK_Up: + return cae::KeyCode::Up; + case XK_Down: + return cae::KeyCode::Down; + case XK_Left: + return cae::KeyCode::Left; + case XK_Right: + return cae::KeyCode::Right; + case XK_Escape: + return cae::KeyCode::Escape; + case XK_space: + return cae::KeyCode::Space; + case XK_Control_L: + return cae::KeyCode::LCtrl; + case XK_Shift_L: + return cae::KeyCode::LShift; + case XK_Alt_L: + return cae::KeyCode::LAlt; + default: + return cae::KeyCode::Count; } } @@ -53,9 +67,8 @@ bool cae::X11::create(const std::string &name, const WindowSize size) XStoreName(m_display, m_window, name.c_str()); XSelectInput(m_display, m_window, - ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask | - PointerMotionMask | ButtonPressMask | ButtonReleaseMask - ); + ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask | PointerMotionMask | + ButtonPressMask | ButtonReleaseMask); m_wmDeleteMessage = XInternAtom(m_display, "WM_DELETE_WINDOW", False); XSetWMProtocols(m_display, m_window, &m_wmDeleteMessage, 1); @@ -140,9 +153,7 @@ bool cae::X11::setIcon(const std::string &path) const bool cae::X11::shouldClose() const { return m_shouldClose; } -void cae::X11::pollEvents() -{ -} +void cae::X11::pollEvents() {} bool cae::X11::pollEvent(WindowEvent &outEvent) { @@ -197,7 +208,8 @@ bool cae::X11::pollEvent(WindowEvent &outEvent) case ButtonPress: case ButtonRelease: - e.type = (event.type == ButtonPress) ? WindowEventType::MouseButtonDown : WindowEventType::MouseButtonUp; + e.type = + (event.type == ButtonPress) ? WindowEventType::MouseButtonDown : WindowEventType::MouseButtonUp; e.mouseButton.button = static_cast(event.xbutton.button); m_eventQueue.push(e); break; @@ -219,4 +231,3 @@ bool cae::X11::pollEvent(WindowEvent &outEvent) return false; } - diff --git a/src/conf.cpp b/src/conf.cpp index 95037cf..435eb51 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -50,6 +50,60 @@ cae::EngineConfig cae::Application::parseEngineConf(const std::string &path) config.audio_muted = audio["muted"]; } } + if (j.contains("camera")) + { + const auto &camera = j["camera"]; + if (camera.contains("position") && camera["position"].is_array() && camera["position"].size() == 3) + { + if (const auto &position = camera["position"]; + position[0].is_number_float() && position[1].is_number_float() && position[2].is_number_float()) + { + config.camera_position.x = position[0]; + config.camera_position.y = position[1]; + config.camera_position.z = position[2]; + } + } + if (camera.contains("rotation") && camera["rotation"].is_array() && camera["rotation"].size() == 3) + { + if (const auto &rotation = camera["rotation"]; + rotation[0].is_number_float() && rotation[1].is_number_float() && rotation[2].is_number_float()) + { + config.camera_rotation.x = rotation[0]; + config.camera_rotation.y = rotation[1]; + config.camera_rotation.z = rotation[2]; + } + } + if (camera.contains("direction") && camera["direction"].is_array() && camera["direction"].size() == 3) + { + if (const auto &direction = camera["direction"]; + direction[0].is_number_float() && direction[1].is_number_float() && direction[2].is_number_float()) + { + config.camera_direction.x = direction[0]; + config.camera_direction.y = direction[1]; + config.camera_direction.z = direction[2]; + } + } + if (camera.contains("movementSpeed") && camera["movementSpeed"].is_number_float()) + { + config.camera_move_speed = camera["movementSpeed"]; + } + if (camera.contains("rotationSpeed") && camera["rotationSpeed"].is_number_float()) + { + config.camera_look_speed = camera["rotationSpeed"]; + } + if (camera.contains("fov") && camera["fov"].is_number_unsigned()) + { + config.camera_fov = camera["fov"]; + } + if (camera.contains("nearPlane") && camera["nearPlane"].is_number_float()) + { + config.camera_near_plane = camera["nearPlane"]; + } + if (camera.contains("farPlane") && camera["farPlane"].is_number_float()) + { + config.camera_far_plane = camera["farPlane"]; + } + } if (j.contains("log")) { if (const auto &log = j["log"]; log.contains("fps") && log["fps"].is_boolean()) From e48fdd1516b480af0b22f13fc1fd1914d0a66603 Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Mon, 19 Jan 2026 08:50:53 +0100 Subject: [PATCH 07/20] Fix: abstract class for all interfaces --- assets/config/default.json | 2 +- modules/Engine/include/Engine/Engine.hpp | 8 ++---- .../Engine/include/Engine/ShaderManager.hpp | 2 +- modules/Engine/src/engine.cpp | 6 ++--- .../include/Interfaces/Audio/AAudio.hpp | 27 +++++++++++++++++++ .../include/Interfaces/{ => Audio}/IAudio.hpp | 0 .../include/Interfaces/Model/AModel.hpp | 27 +++++++++++++++++++ .../include/Interfaces/{ => Model}/IModel.hpp | 0 .../include/Interfaces/Network/ANetwork.hpp | 27 +++++++++++++++++++ .../Interfaces/{ => Network}/INetwork.hpp | 0 .../include/Interfaces/Physic/APhysic.hpp | 27 +++++++++++++++++++ .../Interfaces/{ => Physic}/IPhysic.hpp | 0 .../include/Interfaces/Renderer/ARenderer.hpp | 3 --- .../include/Interfaces/Renderer/IRenderer.hpp | 4 +-- .../Shader/Frontend/AShaderFrontend.hpp | 27 +++++++++++++++++++ .../Shader/{ => Frontend}/IShaderFrontend.hpp | 0 .../Interfaces/Shader/IR/AShaderIR.hpp | 27 +++++++++++++++++++ .../Interfaces/Shader/{ => IR}/IShaderIR.hpp | 2 +- .../Interfaces/include/Interfaces/UI/AUI.hpp | 27 +++++++++++++++++++ .../include/Interfaces/{ => UI}/IUI.hpp | 0 .../include/Interfaces/Window/AWindow.hpp | 27 +++++++++++++++++++ .../Interfaces/{ => Window}/IWindow.hpp | 8 +++--- .../OpenGL/include/OPGL/Context/IContext.hpp | 2 +- .../Frontend/GLSL/include/GLSL/GLSL.hpp | 4 +-- .../Shader/IR/SPIRV/include/SPIRV/SPIRV.hpp | 4 +-- plugins/Window/GLFW/include/GLFW/GLFW.hpp | 4 +-- plugins/Window/Win32/include/Win32/Win32.hpp | 4 +-- plugins/Window/X11/include/X11/X11.hpp | 4 +-- src/application.cpp | 2 +- 29 files changed, 240 insertions(+), 35 deletions(-) create mode 100644 modules/Interfaces/include/Interfaces/Audio/AAudio.hpp rename modules/Interfaces/include/Interfaces/{ => Audio}/IAudio.hpp (100%) create mode 100644 modules/Interfaces/include/Interfaces/Model/AModel.hpp rename modules/Interfaces/include/Interfaces/{ => Model}/IModel.hpp (100%) create mode 100644 modules/Interfaces/include/Interfaces/Network/ANetwork.hpp rename modules/Interfaces/include/Interfaces/{ => Network}/INetwork.hpp (100%) create mode 100644 modules/Interfaces/include/Interfaces/Physic/APhysic.hpp rename modules/Interfaces/include/Interfaces/{ => Physic}/IPhysic.hpp (100%) create mode 100644 modules/Interfaces/include/Interfaces/Shader/Frontend/AShaderFrontend.hpp rename modules/Interfaces/include/Interfaces/Shader/{ => Frontend}/IShaderFrontend.hpp (100%) create mode 100644 modules/Interfaces/include/Interfaces/Shader/IR/AShaderIR.hpp rename modules/Interfaces/include/Interfaces/Shader/{ => IR}/IShaderIR.hpp (96%) create mode 100644 modules/Interfaces/include/Interfaces/UI/AUI.hpp rename modules/Interfaces/include/Interfaces/{ => UI}/IUI.hpp (100%) create mode 100644 modules/Interfaces/include/Interfaces/Window/AWindow.hpp rename modules/Interfaces/include/Interfaces/{ => Window}/IWindow.hpp (96%) diff --git a/assets/config/default.json b/assets/config/default.json index ddb9af1..b1f247c 100644 --- a/assets/config/default.json +++ b/assets/config/default.json @@ -8,7 +8,7 @@ "rotation": [0.0, 0.0, 0.0], "direction": [0.0, 0.0, -1.0], "movementSpeed": 2.5, - "rotationSpeed": 10.0, + "rotationSpeed": 7.5, "fov": 45, "nearPlane": 0.1, "farPlane": 1000.0 diff --git a/modules/Engine/include/Engine/Engine.hpp b/modules/Engine/include/Engine/Engine.hpp index ce905e7..1221b00 100644 --- a/modules/Engine/include/Engine/Engine.hpp +++ b/modules/Engine/include/Engine/Engine.hpp @@ -9,9 +9,8 @@ #include "Engine/Camera.hpp" #include "Engine/ShaderManager.hpp" -#include "Interfaces/IAudio.hpp" -#include "Interfaces/INetwork.hpp" -#include "Interfaces/Input/IInput.hpp" +#include "Interfaces/Audio/IAudio.hpp" +#include "Interfaces/Network/INetwork.hpp" #include "Interfaces/Renderer/IRenderer.hpp" #include "Utils/Clock.hpp" @@ -68,7 +67,6 @@ namespace cae public: Engine(const EngineConfig &config, const std::function()> &audioFactory, - const std::function()> &inputFactory, const std::function()> &networkFactory, const std::function()> &rendererFactory, const std::function()> &shaderIRFactory, @@ -82,7 +80,6 @@ namespace cae Engine &operator=(Engine &&) = delete; [[nodiscard]] const std::shared_ptr &getAudio() const { return m_audioPlugin; } - [[nodiscard]] const std::shared_ptr &getInput() const { return m_inputPlugin; } [[nodiscard]] const std::shared_ptr &getNetwork() const { return m_networkPlugin; } [[nodiscard]] const std::shared_ptr &getRenderer() const { return m_rendererPlugin; } [[nodiscard]] const std::shared_ptr &getWindow() const { return m_windowPlugin; } @@ -110,7 +107,6 @@ namespace cae private: std::shared_ptr m_audioPlugin = nullptr; - std::shared_ptr m_inputPlugin = nullptr; std::shared_ptr m_networkPlugin = nullptr; std::shared_ptr m_rendererPlugin = nullptr; std::shared_ptr m_windowPlugin = nullptr; diff --git a/modules/Engine/include/Engine/ShaderManager.hpp b/modules/Engine/include/Engine/ShaderManager.hpp index 090dafd..7f1a258 100644 --- a/modules/Engine/include/Engine/ShaderManager.hpp +++ b/modules/Engine/include/Engine/ShaderManager.hpp @@ -6,7 +6,7 @@ #pragma once -#include "Interfaces/Shader/IShaderIR.hpp" +#include "Interfaces/Shader/IR/IShaderIR.hpp" #include diff --git a/modules/Engine/src/engine.cpp b/modules/Engine/src/engine.cpp index b65f0a5..ab77bf6 100644 --- a/modules/Engine/src/engine.cpp +++ b/modules/Engine/src/engine.cpp @@ -17,14 +17,13 @@ void printFps(std::array &fpsBuffer, int &fpsIndex, const float delta } cae::Engine::Engine(const EngineConfig &config, const std::function()> &audioFactory, - const std::function()> &inputFactory, const std::function()> &networkFactory, const std::function()> &rendererFactory, const std::function()> &shaderIRFactory, const std::vector()>> &shaderFrontendFactories, const std::function()> &windowFactory) - : m_audioPlugin(audioFactory()), m_inputPlugin(inputFactory()), m_networkPlugin(networkFactory()), - m_rendererPlugin(rendererFactory()), m_windowPlugin(windowFactory()), m_clock(std::make_unique()), + : m_audioPlugin(audioFactory()), m_networkPlugin(networkFactory()), m_rendererPlugin(rendererFactory()), + m_windowPlugin(windowFactory()), m_clock(std::make_unique()), m_shaderManager(std::make_unique(shaderFrontendFactories, shaderIRFactory)), m_camera(std::make_unique(config.camera_position, config.camera_rotation, config.camera_direction, config.camera_move_speed, config.camera_look_speed, config.camera_fov, @@ -160,7 +159,6 @@ void cae::Engine::stop() m_windowPlugin->close(); m_audioPlugin = nullptr; - m_inputPlugin = nullptr; m_networkPlugin = nullptr; m_rendererPlugin = nullptr; m_windowPlugin = nullptr; diff --git a/modules/Interfaces/include/Interfaces/Audio/AAudio.hpp b/modules/Interfaces/include/Interfaces/Audio/AAudio.hpp new file mode 100644 index 0000000..b0c2df1 --- /dev/null +++ b/modules/Interfaces/include/Interfaces/Audio/AAudio.hpp @@ -0,0 +1,27 @@ +/// +/// @file IAudio.hpp +/// @brief This file contains the audio abstract class +/// @namespace cae +/// + +#pragma once + +#include "Interfaces/Audio/IAudio.hpp" + +namespace cae +{ + + /// + /// @interface AAudio + /// @brief Abstract class for audio + /// @namespace cae + /// + class AAudio : public IAudio + { + + public: + ~AAudio() override = default; + + }; // interface AAudio + +} // namespace cae diff --git a/modules/Interfaces/include/Interfaces/IAudio.hpp b/modules/Interfaces/include/Interfaces/Audio/IAudio.hpp similarity index 100% rename from modules/Interfaces/include/Interfaces/IAudio.hpp rename to modules/Interfaces/include/Interfaces/Audio/IAudio.hpp diff --git a/modules/Interfaces/include/Interfaces/Model/AModel.hpp b/modules/Interfaces/include/Interfaces/Model/AModel.hpp new file mode 100644 index 0000000..fad0d4f --- /dev/null +++ b/modules/Interfaces/include/Interfaces/Model/AModel.hpp @@ -0,0 +1,27 @@ +/// +/// @file AModel.hpp +/// @brief This file contains the model abstract class +/// @namespace cae +/// + +#pragma once + +#include "Interfaces/Model/IModel.hpp" + +namespace cae +{ + + /// + /// @interface AModel + /// @brief Abstract class for model + /// @namespace cae + /// + class AModel : public IModel + { + + public: + ~AModel() override = default; + + }; // interface AModel + +} // namespace cae diff --git a/modules/Interfaces/include/Interfaces/IModel.hpp b/modules/Interfaces/include/Interfaces/Model/IModel.hpp similarity index 100% rename from modules/Interfaces/include/Interfaces/IModel.hpp rename to modules/Interfaces/include/Interfaces/Model/IModel.hpp diff --git a/modules/Interfaces/include/Interfaces/Network/ANetwork.hpp b/modules/Interfaces/include/Interfaces/Network/ANetwork.hpp new file mode 100644 index 0000000..95e75d1 --- /dev/null +++ b/modules/Interfaces/include/Interfaces/Network/ANetwork.hpp @@ -0,0 +1,27 @@ +/// +/// @file ANetwork.hpp +/// @brief This file contains the network abstract class +/// @namespace cae +/// + +#pragma once + +#include "Interfaces/Network/INetwork.hpp" + +namespace cae +{ + + /// + /// @interface ANetwork + /// @brief Abstract class for network + /// @namespace cae + /// + class ANetwork : public INetwork + { + + public: + ~ANetwork() override = default; + + }; // interface ANetwork + +} // namespace cae diff --git a/modules/Interfaces/include/Interfaces/INetwork.hpp b/modules/Interfaces/include/Interfaces/Network/INetwork.hpp similarity index 100% rename from modules/Interfaces/include/Interfaces/INetwork.hpp rename to modules/Interfaces/include/Interfaces/Network/INetwork.hpp diff --git a/modules/Interfaces/include/Interfaces/Physic/APhysic.hpp b/modules/Interfaces/include/Interfaces/Physic/APhysic.hpp new file mode 100644 index 0000000..2d32105 --- /dev/null +++ b/modules/Interfaces/include/Interfaces/Physic/APhysic.hpp @@ -0,0 +1,27 @@ +/// +/// @file APhysic.hpp +/// @brief This file contains the physic abstract class +/// @namespace cae +/// + +#pragma once + +#include "Interfaces/Physic/IPhysic.hpp" + +namespace cae +{ + + /// + /// @interface APhysic + /// @brief Abstract class for physic + /// @namespace cae + /// + class APhysic : public IPhysic + { + + public: + ~APhysic() override = default; + + }; // interface APhysic + +} // namespace cae diff --git a/modules/Interfaces/include/Interfaces/IPhysic.hpp b/modules/Interfaces/include/Interfaces/Physic/IPhysic.hpp similarity index 100% rename from modules/Interfaces/include/Interfaces/IPhysic.hpp rename to modules/Interfaces/include/Interfaces/Physic/IPhysic.hpp diff --git a/modules/Interfaces/include/Interfaces/Renderer/ARenderer.hpp b/modules/Interfaces/include/Interfaces/Renderer/ARenderer.hpp index 4183b16..cf2192b 100644 --- a/modules/Interfaces/include/Interfaces/Renderer/ARenderer.hpp +++ b/modules/Interfaces/include/Interfaces/Renderer/ARenderer.hpp @@ -22,9 +22,6 @@ namespace cae public: ~ARenderer() override = default; - protected: - - private: }; // interface ARenderer } // namespace cae diff --git a/modules/Interfaces/include/Interfaces/Renderer/IRenderer.hpp b/modules/Interfaces/include/Interfaces/Renderer/IRenderer.hpp index dcb739b..fce1988 100644 --- a/modules/Interfaces/include/Interfaces/Renderer/IRenderer.hpp +++ b/modules/Interfaces/include/Interfaces/Renderer/IRenderer.hpp @@ -6,8 +6,8 @@ #pragma once -#include "Interfaces/IWindow.hpp" -#include "Interfaces/Shader/IShaderFrontend.hpp" +#include "Interfaces/Shader/Frontend/IShaderFrontend.hpp" +#include "Interfaces/Window/IWindow.hpp" #include diff --git a/modules/Interfaces/include/Interfaces/Shader/Frontend/AShaderFrontend.hpp b/modules/Interfaces/include/Interfaces/Shader/Frontend/AShaderFrontend.hpp new file mode 100644 index 0000000..a39772c --- /dev/null +++ b/modules/Interfaces/include/Interfaces/Shader/Frontend/AShaderFrontend.hpp @@ -0,0 +1,27 @@ +/// +/// @file AShaderFrontend.hpp +/// @brief This file contains the ShaderFrontend abstract class +/// @namespace cae +/// + +#pragma once + +#include "Interfaces/Shader/Frontend/IShaderFrontend.hpp" + +namespace cae +{ + + /// + /// @interface IShaderFrontend + /// @brief Abstract class for shader frontend + /// @namespace cae + /// + class AShaderFrontend : public IShaderFrontend + { + + public: + ~AShaderFrontend() override = default; + + }; // interface AShaderFrontend + +} // namespace cae diff --git a/modules/Interfaces/include/Interfaces/Shader/IShaderFrontend.hpp b/modules/Interfaces/include/Interfaces/Shader/Frontend/IShaderFrontend.hpp similarity index 100% rename from modules/Interfaces/include/Interfaces/Shader/IShaderFrontend.hpp rename to modules/Interfaces/include/Interfaces/Shader/Frontend/IShaderFrontend.hpp diff --git a/modules/Interfaces/include/Interfaces/Shader/IR/AShaderIR.hpp b/modules/Interfaces/include/Interfaces/Shader/IR/AShaderIR.hpp new file mode 100644 index 0000000..6f57023 --- /dev/null +++ b/modules/Interfaces/include/Interfaces/Shader/IR/AShaderIR.hpp @@ -0,0 +1,27 @@ +/// +/// @file AShaderIR.hpp +/// @brief This file contains the ShaderIR abstract class +/// @namespace cae +/// + +#pragma once + +#include "Interfaces/Shader/IR/IShaderIR.hpp" + +namespace cae +{ + + /// + /// @interface AShaderIR + /// @brief Abstract class for shader IR + /// @namespace cae + /// + class AShaderIR : public IShaderIR + { + + public: + ~AShaderIR() override = default; + + }; // interface AShaderIR + +} // namespace cae diff --git a/modules/Interfaces/include/Interfaces/Shader/IShaderIR.hpp b/modules/Interfaces/include/Interfaces/Shader/IR/IShaderIR.hpp similarity index 96% rename from modules/Interfaces/include/Interfaces/Shader/IShaderIR.hpp rename to modules/Interfaces/include/Interfaces/Shader/IR/IShaderIR.hpp index 3fde505..1d4551e 100644 --- a/modules/Interfaces/include/Interfaces/Shader/IShaderIR.hpp +++ b/modules/Interfaces/include/Interfaces/Shader/IR/IShaderIR.hpp @@ -6,7 +6,7 @@ #pragma once -#include "Interfaces/Shader/IShaderFrontend.hpp" +#include "Interfaces/Shader/Frontend/IShaderFrontend.hpp" #include #include diff --git a/modules/Interfaces/include/Interfaces/UI/AUI.hpp b/modules/Interfaces/include/Interfaces/UI/AUI.hpp new file mode 100644 index 0000000..27f1394 --- /dev/null +++ b/modules/Interfaces/include/Interfaces/UI/AUI.hpp @@ -0,0 +1,27 @@ +/// +/// @file AUI.hpp +/// @brief This file contains the ui abstract class +/// @namespace cae +/// + +#pragma once + +#include "Interfaces/UI/IUI.hpp" + +namespace cae +{ + + /// + /// @interface AUI + /// @brief Abstract class for ui + /// @namespace cae + /// + class AUI : public IUI + { + + public: + ~AUI() override = default; + + }; // interface AUI + +} // namespace cae diff --git a/modules/Interfaces/include/Interfaces/IUI.hpp b/modules/Interfaces/include/Interfaces/UI/IUI.hpp similarity index 100% rename from modules/Interfaces/include/Interfaces/IUI.hpp rename to modules/Interfaces/include/Interfaces/UI/IUI.hpp diff --git a/modules/Interfaces/include/Interfaces/Window/AWindow.hpp b/modules/Interfaces/include/Interfaces/Window/AWindow.hpp new file mode 100644 index 0000000..b42faec --- /dev/null +++ b/modules/Interfaces/include/Interfaces/Window/AWindow.hpp @@ -0,0 +1,27 @@ +/// +/// @file AWindow.hpp +/// @brief This file contains the Window abstract class +/// @namespace cae +/// + +#pragma once + +#include "Interfaces/Window/IWindow.hpp" + +namespace cae +{ + + /// + /// @interface IWindow + /// @brief Abstract class for window + /// @namespace cae + /// + class AWindow : public IWindow + { + + public: + ~AWindow() override = default; + + }; // interface AWindow + +} // namespace cae diff --git a/modules/Interfaces/include/Interfaces/IWindow.hpp b/modules/Interfaces/include/Interfaces/Window/IWindow.hpp similarity index 96% rename from modules/Interfaces/include/Interfaces/IWindow.hpp rename to modules/Interfaces/include/Interfaces/Window/IWindow.hpp index 86d4780..0bbbb40 100644 --- a/modules/Interfaces/include/Interfaces/IWindow.hpp +++ b/modules/Interfaces/include/Interfaces/Window/IWindow.hpp @@ -6,8 +6,9 @@ #pragma once -#include "Input/Key/Keyboard.hpp" -#include "Input/Key/Mouse.hpp" +#include "Interfaces/Input/Key/Keyboard.hpp" +#include "Interfaces/Input/Key/Mouse.hpp" + #include "Utils/Interfaces/IPlugin.hpp" namespace cae @@ -162,9 +163,6 @@ namespace cae // virtual bool isFullScreen() const = 0; // virtual void setFullScreen(bool fullScreen) const = 0; - private: - // std::unique_ptr m_inputManager; - }; // interface IWindow } // namespace cae diff --git a/plugins/Renderer/OpenGL/include/OPGL/Context/IContext.hpp b/plugins/Renderer/OpenGL/include/OPGL/Context/IContext.hpp index 13c1588..3f3fe30 100644 --- a/plugins/Renderer/OpenGL/include/OPGL/Context/IContext.hpp +++ b/plugins/Renderer/OpenGL/include/OPGL/Context/IContext.hpp @@ -6,7 +6,7 @@ #pragma once -#include "Interfaces/IWindow.hpp" +#include "Interfaces/Window/IWindow.hpp" #include diff --git a/plugins/Shader/Frontend/GLSL/include/GLSL/GLSL.hpp b/plugins/Shader/Frontend/GLSL/include/GLSL/GLSL.hpp index e9a7980..b49e6b8 100644 --- a/plugins/Shader/Frontend/GLSL/include/GLSL/GLSL.hpp +++ b/plugins/Shader/Frontend/GLSL/include/GLSL/GLSL.hpp @@ -6,7 +6,7 @@ #pragma once -#include "Interfaces/Shader/IShaderFrontend.hpp" +#include "Interfaces/Shader/Frontend/AShaderFrontend.hpp" #include @@ -22,7 +22,7 @@ namespace cae /// @brief Class for the GLSL plugin /// @namespace cae /// - class GLSL final : public IShaderFrontend + class GLSL final : public AShaderFrontend { public: diff --git a/plugins/Shader/IR/SPIRV/include/SPIRV/SPIRV.hpp b/plugins/Shader/IR/SPIRV/include/SPIRV/SPIRV.hpp index 12148a1..21e09b0 100644 --- a/plugins/Shader/IR/SPIRV/include/SPIRV/SPIRV.hpp +++ b/plugins/Shader/IR/SPIRV/include/SPIRV/SPIRV.hpp @@ -6,7 +6,7 @@ #pragma once -#include "Interfaces/Shader/IShaderIR.hpp" +#include "Interfaces/Shader/IR/AShaderIR.hpp" namespace cae { @@ -16,7 +16,7 @@ namespace cae /// @brief Class for the SPIR-V IR plugin /// @namespace cae /// - class SPIRV final : public IShaderIR + class SPIRV final : public AShaderIR { public: SPIRV() = default; diff --git a/plugins/Window/GLFW/include/GLFW/GLFW.hpp b/plugins/Window/GLFW/include/GLFW/GLFW.hpp index 9e7bfaf..67a5bd9 100644 --- a/plugins/Window/GLFW/include/GLFW/GLFW.hpp +++ b/plugins/Window/GLFW/include/GLFW/GLFW.hpp @@ -6,7 +6,7 @@ #pragma once -#include "Interfaces/IWindow.hpp" +#include "Interfaces/Window/AWindow.hpp" #ifdef _WIN32 #define GLFW_EXPOSE_NATIVE_WIN32 @@ -27,7 +27,7 @@ namespace cae /// @brief Class for the GLFW plugin /// @namespace cae /// - class GLFW final : public IWindow + class GLFW final : public AWindow { public: diff --git a/plugins/Window/Win32/include/Win32/Win32.hpp b/plugins/Window/Win32/include/Win32/Win32.hpp index 84dba29..ec303dc 100644 --- a/plugins/Window/Win32/include/Win32/Win32.hpp +++ b/plugins/Window/Win32/include/Win32/Win32.hpp @@ -6,7 +6,7 @@ #pragma once -#include "Interfaces/IWindow.hpp" +#include "Interfaces/Window/AWindow.hpp" #include @@ -20,7 +20,7 @@ namespace cae /// @brief Class for the Win32 plugin /// @namespace cae /// - class Win32 final : public IWindow + class Win32 final : public AWindow { public: diff --git a/plugins/Window/X11/include/X11/X11.hpp b/plugins/Window/X11/include/X11/X11.hpp index 86eb5b7..d0fb596 100644 --- a/plugins/Window/X11/include/X11/X11.hpp +++ b/plugins/Window/X11/include/X11/X11.hpp @@ -6,7 +6,7 @@ #pragma once -#include "Interfaces/IWindow.hpp" +#include "Interfaces/Window/AWindow.hpp" #include @@ -20,7 +20,7 @@ namespace cae /// @brief Class for the X11 plugin /// @namespace cae /// - class X11 final : public IWindow + class X11 final : public AWindow { public: diff --git a/src/application.cpp b/src/application.cpp index d9d71ad..7e038e9 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -114,7 +114,7 @@ void cae::Application::setupEngine(const std::string &rendererName, const std::s utl::Logger::log("No shader plugin found with name: " + shaderFrontendName, utl::LogLevel::WARNING); } m_engine = std::make_unique( - m_appConfig.engineConfig, []() { return nullptr; }, []() { return nullptr; }, []() { return nullptr; }, + m_appConfig.engineConfig, []() { return nullptr; }, []() { return nullptr; }, [rendererPlugin]() { return rendererPlugin; }, [shaderIRPlugin]() { return shaderIRPlugin; }, shaderFactories, [windowPlugin]() { return windowPlugin; }); } From 4c4c1950e52709199bf7e5ef9eeab4d596ed3647 Mon Sep 17 00:00:00 2001 From: bobi Date: Mon, 19 Jan 2026 10:50:45 +0100 Subject: [PATCH 08/20] Fix: X11 keymapping use keycode --- plugins/Window/X11/src/x11.cpp | 41 +++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/plugins/Window/X11/src/x11.cpp b/plugins/Window/X11/src/x11.cpp index 635b4de..47c1bef 100644 --- a/plugins/Window/X11/src/x11.cpp +++ b/plugins/Window/X11/src/x11.cpp @@ -8,36 +8,39 @@ #include -static cae::KeyCode translateKey(const KeySym keysym) +static cae::KeyCode translateKeycode(const unsigned int keycode) { - switch (keysym) + switch (keycode) { - case XK_w: + case 25: return cae::KeyCode::W; - case XK_a: + case 38: return cae::KeyCode::A; - case XK_s: + case 39: return cae::KeyCode::S; - case XK_d: + case 40: return cae::KeyCode::D; - case XK_Up: + + case 111: return cae::KeyCode::Up; - case XK_Down: + case 116: return cae::KeyCode::Down; - case XK_Left: + case 113: return cae::KeyCode::Left; - case XK_Right: + case 114: return cae::KeyCode::Right; - case XK_Escape: - return cae::KeyCode::Escape; - case XK_space: + + case 65: return cae::KeyCode::Space; - case XK_Control_L: + case 37: return cae::KeyCode::LCtrl; - case XK_Shift_L: + case 50: return cae::KeyCode::LShift; - case XK_Alt_L: + case 64: return cae::KeyCode::LAlt; + + case 9: + return cae::KeyCode::Escape; default: return cae::KeyCode::Count; } @@ -158,7 +161,9 @@ void cae::X11::pollEvents() {} bool cae::X11::pollEvent(WindowEvent &outEvent) { if (m_eventQueue.empty() && XPending(m_display) == 0) + { return false; + } while (XPending(m_display) > 0) { @@ -170,13 +175,13 @@ bool cae::X11::pollEvent(WindowEvent &outEvent) { case KeyPress: e.type = WindowEventType::KeyDown; - e.key.key = translateKey(XLookupKeysym(&event.xkey, 0)); + e.key.key = translateKeycode(event.xkey.keycode); m_eventQueue.push(e); break; case KeyRelease: e.type = WindowEventType::KeyUp; - e.key.key = translateKey(XLookupKeysym(&event.xkey, 0)); + e.key.key = translateKeycode(event.xkey.keycode); m_eventQueue.push(e); break; From 0d0f076d9288bcc43ea1520c7429f4858d65a71f Mon Sep 17 00:00:00 2001 From: bobi Date: Mon, 19 Jan 2026 11:15:53 +0100 Subject: [PATCH 09/20] Fix: set icon for window interface bool -> void --- modules/Engine/src/engine.cpp | 8 ++++---- .../Interfaces/include/Interfaces/Window/IWindow.hpp | 2 +- plugins/Window/GLFW/include/GLFW/GLFW.hpp | 2 +- plugins/Window/GLFW/src/glfw.cpp | 5 ++--- plugins/Window/Win32/include/Win32/Win32.hpp | 2 +- plugins/Window/Win32/src/win32.cpp | 10 +++++----- plugins/Window/X11/include/X11/X11.hpp | 2 +- plugins/Window/X11/src/x11.cpp | 7 +++---- 8 files changed, 18 insertions(+), 20 deletions(-) diff --git a/modules/Engine/src/engine.cpp b/modules/Engine/src/engine.cpp index ab77bf6..3fae6ff 100644 --- a/modules/Engine/src/engine.cpp +++ b/modules/Engine/src/engine.cpp @@ -12,7 +12,7 @@ void printFps(std::array &fpsBuffer, int &fpsIndex, const float delta fpsBuffer[fpsIndex % 10] = 1.0F / deltaTime; fpsIndex++; - float avgFps = std::accumulate(fpsBuffer.begin(), fpsBuffer.end(), 0.0f) / 10.0f; + float avgFps = std::accumulate(fpsBuffer.begin(), fpsBuffer.end(), 0.0F) / 10.0F; utl::Logger::log(std::format("FPS: {}", avgFps), utl::LogLevel::INFO); } @@ -130,7 +130,7 @@ void cae::Engine::run() moveDir += right; } - if (glm::length(moveDir) > 0.0f) + if (glm::length(moveDir) > 0.0F) { moveDir = glm::normalize(moveDir); m_camera->move(moveDir, m_clock->getDeltaSeconds()); @@ -138,11 +138,11 @@ void cae::Engine::run() if (m_keyState[KeyCode::LCtrl]) { - m_camera->move(glm::vec3(0.0f, -1.0f, 0.0f), m_clock->getDeltaSeconds()); + m_camera->move(glm::vec3(0.0F, -1.0F, 0.0F), m_clock->getDeltaSeconds()); } if (m_keyState[KeyCode::Space]) { - m_camera->move(glm::vec3(0.0f, 1.0f, 0.0f), m_clock->getDeltaSeconds()); + m_camera->move(glm::vec3(0.0F, 1.0F, 0.0F), m_clock->getDeltaSeconds()); } if (m_logFps) diff --git a/modules/Interfaces/include/Interfaces/Window/IWindow.hpp b/modules/Interfaces/include/Interfaces/Window/IWindow.hpp index 0bbbb40..dbfdfcc 100644 --- a/modules/Interfaces/include/Interfaces/Window/IWindow.hpp +++ b/modules/Interfaces/include/Interfaces/Window/IWindow.hpp @@ -129,7 +129,7 @@ namespace cae /// @return True if the icon was set successfully /// @brief Set the window icon from the given image path /// - virtual bool setIcon(const std::string &path) const = 0; + virtual void setIcon(const std::string &path) const = 0; /// /// @return True if the window should close diff --git a/plugins/Window/GLFW/include/GLFW/GLFW.hpp b/plugins/Window/GLFW/include/GLFW/GLFW.hpp index 67a5bd9..eed663c 100644 --- a/plugins/Window/GLFW/include/GLFW/GLFW.hpp +++ b/plugins/Window/GLFW/include/GLFW/GLFW.hpp @@ -49,7 +49,7 @@ namespace cae [[nodiscard]] NativeWindowHandle getNativeHandle() const override; [[nodiscard]] WindowSize getWindowSize() const override; - [[nodiscard]] bool setIcon(const std::string &path) const override; + [[nodiscard]] void setIcon(const std::string &path) const override; [[nodiscard]] bool shouldClose() const override { return glfwWindowShouldClose(m_window) != 0; } void pollEvents() override { glfwPollEvents(); } diff --git a/plugins/Window/GLFW/src/glfw.cpp b/plugins/Window/GLFW/src/glfw.cpp index c9957b7..eed7c86 100644 --- a/plugins/Window/GLFW/src/glfw.cpp +++ b/plugins/Window/GLFW/src/glfw.cpp @@ -202,16 +202,15 @@ cae::NativeWindowHandle cae::GLFW::getNativeHandle() const return handle; } -bool cae::GLFW::setIcon(const std::string &path) const +void cae::GLFW::setIcon(const std::string &path) const { static const utl::Image image(path); if (image.pixels == nullptr) { - return false; + utl::Logger::log("Failed to create icon.", utl::LogLevel::WARNING); } static const GLFWimage appIcon{.width = image.width, .height = image.height, .pixels = image.pixels}; glfwSetWindowIcon(m_window, 1, &appIcon); - return true; } bool cae::GLFW::pollEvent(WindowEvent &event) diff --git a/plugins/Window/Win32/include/Win32/Win32.hpp b/plugins/Window/Win32/include/Win32/Win32.hpp index ec303dc..b51764c 100644 --- a/plugins/Window/Win32/include/Win32/Win32.hpp +++ b/plugins/Window/Win32/include/Win32/Win32.hpp @@ -42,7 +42,7 @@ namespace cae [[nodiscard]] NativeWindowHandle getNativeHandle() const override; [[nodiscard]] WindowSize getWindowSize() const override; - [[nodiscard]] bool setIcon(const std::string &path) const override; + void setIcon(const std::string &path) const override; [[nodiscard]] bool shouldClose() const override { return m_shouldClose; } void pollEvents() override; diff --git a/plugins/Window/Win32/src/win32.cpp b/plugins/Window/Win32/src/win32.cpp index bd1346c..0ebb49b 100644 --- a/plugins/Window/Win32/src/win32.cpp +++ b/plugins/Window/Win32/src/win32.cpp @@ -194,7 +194,7 @@ cae::WindowSize cae::Win32::getWindowSize() const .height = static_cast(rect.bottom - rect.top)}; } -bool cae::Win32::setIcon(const std::string &path) const +void cae::Win32::setIcon(const std::string &path) const { try { @@ -228,7 +228,8 @@ bool cae::Win32::setIcon(const std::string &path) const if (hBitmap == nullptr) { - return false; + utl::Logger::log("Failed to create window icon", utl::LogLevel::WARNING); + return; } std::memcpy(pBits, image.pixels, static_cast(image.width * image.height * 4)); @@ -243,18 +244,17 @@ bool cae::Win32::setIcon(const std::string &path) const if (hIcon == nullptr) { - return false; + utl::Logger::log("Failed to create window icon", utl::LogLevel::WARNING); + return; } SendMessageW(m_hwnd, WM_SETICON, ICON_BIG, reinterpret_cast(hIcon)); SendMessageW(m_hwnd, WM_SETICON, ICON_SMALL, reinterpret_cast(hIcon)); - return true; } catch (const std::exception &e) { utl::Logger::log("Failed to load icon: " + std::string(e.what()), utl::LogLevel::WARNING); - return false; } } diff --git a/plugins/Window/X11/include/X11/X11.hpp b/plugins/Window/X11/include/X11/X11.hpp index d0fb596..4ca79c9 100644 --- a/plugins/Window/X11/include/X11/X11.hpp +++ b/plugins/Window/X11/include/X11/X11.hpp @@ -45,7 +45,7 @@ namespace cae } [[nodiscard]] WindowSize getWindowSize() const override; - [[nodiscard]] bool setIcon(const std::string &path) const override; + void setIcon(const std::string &path) const override; [[nodiscard]] bool shouldClose() const override; void pollEvents() override; diff --git a/plugins/Window/X11/src/x11.cpp b/plugins/Window/X11/src/x11.cpp index 47c1bef..f3f1fa2 100644 --- a/plugins/Window/X11/src/x11.cpp +++ b/plugins/Window/X11/src/x11.cpp @@ -106,11 +106,12 @@ cae::WindowSize cae::X11::getWindowSize() const return {.width = static_cast(attrs.width), .height = static_cast(attrs.height)}; } -bool cae::X11::setIcon(const std::string &path) const +void cae::X11::setIcon(const std::string &path) const { if ((m_display == nullptr) || m_window == 0) { - return false; + utl::Logger::log("Failed to create window icon", utl::LogLevel::WARNING); + return; } try @@ -145,12 +146,10 @@ bool cae::X11::setIcon(const std::string &path) const reinterpret_cast(iconData.data()), static_cast(iconData.size())); XFlush(m_display); - return true; } catch (const std::exception &e) { utl::Logger::log(std::string("Failed to set X11 window icon: ") + e.what(), utl::LogLevel::WARNING); - return false; } } From 74411e81e1153cbddfea554a1dbe8990b3ab1624 Mon Sep 17 00:00:00 2001 From: bobi Date: Mon, 19 Jan 2026 12:31:16 +0100 Subject: [PATCH 10/20] Fix: resolve path for config --- modules/Utils/include/Utils/Path.hpp | 10 ++++++++++ src/conf.cpp | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/modules/Utils/include/Utils/Path.hpp b/modules/Utils/include/Utils/Path.hpp index 25fd4dc..7b3be26 100644 --- a/modules/Utils/include/Utils/Path.hpp +++ b/modules/Utils/include/Utils/Path.hpp @@ -123,6 +123,16 @@ namespace utl return normalize(executableDir() / relativePath); } + /// + /// @param relativePath Relative path to be resolved + /// @return Resolved path relative to the user cwd + /// @brief + /// + static fs::path resolveRelativeToCwd(const fs::path& relativePath) { + return normalize(fs::current_path() / relativePath); + } + + }; // class Path } // namespace utl diff --git a/src/conf.cpp b/src/conf.cpp index 435eb51..4013e7a 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -11,7 +11,7 @@ using json = nlohmann::json; cae::EngineConfig cae::Application::parseEngineConf(const std::string &path) { - auto confPath = utl::Path::resolveRelativeToExe(path); + auto confPath = utl::Path::resolveRelativeToCwd(path); if (!utl::Path::existsFile(confPath)) { utl::Logger::log("Config file does not exist: " + confPath.string(), utl::LogLevel::WARNING); From 55f786f4bc4b1bcf22b8d625002aebc578a4344f Mon Sep 17 00:00:00 2001 From: bobi Date: Mon, 19 Jan 2026 12:32:43 +0100 Subject: [PATCH 11/20] Fix: missing get shader in engine, reset ptr and improve conf --- assets/config/default.json | 2 +- modules/Engine/include/Engine/Engine.hpp | 1 + modules/Engine/src/engine.cpp | 23 +++++++++++-------- .../include/Interfaces/Input/Key/Mouse.hpp | 3 ++- .../include/Interfaces/Window/IWindow.hpp | 2 +- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/assets/config/default.json b/assets/config/default.json index b1f247c..76c95b7 100644 --- a/assets/config/default.json +++ b/assets/config/default.json @@ -4,7 +4,7 @@ "muted": false }, "camera": { - "position": [0.0, 1.0, 5.0], + "position": [0.0, 0.0, 1.0], "rotation": [0.0, 0.0, 0.0], "direction": [0.0, 0.0, -1.0], "movementSpeed": 2.5, diff --git a/modules/Engine/include/Engine/Engine.hpp b/modules/Engine/include/Engine/Engine.hpp index 1221b00..14f2206 100644 --- a/modules/Engine/include/Engine/Engine.hpp +++ b/modules/Engine/include/Engine/Engine.hpp @@ -85,6 +85,7 @@ namespace cae [[nodiscard]] const std::shared_ptr &getWindow() const { return m_windowPlugin; } [[nodiscard]] const std::unique_ptr &getClock() { return m_clock; } + [[nodiscard]] const std::unique_ptr &getShaderManager() const { return m_shaderManager; } [[nodiscard]] const std::unique_ptr &getCamera() const { return m_camera; } /// diff --git a/modules/Engine/src/engine.cpp b/modules/Engine/src/engine.cpp index 3fae6ff..b08bf58 100644 --- a/modules/Engine/src/engine.cpp +++ b/modules/Engine/src/engine.cpp @@ -1,12 +1,11 @@ #include "Engine/Engine.hpp" #include "Utils/Logger.hpp" +#include "Utils/Path.hpp" #include #include -#include "Utils/Path.hpp" - void printFps(std::array &fpsBuffer, int &fpsIndex, const float deltaTime) { fpsBuffer[fpsIndex % 10] = 1.0F / deltaTime; @@ -89,29 +88,29 @@ void cae::Engine::run() if (m_keyState[KeyCode::Up]) { - lookDir.y += 1.0f; + lookDir.y += 1.0F; } if (m_keyState[KeyCode::Down]) { - lookDir.y -= 1.0f; + lookDir.y -= 1.0F; } if (m_keyState[KeyCode::Left]) { - lookDir.x -= 1.0f; + lookDir.x -= 1.0F; } if (m_keyState[KeyCode::Right]) { - lookDir.x += 1.0f; + lookDir.x += 1.0F; } - if (glm::length(lookDir) > 0.0f) + if (glm::length(lookDir) > 0.0F) { lookDir *= m_camera->getLookSpeed() * m_clock->getDeltaSeconds(); - m_camera->rotate(lookDir.x, lookDir.y, 1.0f); + m_camera->rotate(lookDir.x, lookDir.y, 1.0F); } - glm::vec3 forward = glm::normalize(glm::vec3(m_camera->getDirection().x, 0.0f, m_camera->getDirection().z)); - glm::vec3 right = glm::normalize(glm::cross(forward, glm::vec3(0.0f, 1.0f, 0.0f))); + glm::vec3 forward = glm::normalize(glm::vec3(m_camera->getDirection().x, 0.0F, m_camera->getDirection().z)); + glm::vec3 right = glm::normalize(glm::cross(forward, glm::vec3(0.0F, 1.0F, 0.0F))); if (m_keyState[KeyCode::W]) { @@ -162,6 +161,10 @@ void cae::Engine::stop() m_networkPlugin = nullptr; m_rendererPlugin = nullptr; m_windowPlugin = nullptr; + + m_clock = nullptr; + m_shaderManager = nullptr; + m_camera = nullptr; } void cae::Engine::initWindow(const std::string &windowName, const WindowSize &windowSize, diff --git a/modules/Interfaces/include/Interfaces/Input/Key/Mouse.hpp b/modules/Interfaces/include/Interfaces/Input/Key/Mouse.hpp index ee774ef..1e98e7e 100644 --- a/modules/Interfaces/include/Interfaces/Input/Key/Mouse.hpp +++ b/modules/Interfaces/include/Interfaces/Input/Key/Mouse.hpp @@ -18,6 +18,7 @@ namespace cae XButton1, XButton2, WheelUp, - WheelDown + WheelDown, + Count }; } // namespace cae diff --git a/modules/Interfaces/include/Interfaces/Window/IWindow.hpp b/modules/Interfaces/include/Interfaces/Window/IWindow.hpp index dbfdfcc..e04a192 100644 --- a/modules/Interfaces/include/Interfaces/Window/IWindow.hpp +++ b/modules/Interfaces/include/Interfaces/Window/IWindow.hpp @@ -41,7 +41,7 @@ namespace cae /// @brief Enum for window event types /// @namespace cae /// - enum class WindowEventType + enum class WindowEventType : uint8_t { KeyDown, KeyUp, From e62ae26927d4312e7f10d1deb757a5f81749a3cf Mon Sep 17 00:00:00 2001 From: bobi Date: Mon, 19 Jan 2026 13:21:00 +0100 Subject: [PATCH 12/20] Fix: keybinding in `application` instead of `engine` --- include/CAE/Application.hpp | 6 +- modules/Engine/include/Engine/Engine.hpp | 7 +- modules/Engine/src/engine.cpp | 98 +++--------------------- src/application.cpp | 90 +++++++++++++++++++++- 4 files changed, 107 insertions(+), 94 deletions(-) diff --git a/include/CAE/Application.hpp b/include/CAE/Application.hpp index ed6ffe4..e3297da 100644 --- a/include/CAE/Application.hpp +++ b/include/CAE/Application.hpp @@ -50,7 +50,7 @@ namespace cae /// /// @brief Start the application /// - void start() const; + void start(); /// /// @brief Stop the application @@ -75,10 +75,14 @@ namespace cae /// static EngineConfig parseEngineConf(const std::string &path); + void mainLoop(); + std::unique_ptr m_pluginLoader = nullptr; std::unique_ptr m_engine = nullptr; AppConfig m_appConfig; + std::unordered_map m_keyState; + }; // class Application diff --git a/modules/Engine/include/Engine/Engine.hpp b/modules/Engine/include/Engine/Engine.hpp index 14f2206..8bbe913 100644 --- a/modules/Engine/include/Engine/Engine.hpp +++ b/modules/Engine/include/Engine/Engine.hpp @@ -96,10 +96,8 @@ namespace cae void initializeRenderResources(const std::vector &shaderSources, const std::vector &vertices) const; - /// - /// @brief Run the engine main loop - /// - void run(); + void update(std::array &fpsBuffer, int &fpsIndex); + void render(); /// /// @brief Stop the engine @@ -116,7 +114,6 @@ namespace cae std::unique_ptr m_shaderManager = nullptr; std::unique_ptr m_camera = nullptr; - std::unordered_map m_keyState; bool m_logFps = false; /// diff --git a/modules/Engine/src/engine.cpp b/modules/Engine/src/engine.cpp index b08bf58..3d03de9 100644 --- a/modules/Engine/src/engine.cpp +++ b/modules/Engine/src/engine.cpp @@ -59,97 +59,23 @@ void cae::Engine::initializeRenderResources(const std::vector m_rendererPlugin->createMesh(vertices); } -void cae::Engine::run() +void cae::Engine::render() { - std::array fpsBuffer{}; - int fpsIndex = 0; - WindowEvent e{}; constexpr auto model = glm::mat4(1.0F); - while (!m_windowPlugin->shouldClose()) - { - const glm::mat4 mvp = m_camera->getViewProjection(static_cast(m_windowPlugin->getWindowSize().width) / - m_windowPlugin->getWindowSize().height) * - model; - m_rendererPlugin->draw(m_windowPlugin->getWindowSize(), "basic", mvp); - m_windowPlugin->pollEvents(); - while (m_windowPlugin->pollEvent(e)) - { - if (e.type == WindowEventType::KeyDown) - { - m_keyState[e.key.key] = true; - } - else if (e.type == WindowEventType::KeyUp) - { - m_keyState[e.key.key] = false; - } - } - glm::vec3 moveDir(0.0F); - glm::vec2 lookDir(0.0F); - - if (m_keyState[KeyCode::Up]) - { - lookDir.y += 1.0F; - } - if (m_keyState[KeyCode::Down]) - { - lookDir.y -= 1.0F; - } - if (m_keyState[KeyCode::Left]) - { - lookDir.x -= 1.0F; - } - if (m_keyState[KeyCode::Right]) - { - lookDir.x += 1.0F; - } - - if (glm::length(lookDir) > 0.0F) - { - lookDir *= m_camera->getLookSpeed() * m_clock->getDeltaSeconds(); - m_camera->rotate(lookDir.x, lookDir.y, 1.0F); - } - - glm::vec3 forward = glm::normalize(glm::vec3(m_camera->getDirection().x, 0.0F, m_camera->getDirection().z)); - glm::vec3 right = glm::normalize(glm::cross(forward, glm::vec3(0.0F, 1.0F, 0.0F))); - - if (m_keyState[KeyCode::W]) - { - moveDir += forward; - } - if (m_keyState[KeyCode::S]) - { - moveDir -= forward; - } - if (m_keyState[KeyCode::A]) - { - moveDir -= right; - } - if (m_keyState[KeyCode::D]) - { - moveDir += right; - } - if (glm::length(moveDir) > 0.0F) - { - moveDir = glm::normalize(moveDir); - m_camera->move(moveDir, m_clock->getDeltaSeconds()); - } - - if (m_keyState[KeyCode::LCtrl]) - { - m_camera->move(glm::vec3(0.0F, -1.0F, 0.0F), m_clock->getDeltaSeconds()); - } - if (m_keyState[KeyCode::Space]) - { - m_camera->move(glm::vec3(0.0F, 1.0F, 0.0F), m_clock->getDeltaSeconds()); - } + const glm::mat4 mvp = m_camera->getViewProjection(static_cast(m_windowPlugin->getWindowSize().width) / + m_windowPlugin->getWindowSize().height) * + model; + m_rendererPlugin->draw(m_windowPlugin->getWindowSize(), "basic", mvp); +} - if (m_logFps) - { - printFps(fpsBuffer, fpsIndex, m_clock->getDeltaSeconds()); - } - m_clock->restart(); +void cae::Engine::update(std::array &fpsBuffer, int &fpsIndex) +{ + if (m_logFps) + { + printFps(fpsBuffer, fpsIndex, m_clock->getDeltaSeconds()); } + m_clock->restart(); } void cae::Engine::stop() diff --git a/src/application.cpp b/src/application.cpp index 7e038e9..b164c39 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -139,7 +139,7 @@ static const std::vector cubeVertices = { -0.5f, 0.5f, -0.5f, 1, 0, 1, 0.5f, 0.5f, -0.5f, 0, 1, 1, 0.5f, 0.5f, 0.5f, 1, 1, 1, 0.5f, 0.5f, 0.5f, 1, 1, 1, -0.5f, 0.5f, 0.5f, 0, 0, 0, -0.5f, 0.5f, -0.5f, 1, 0, 1}; -void cae::Application::start() const +void cae::Application::start() { static const std::vector shaderSources = { {.id = "basic_vertex", @@ -153,7 +153,7 @@ void cae::Application::start() const .stage = ShaderStage::FRAGMENT}, }; m_engine->initializeRenderResources(shaderSources, cubeVertices); - m_engine->run(); + mainLoop(); } void cae::Application::stop() @@ -163,3 +163,89 @@ void cae::Application::stop() m_pluginLoader = nullptr; m_engine = nullptr; } + +void cae::Application::mainLoop() +{ + std::array fpsBuffer{}; + int fpsIndex = 0; + WindowEvent e{}; + + while (!m_engine->getWindow()->shouldClose()) + { + m_engine->render(); + glm::vec3 moveDir(0.0F); + glm::vec2 lookDir(0.0F); + m_engine->getWindow()->pollEvents(); + while (m_engine->getWindow()->pollEvent(e)) + { + if (e.type == WindowEventType::KeyDown) + { + m_keyState[e.key.key] = true; + } + else if (e.type == WindowEventType::KeyUp) + { + m_keyState[e.key.key] = false; + } + } + + if (m_keyState[KeyCode::Up]) + { + lookDir.y += 1.0F; + } + if (m_keyState[KeyCode::Down]) + { + lookDir.y -= 1.0F; + } + if (m_keyState[KeyCode::Left]) + { + lookDir.x -= 1.0F; + } + if (m_keyState[KeyCode::Right]) + { + lookDir.x += 1.0F; + } + + if (glm::length(lookDir) > 0.0F) + { + lookDir *= m_engine->getCamera()->getLookSpeed() * m_engine->getClock()->getDeltaSeconds(); + m_engine->getCamera()->rotate(lookDir.x, lookDir.y, 1.0F); + } + + glm::vec3 forward = glm::normalize(glm::vec3(m_engine->getCamera()->getDirection().x, 0.0F, m_engine->getCamera()->getDirection().z)); + glm::vec3 right = glm::normalize(glm::cross(forward, glm::vec3(0.0F, 1.0F, 0.0F))); + + if (m_keyState[KeyCode::W]) + { + moveDir += forward; + } + if (m_keyState[KeyCode::S]) + { + moveDir -= forward; + } + if (m_keyState[KeyCode::A]) + { + moveDir -= right; + } + if (m_keyState[KeyCode::D]) + { + moveDir += right; + } + + if (glm::length(moveDir) > 0.0F) + { + moveDir = glm::normalize(moveDir); + m_engine->getCamera()->move(moveDir, m_engine->getClock()->getDeltaSeconds()); + } + + if (m_keyState[KeyCode::LCtrl]) + { + m_engine->getCamera()->move(glm::vec3(0.0F, -1.0F, 0.0F), m_engine->getClock()->getDeltaSeconds()); + } + if (m_keyState[KeyCode::Space]) + { + m_engine->getCamera()->move(glm::vec3(0.0F, 1.0F, 0.0F), m_engine->getClock()->getDeltaSeconds()); + } + + m_engine->update(fpsBuffer, fpsIndex); + } +} From df580daa9d7800d78d7b04b234d36941781cdcf2 Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Mon, 19 Jan 2026 15:08:23 +0100 Subject: [PATCH 13/20] Fix: glfw and opengl context --- plugins/Renderer/OpenGL/src/context/NSGLContextMac.mm | 2 +- plugins/Window/GLFW/src/glfw.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Renderer/OpenGL/src/context/NSGLContextMac.mm b/plugins/Renderer/OpenGL/src/context/NSGLContextMac.mm index 5dd3b15..46534f1 100644 --- a/plugins/Renderer/OpenGL/src/context/NSGLContextMac.mm +++ b/plugins/Renderer/OpenGL/src/context/NSGLContextMac.mm @@ -12,7 +12,7 @@ } void cae::NSGLContextMac::initialize(const NativeWindowHandle &window) { - NSView* nsview = (__bridge NSView*)window.window; + NSView* nsview = (__bridge NSView*)window.display; NSOpenGLPixelFormatAttribute attrs[] = { NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, diff --git a/plugins/Window/GLFW/src/glfw.cpp b/plugins/Window/GLFW/src/glfw.cpp index eed7c86..095c05d 100644 --- a/plugins/Window/GLFW/src/glfw.cpp +++ b/plugins/Window/GLFW/src/glfw.cpp @@ -197,7 +197,7 @@ cae::NativeWindowHandle cae::GLFW::getNativeHandle() const handle.display = glfwGetX11Display(); #elifdef __APPLE__ handle.window = glfwGetCocoaWindow(m_window); - handle.display = nullptr; + handle.display = glfwGetCocoaView(m_window); #endif return handle; } From 4335503b74bd4eb43c383c03829a7a78676f645f Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Mon, 19 Jan 2026 15:08:38 +0100 Subject: [PATCH 14/20] Fix: window windows missing cases --- plugins/Window/Win32/src/win32.cpp | 13 ++++++++----- src/application.cpp | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/plugins/Window/Win32/src/win32.cpp b/plugins/Window/Win32/src/win32.cpp index 0ebb49b..6b2edca 100644 --- a/plugins/Window/Win32/src/win32.cpp +++ b/plugins/Window/Win32/src/win32.cpp @@ -60,9 +60,12 @@ cae::KeyCode cae::Win32::mapWinKey(const WPARAM key) {VK_RETURN, KeyCode::Enter}, {VK_BACK, KeyCode::Backspace}, {VK_TAB, KeyCode::Tab}, - {VK_SHIFT, KeyCode::LShift}, - {VK_CONTROL, KeyCode::LCtrl}, - {VK_MENU, KeyCode::LAlt} + {VK_LSHIFT, KeyCode::LShift}, + {VK_RSHIFT, KeyCode::RShift}, + {VK_LCONTROL, KeyCode::LCtrl}, + {VK_RCONTROL, KeyCode::RCtrl}, + {VK_LMENU, KeyCode::LAlt}, + {VK_RMENU, KeyCode::RAlt} // ... }; @@ -93,7 +96,7 @@ LRESULT CALLBACK cae::Win32::WindowProc(const HWND hwnd, const UINT msg, const W self->m_frameBufferResized = true; self->m_frameBufferSize = {.width = LOWORD(lParam), .height = HIWORD(lParam)}; e.type = WindowEventType::Resize; - e.resize = {LOWORD(lParam), HIWORD(lParam)}; + e.resize = {.w=LOWORD(lParam), .h=HIWORD(lParam)}; self->m_eventQueue.push(e); return 0; @@ -117,7 +120,7 @@ LRESULT CALLBACK cae::Win32::WindowProc(const HWND hwnd, const UINT msg, const W self->m_eventQueue.push(e); return 0; - // souris, scroll, etc + // mouse, scroll, ... } return DefWindowProcW(hwnd, msg, wParam, lParam); diff --git a/src/application.cpp b/src/application.cpp index b164c39..bd2019a 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -53,7 +53,7 @@ cae::Application::Application(const ArgsConfig &argsConfig, const EnvConfig &env { m_appConfig.engineConfig = parseEngineConf(argsConfig.config_path); } - setupEngine(PLUGINS::NAME::RENDERER::OPENGL, PLUGINS::NAME::WINDOW::X11, PLUGINS::NAME::SHADER::FRONTEND::GLSL, + setupEngine(PLUGINS::NAME::RENDERER::OPENGL, PLUGINS::NAME::WINDOW::GLFW, PLUGINS::NAME::SHADER::FRONTEND::GLSL, PLUGINS::NAME::SHADER::IR::SPIRV); } catch (const std::exception &e) From 9dfd06330b01552d1bb31884c90ed6bb31027658 Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Mon, 19 Jan 2026 16:59:58 +0100 Subject: [PATCH 15/20] Feat: minimal cocoa window impl --- include/CAE/Common.hpp | 1 + .../OpenGL/src/context/NSGLContextMac.mm | 2 + plugins/Window/CMakeLists.txt | 1 + plugins/Window/Cocoa/CMakeLists.txt | 27 ++++ plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp | 52 +++++++ plugins/Window/Cocoa/src/cocoa.mm | 136 ++++++++++++++++++ plugins/Window/Cocoa/src/entrypoint.cpp | 8 ++ plugins/Window/GLFW/include/GLFW/GLFW.hpp | 2 +- plugins/Window/GLFW/src/glfw.cpp | 10 +- src/application.cpp | 2 +- 10 files changed, 237 insertions(+), 4 deletions(-) create mode 100644 plugins/Window/Cocoa/src/cocoa.mm diff --git a/include/CAE/Common.hpp b/include/CAE/Common.hpp index f1edb22..e5547b4 100644 --- a/include/CAE/Common.hpp +++ b/include/CAE/Common.hpp @@ -47,6 +47,7 @@ namespace cae namespace WINDOW { + inline constexpr auto COCOA = "Cocoa"; inline constexpr auto GLFW = "GLFW"; inline constexpr auto WIN32_ = "Win32"; inline constexpr auto X11 = "X11"; diff --git a/plugins/Renderer/OpenGL/src/context/NSGLContextMac.mm b/plugins/Renderer/OpenGL/src/context/NSGLContextMac.mm index 46534f1..7545def 100644 --- a/plugins/Renderer/OpenGL/src/context/NSGLContextMac.mm +++ b/plugins/Renderer/OpenGL/src/context/NSGLContextMac.mm @@ -2,6 +2,8 @@ #include "OPGL/Context/NSGLContextMac.hpp" +#include "Utils/Logger.hpp" + #import cae::NSGLContextMac::~NSGLContextMac() { diff --git a/plugins/Window/CMakeLists.txt b/plugins/Window/CMakeLists.txt index 033b108..0d7a915 100644 --- a/plugins/Window/CMakeLists.txt +++ b/plugins/Window/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(Cocoa) add_subdirectory(GLFW) add_subdirectory(Win32) add_subdirectory(X11) \ No newline at end of file diff --git a/plugins/Window/Cocoa/CMakeLists.txt b/plugins/Window/Cocoa/CMakeLists.txt index e69de29..5e20d2a 100644 --- a/plugins/Window/Cocoa/CMakeLists.txt +++ b/plugins/Window/Cocoa/CMakeLists.txt @@ -0,0 +1,27 @@ +project(cae-cocoa + DESCRIPTION "CAE Cocoa Window Plugin" + LANGUAGES C CXX OBJCXX +) + +if (NOT APPLE) + message(WARNING "${PROJECT_NAME} can only be build on MacOS") + return() +endif () + +file(GLOB_RECURSE SOURCES "${PROJECT_SOURCE_DIR}/src/*.mm" "${PROJECT_SOURCE_DIR}/src/*.cpp") + +add_library(${PROJECT_NAME} SHARED ${SOURCES}) + +target_include_directories(${PROJECT_NAME} PRIVATE + "${PROJECT_SOURCE_DIR}/include" +) +target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) +target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) +target_link_libraries(${PROJECT_NAME} PRIVATE + cae-modules + "-framework Cocoa" +) +set_target_properties(${PROJECT_NAME} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${PLUGIN_DIR}" + RUNTIME_OUTPUT_DIRECTORY "${PLUGIN_DIR}" +) diff --git a/plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp b/plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp index e69de29..af021d0 100644 --- a/plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp +++ b/plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include "Interfaces/Window/AWindow.hpp" + +#include + +#ifdef __APPLE__ + +namespace cae +{ + class Cocoa final : public AWindow + { + public: + Cocoa() = default; + ~Cocoa() override; + + Cocoa(const Cocoa&) = delete; + Cocoa& operator=(const Cocoa&) = delete; + + [[nodiscard]] std::string getName() const override { return "Cocoa"; } + [[nodiscard]] utl::PluginType getType() const override { return utl::PluginType::WINDOW; } + [[nodiscard]] utl::PluginPlatform getPlatform() const override { return utl::PluginPlatform::MACOSX; } + + bool create(const std::string& name, WindowSize size) override; + void close() override; + + [[nodiscard]] NativeWindowHandle getNativeHandle() const override; + [[nodiscard]] WindowSize getWindowSize() const override; + + void setIcon(const std::string &path) const override {} + + [[nodiscard]] bool shouldClose() const override; + void pollEvents() override; + bool pollEvent(WindowEvent& event) override; + + [[nodiscard]] bool wasResized() const override { return m_resized; } + void resetResizedFlag() override { m_resized = false; } + + private: + void* m_window = nullptr; // NSWindow* + void* m_view = nullptr; // NSView* + void* m_app = nullptr; // NSApplication* + + bool m_shouldClose = false; + bool m_resized = false; + + std::queue m_eventQueue; + WindowSize m_size{}; + }; +} + +#endif diff --git a/plugins/Window/Cocoa/src/cocoa.mm b/plugins/Window/Cocoa/src/cocoa.mm new file mode 100644 index 0000000..add1157 --- /dev/null +++ b/plugins/Window/Cocoa/src/cocoa.mm @@ -0,0 +1,136 @@ +#import + +#include "Cocoa/Cocoa.hpp" + +#include + +using namespace cae; + +Cocoa::~Cocoa() +{ + close(); +} + +bool Cocoa::create(const std::string& title, WindowSize size) +{ + @autoreleasepool + { + m_app = [NSApplication sharedApplication]; + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + + NSRect rect = NSMakeRect(0, 0, size.width, size.height); + NSUInteger style = + NSWindowStyleMaskTitled | + NSWindowStyleMaskClosable | + NSWindowStyleMaskResizable; + + NSWindow* window = [[NSWindow alloc] + initWithContentRect:rect + styleMask:style + backing:NSBackingStoreBuffered + defer:NO]; + + [window setTitle:[NSString stringWithUTF8String:title.c_str()]]; + [window makeKeyAndOrderFront:nil]; + [NSApp activateIgnoringOtherApps:YES]; + + m_window = window; + m_view = [window contentView]; + m_size = size; + } + + return true; +} + +void Cocoa::close() +{ + if (m_window) + { + NSWindow* window = (NSWindow*)m_window; + [window close]; + m_window = nullptr; + m_view = nullptr; + } +} + +void Cocoa::pollEvents() +{ + @autoreleasepool + { + NSEvent* event; + while ((event = [NSApp + nextEventMatchingMask:NSEventMaskAny + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES])) + { + switch ([event type]) + { + case NSEventTypeKeyDown: + case NSEventTypeKeyUp: + { + WindowEvent e{}; + e.type = ([event type] == NSEventTypeKeyDown) + ? WindowEventType::KeyDown + : WindowEventType::KeyUp; + // mapping clavier à faire ici + m_eventQueue.push(e); + break; + } + + case NSEventTypeLeftMouseDown: + case NSEventTypeLeftMouseUp: + { + WindowEvent e{}; + e.type = ([event type] == NSEventTypeLeftMouseDown) + ? WindowEventType::MouseButtonDown + : WindowEventType::MouseButtonUp; + e.mouseButton.button = MouseButton::Left; + m_eventQueue.push(e); + break; + } + + default: + break; + } + + [NSApp sendEvent:event]; + } + } +} + +bool Cocoa::pollEvent(WindowEvent& event) +{ + if (m_eventQueue.empty()) + return false; + + event = m_eventQueue.front(); + m_eventQueue.pop(); + return true; +} + +bool Cocoa::shouldClose() const +{ + return m_shouldClose; +} + +WindowSize Cocoa::getWindowSize() const +{ + if (!m_window) + return {}; + + NSWindow* window = (NSWindow*)m_window; + NSRect rect = [window frame]; + return { + .width = (uint16_t)rect.size.width, + .height = (uint16_t)rect.size.height + }; +} + +NativeWindowHandle Cocoa::getNativeHandle() const +{ + NativeWindowHandle handle{}; + handle.window = m_window; // NSWindow* + handle.display = m_view; // NSView* + return handle; +} diff --git a/plugins/Window/Cocoa/src/entrypoint.cpp b/plugins/Window/Cocoa/src/entrypoint.cpp index e69de29..fdd9e7c 100644 --- a/plugins/Window/Cocoa/src/entrypoint.cpp +++ b/plugins/Window/Cocoa/src/entrypoint.cpp @@ -0,0 +1,8 @@ +#include "Cocoa/Cocoa.hpp" + +#include + +extern "C" +{ + PLUGIN_EXPORT cae::IWindow *entryPoint() { return std::make_unique().release(); } +} diff --git a/plugins/Window/GLFW/include/GLFW/GLFW.hpp b/plugins/Window/GLFW/include/GLFW/GLFW.hpp index eed663c..6160815 100644 --- a/plugins/Window/GLFW/include/GLFW/GLFW.hpp +++ b/plugins/Window/GLFW/include/GLFW/GLFW.hpp @@ -49,7 +49,7 @@ namespace cae [[nodiscard]] NativeWindowHandle getNativeHandle() const override; [[nodiscard]] WindowSize getWindowSize() const override; - [[nodiscard]] void setIcon(const std::string &path) const override; + void setIcon(const std::string &path) const override; [[nodiscard]] bool shouldClose() const override { return glfwWindowShouldClose(m_window) != 0; } void pollEvents() override { glfwPollEvents(); } diff --git a/plugins/Window/GLFW/src/glfw.cpp b/plugins/Window/GLFW/src/glfw.cpp index 095c05d..fa1d925 100644 --- a/plugins/Window/GLFW/src/glfw.cpp +++ b/plugins/Window/GLFW/src/glfw.cpp @@ -148,8 +148,11 @@ bool cae::GLFW::create(const std::string &name, const WindowSize size) utl::Logger::log("Failed to init glfw", utl::LogLevel::WARNING); return false; } - +#ifdef __APPLE__ +#else glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); +#endif + m_window = glfwCreateWindow(size.width, size.height, name.c_str(), nullptr, nullptr); if (m_window == nullptr) { @@ -165,6 +168,9 @@ bool cae::GLFW::create(const std::string &name, const WindowSize size) glfwSetMouseButtonCallback(m_window, mouseButtonCallback); glfwSetCursorPosCallback(m_window, cursorPosCallback); glfwSetScrollCallback(m_window, scrollCallback); +#ifdef __APPLE__ + glfwMakeContextCurrent((GLFWwindow*)m_window); +#endif return true; } @@ -197,7 +203,7 @@ cae::NativeWindowHandle cae::GLFW::getNativeHandle() const handle.display = glfwGetX11Display(); #elifdef __APPLE__ handle.window = glfwGetCocoaWindow(m_window); - handle.display = glfwGetCocoaView(m_window); + handle.display = nullptr; #endif return handle; } diff --git a/src/application.cpp b/src/application.cpp index bd2019a..7d19559 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -53,7 +53,7 @@ cae::Application::Application(const ArgsConfig &argsConfig, const EnvConfig &env { m_appConfig.engineConfig = parseEngineConf(argsConfig.config_path); } - setupEngine(PLUGINS::NAME::RENDERER::OPENGL, PLUGINS::NAME::WINDOW::GLFW, PLUGINS::NAME::SHADER::FRONTEND::GLSL, + setupEngine(PLUGINS::NAME::RENDERER::OPENGL, PLUGINS::NAME::WINDOW::COCOA, PLUGINS::NAME::SHADER::FRONTEND::GLSL, PLUGINS::NAME::SHADER::IR::SPIRV); } catch (const std::exception &e) From 319f90eaf902f546d0ba7400e8900cf8618648ff Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Tue, 20 Jan 2026 10:43:35 +0100 Subject: [PATCH 16/20] Refactor: rename lib and opengl context calss impl --- modules/Engine/include/Engine/Camera.hpp | 2 +- modules/Engine/include/Engine/Engine.hpp | 9 +++++++++ plugins/Renderer/OpenGL/CMakeLists.txt | 2 +- .../{EGLContextLinux.hpp => EGLContext.hpp} | 14 +++++++------- .../{NSGLContextMac.hpp => NSGLContext.hpp} | 14 +++++++------- .../{WGLContextWindows.hpp => WGLContext.hpp} | 14 +++++++------- .../{EGLContextLinux.cpp => EGLContext.cpp} | 10 +++++----- .../{NSGLContextMac.mm => NSGLContext.mm} | 18 ++++++++---------- .../{WGLContextWindows.cpp => WGLContext.cpp} | 10 +++++----- plugins/Renderer/OpenGL/src/opgl.cpp | 12 ++++++------ plugins/Renderer/Vulkan/CMakeLists.txt | 2 +- plugins/Shader/Frontend/GLSL/CMakeLists.txt | 2 +- plugins/Shader/IR/SPIRV/CMakeLists.txt | 2 +- plugins/Window/Cocoa/CMakeLists.txt | 6 ++++-- plugins/Window/GLFW/CMakeLists.txt | 2 +- plugins/Window/X11/CMakeLists.txt | 2 +- src/application.cpp | 2 +- 17 files changed, 66 insertions(+), 57 deletions(-) rename plugins/Renderer/OpenGL/include/OPGL/Context/{EGLContextLinux.hpp => EGLContext.hpp} (73%) rename plugins/Renderer/OpenGL/include/OPGL/Context/{NSGLContextMac.hpp => NSGLContext.hpp} (66%) rename plugins/Renderer/OpenGL/include/OPGL/Context/{WGLContextWindows.hpp => WGLContext.hpp} (71%) rename plugins/Renderer/OpenGL/src/context/{EGLContextLinux.cpp => EGLContext.cpp} (91%) rename plugins/Renderer/OpenGL/src/context/{NSGLContextMac.mm => NSGLContext.mm} (77%) rename plugins/Renderer/OpenGL/src/context/{WGLContextWindows.cpp => WGLContext.cpp} (94%) diff --git a/modules/Engine/include/Engine/Camera.hpp b/modules/Engine/include/Engine/Camera.hpp index bbedfda..9387414 100644 --- a/modules/Engine/include/Engine/Camera.hpp +++ b/modules/Engine/include/Engine/Camera.hpp @@ -112,7 +112,7 @@ namespace cae private: std::string m_name = CAMERA::NAME; - glm::vec3 m_position = glm::vec3(1.0F, 1.0F, 5.0F); + glm::vec3 m_position = glm::vec3(0.0F, 0.0F, 0.0F); glm::vec3 m_rotation = glm::vec3(0.0F, 0.0F, 0.0F); glm::vec3 m_direction = glm::vec3(0.0F, 0.0F, -1.0F); diff --git a/modules/Engine/include/Engine/Engine.hpp b/modules/Engine/include/Engine/Engine.hpp index 8bbe913..085f909 100644 --- a/modules/Engine/include/Engine/Engine.hpp +++ b/modules/Engine/include/Engine/Engine.hpp @@ -96,7 +96,16 @@ namespace cae void initializeRenderResources(const std::vector &shaderSources, const std::vector &vertices) const; + /// + /// @param fpsBuffer + /// @param fpsIndex + /// @brief + /// void update(std::array &fpsBuffer, int &fpsIndex); + + /// + /// @brief + /// void render(); /// diff --git a/plugins/Renderer/OpenGL/CMakeLists.txt b/plugins/Renderer/OpenGL/CMakeLists.txt index 81b687b..38885b2 100644 --- a/plugins/Renderer/OpenGL/CMakeLists.txt +++ b/plugins/Renderer/OpenGL/CMakeLists.txt @@ -1,4 +1,4 @@ -project(cae-opengl +project(cae-renderer-opengl DESCRIPTION "CAE OpenGL Renderer Plugin" LANGUAGES CXX ) diff --git a/plugins/Renderer/OpenGL/include/OPGL/Context/EGLContextLinux.hpp b/plugins/Renderer/OpenGL/include/OPGL/Context/EGLContext.hpp similarity index 73% rename from plugins/Renderer/OpenGL/include/OPGL/Context/EGLContextLinux.hpp rename to plugins/Renderer/OpenGL/include/OPGL/Context/EGLContext.hpp index 7f19a22..4450cf5 100644 --- a/plugins/Renderer/OpenGL/include/OPGL/Context/EGLContextLinux.hpp +++ b/plugins/Renderer/OpenGL/include/OPGL/Context/EGLContext.hpp @@ -1,6 +1,6 @@ /// -/// @file EGLContextLinux.hpp -/// @brief This file contains the EGLContextLinux class declaration +/// @file EGLContext.hpp +/// @brief This file contains the EGLContext_ class declaration /// @namespace cae /// @@ -16,15 +16,15 @@ namespace cae { /// - /// @class EGLContextLinux + /// @class EGLContext_ /// @brief Implementation of IContext for Linux using EGL /// @namespace cae /// - class EGLContextLinux final : public IContext + class EGLContext_ final : public IContext { public: - explicit EGLContextLinux() = default; - ~EGLContextLinux() override; + explicit EGLContext_() = default; + ~EGLContext_() override; void initialize(const NativeWindowHandle &window) override; @@ -42,7 +42,7 @@ namespace cae EGLSurface m_surface = EGL_NO_SURFACE; EGLContext m_context = EGL_NO_CONTEXT; - }; // class EGLContextLinux + }; // class EGLContext_ } // namespace cae diff --git a/plugins/Renderer/OpenGL/include/OPGL/Context/NSGLContextMac.hpp b/plugins/Renderer/OpenGL/include/OPGL/Context/NSGLContext.hpp similarity index 66% rename from plugins/Renderer/OpenGL/include/OPGL/Context/NSGLContextMac.hpp rename to plugins/Renderer/OpenGL/include/OPGL/Context/NSGLContext.hpp index 675b825..ec4889d 100644 --- a/plugins/Renderer/OpenGL/include/OPGL/Context/NSGLContextMac.hpp +++ b/plugins/Renderer/OpenGL/include/OPGL/Context/NSGLContext.hpp @@ -1,6 +1,6 @@ /// -/// @file NSGLContextMac.hpp -/// @brief This file contains the NSGLContextMac class declaration +/// @file NSGLContext.hpp +/// @brief This file contains the NSGLContext class declaration /// @namespace cae /// @@ -14,15 +14,15 @@ namespace cae { /// - /// @class NSGLContextMac + /// @class NSGLContext /// @brief Implementation of IContext for macOS using NSGL /// @namespace cae /// - class NSGLContextMac final : public IContext + class NSGLContext final : public IContext { public: - NSGLContextMac() = default; - ~NSGLContextMac() override; + NSGLContext() = default; + ~NSGLContext() override; void initialize(const NativeWindowHandle &window) override; @@ -34,7 +34,7 @@ namespace cae private: void *m_context = nullptr; - }; // class NSGLContextMac + }; // class NSGLContext } // namespace cae diff --git a/plugins/Renderer/OpenGL/include/OPGL/Context/WGLContextWindows.hpp b/plugins/Renderer/OpenGL/include/OPGL/Context/WGLContext.hpp similarity index 71% rename from plugins/Renderer/OpenGL/include/OPGL/Context/WGLContextWindows.hpp rename to plugins/Renderer/OpenGL/include/OPGL/Context/WGLContext.hpp index 845b985..532d671 100644 --- a/plugins/Renderer/OpenGL/include/OPGL/Context/WGLContextWindows.hpp +++ b/plugins/Renderer/OpenGL/include/OPGL/Context/WGLContext.hpp @@ -1,6 +1,6 @@ /// -/// @file WGLContextWindows.hpp -/// @brief This file contains the WGLContextWindows class declaration +/// @file WGLContext.hpp +/// @brief This file contains the WGLContext class declaration /// @namespace cae /// @@ -16,15 +16,15 @@ namespace cae { /// - /// @class WGLContextWindows + /// @class WGLContext /// @brief Implementation of IContext for Windows using WGL /// @namespace cae /// - class WGLContextWindows final : public IContext + class WGLContext final : public IContext { public: - WGLContextWindows() = default; - ~WGLContextWindows() override; + WGLContext() = default; + ~WGLContext() override; void initialize(const NativeWindowHandle &window) override; void swapBuffers() override; @@ -40,7 +40,7 @@ namespace cae HDC m_hdc = nullptr; HGLRC m_hglrc = nullptr; - }; // class WGLContextWindows + }; // class WGLContext } // namespace cae diff --git a/plugins/Renderer/OpenGL/src/context/EGLContextLinux.cpp b/plugins/Renderer/OpenGL/src/context/EGLContext.cpp similarity index 91% rename from plugins/Renderer/OpenGL/src/context/EGLContextLinux.cpp rename to plugins/Renderer/OpenGL/src/context/EGLContext.cpp index 4729f7a..f1ab024 100644 --- a/plugins/Renderer/OpenGL/src/context/EGLContextLinux.cpp +++ b/plugins/Renderer/OpenGL/src/context/EGLContext.cpp @@ -1,10 +1,10 @@ #ifdef __linux__ -#include "OPGL/Context/EGLContextLinux.hpp" +#include "OPGL/Context/EGLContext.hpp" #include -cae::EGLContextLinux::~EGLContextLinux() +cae::EGLContext_::~EGLContext_() { if (m_display != EGL_NO_DISPLAY) { @@ -21,7 +21,7 @@ cae::EGLContextLinux::~EGLContextLinux() } } -void cae::EGLContextLinux::initialize(const NativeWindowHandle &window) +void cae::EGLContext_::initialize(const NativeWindowHandle &window) { if (eglBindAPI(EGL_OPENGL_API) == EGL_FALSE) { @@ -87,7 +87,7 @@ void cae::EGLContextLinux::initialize(const NativeWindowHandle &window) } } -void cae::EGLContextLinux::swapBuffers() +void cae::EGLContext_::swapBuffers() { if (m_display != EGL_NO_DISPLAY && m_surface != EGL_NO_SURFACE) { @@ -95,7 +95,7 @@ void cae::EGLContextLinux::swapBuffers() } } -void cae::EGLContextLinux::setVSyncEnabled(const bool enabled) +void cae::EGLContext_::setVSyncEnabled(const bool enabled) { if (m_display != EGL_NO_DISPLAY) { diff --git a/plugins/Renderer/OpenGL/src/context/NSGLContextMac.mm b/plugins/Renderer/OpenGL/src/context/NSGLContext.mm similarity index 77% rename from plugins/Renderer/OpenGL/src/context/NSGLContextMac.mm rename to plugins/Renderer/OpenGL/src/context/NSGLContext.mm index 7545def..c1bf7d6 100644 --- a/plugins/Renderer/OpenGL/src/context/NSGLContextMac.mm +++ b/plugins/Renderer/OpenGL/src/context/NSGLContext.mm @@ -1,19 +1,17 @@ -#if defined(__APPLE__) +#ifdef __APPLE__ -#include "OPGL/Context/NSGLContextMac.hpp" - -#include "Utils/Logger.hpp" +#include "OPGL/Context/NSGLContext.hpp" #import -cae::NSGLContextMac::~NSGLContextMac() { +cae::NSGLContext::~NSGLContext() { if (m_context) { [(NSOpenGLContext*)m_context clearDrawable]; m_context = nil; } } -void cae::NSGLContextMac::initialize(const NativeWindowHandle &window) { +void cae::NSGLContext::initialize(const NativeWindowHandle &window) { NSView* nsview = (__bridge NSView*)window.display; NSOpenGLPixelFormatAttribute attrs[] = { @@ -37,19 +35,19 @@ } } -void cae::NSGLContextMac::swapBuffers() { +void cae::NSGLContext::swapBuffers() { if (m_context) [(NSOpenGLContext*)m_context flushBuffer]; } -void cae::NSGLContextMac::setVSyncEnabled(const bool enabled) { +void cae::NSGLContext::setVSyncEnabled(const bool enabled) { if (m_context) { GLint sync = enabled ? 1 : 0; [(NSOpenGLContext*)m_context setValues:&sync forParameter:NSOpenGLContextParameterSwapInterval]; } } -bool cae::NSGLContextMac::isVSyncEnabled() const { +bool cae::NSGLContext::isVSyncEnabled() const { if (m_context) { GLint sync = 0; [(NSOpenGLContext*)m_context getValues:&sync forParameter:NSOpenGLContextParameterSwapInterval]; @@ -58,4 +56,4 @@ return false; } -#endif // defined(__APPLE__) \ No newline at end of file +#endif \ No newline at end of file diff --git a/plugins/Renderer/OpenGL/src/context/WGLContextWindows.cpp b/plugins/Renderer/OpenGL/src/context/WGLContext.cpp similarity index 94% rename from plugins/Renderer/OpenGL/src/context/WGLContextWindows.cpp rename to plugins/Renderer/OpenGL/src/context/WGLContext.cpp index 0b56da4..57c2b33 100644 --- a/plugins/Renderer/OpenGL/src/context/WGLContextWindows.cpp +++ b/plugins/Renderer/OpenGL/src/context/WGLContext.cpp @@ -1,6 +1,6 @@ #ifdef _WIN32 -#include "OPGL/Context/WGLContextWindows.hpp" +#include "OPGL/Context/WGLContext.hpp" #include "Utils/Logger.hpp" @@ -50,7 +50,7 @@ static void *win32GetGLProc(const char *name) return proc; } -cae::WGLContextWindows::~WGLContextWindows() +cae::WGLContext::~WGLContext() { if (m_hglrc != nullptr) { @@ -63,7 +63,7 @@ cae::WGLContextWindows::~WGLContextWindows() } } -void cae::WGLContextWindows::initialize(const NativeWindowHandle &window) +void cae::WGLContext::initialize(const NativeWindowHandle &window) { m_hwnd = static_cast(window.window); m_hdc = GetDC(m_hwnd); @@ -149,7 +149,7 @@ void cae::WGLContextWindows::initialize(const NativeWindowHandle &window) } } -void cae::WGLContextWindows::swapBuffers() +void cae::WGLContext::swapBuffers() { if (m_hdc != nullptr) { @@ -157,7 +157,7 @@ void cae::WGLContextWindows::swapBuffers() } } -void cae::WGLContextWindows::setVSyncEnabled(const bool enabled) +void cae::WGLContext::setVSyncEnabled(const bool enabled) { using PFNWGLSWAPINTERVALEXTPROC = BOOL(WINAPI *)(int); static auto wglSwapIntervalEXT = diff --git a/plugins/Renderer/OpenGL/src/opgl.cpp b/plugins/Renderer/OpenGL/src/opgl.cpp index d1ec723..99f9409 100644 --- a/plugins/Renderer/OpenGL/src/opgl.cpp +++ b/plugins/Renderer/OpenGL/src/opgl.cpp @@ -1,11 +1,11 @@ #include "OPGL/OPGL.hpp" #ifdef __linux__ -#include "OPGL/Context/EGLContextLinux.hpp" +#include "OPGL/Context/EGLContext.hpp" #elifdef _WIN32 -#include "OPGL/Context/WGLContextWindows.hpp" +#include "OPGL/Context/WGLContext.hpp" #elifdef __APPLE__ -#include "OPGL/Context/NSGLContextMac.hpp" +#include "OPGL/Context/NSGLContext.hpp" #endif #include @@ -15,11 +15,11 @@ void cae::OPGL::initialize(const NativeWindowHandle &nativeWindowHandle, const Color &clearColor) { #ifdef __linux__ - m_context = std::make_unique(); + m_context = std::make_unique(); #elifdef _WIN32 - m_context = std::make_unique(); + m_context = std::make_unique(); #elifdef __APPLE__ - m_context = std::make_unique(); + m_context = std::make_unique(); #endif m_context->initialize(nativeWindowHandle); diff --git a/plugins/Renderer/Vulkan/CMakeLists.txt b/plugins/Renderer/Vulkan/CMakeLists.txt index 2cfd729..78c4cac 100644 --- a/plugins/Renderer/Vulkan/CMakeLists.txt +++ b/plugins/Renderer/Vulkan/CMakeLists.txt @@ -1,4 +1,4 @@ -project(cae-vulkan +project(cae-renderer-vulkan DESCRIPTION "CAE Vulkan Renderer Plugin" LANGUAGES C CXX ) diff --git a/plugins/Shader/Frontend/GLSL/CMakeLists.txt b/plugins/Shader/Frontend/GLSL/CMakeLists.txt index a4cddf3..5087cb0 100644 --- a/plugins/Shader/Frontend/GLSL/CMakeLists.txt +++ b/plugins/Shader/Frontend/GLSL/CMakeLists.txt @@ -1,4 +1,4 @@ -project(cae-glsl +project(cae-shaders-frontend-glsl DESCRIPTION "CAE GLSL Shader Frontend Plugin" LANGUAGES C CXX ) diff --git a/plugins/Shader/IR/SPIRV/CMakeLists.txt b/plugins/Shader/IR/SPIRV/CMakeLists.txt index 9c13c54..2099e4a 100644 --- a/plugins/Shader/IR/SPIRV/CMakeLists.txt +++ b/plugins/Shader/IR/SPIRV/CMakeLists.txt @@ -10,7 +10,7 @@ ## set(SPIRV_TOOLS_INCLUDE_DIR ${spirv-headers_SOURCE_DIR}) ## FetchContent_MakeAvailable(spirv-tools) -project(cae-spirv +project(cae-shaders-ir-spirv DESCRIPTION "CAE SPIRV Shader Intermediate Representation Plugin" LANGUAGES C CXX ) diff --git a/plugins/Window/Cocoa/CMakeLists.txt b/plugins/Window/Cocoa/CMakeLists.txt index 5e20d2a..eac2724 100644 --- a/plugins/Window/Cocoa/CMakeLists.txt +++ b/plugins/Window/Cocoa/CMakeLists.txt @@ -1,11 +1,13 @@ -project(cae-cocoa +project(cae-window-cocoa DESCRIPTION "CAE Cocoa Window Plugin" - LANGUAGES C CXX OBJCXX + LANGUAGES C CXX ) if (NOT APPLE) message(WARNING "${PROJECT_NAME} can only be build on MacOS") return() +else () + enable_language(OBJCXX) endif () file(GLOB_RECURSE SOURCES "${PROJECT_SOURCE_DIR}/src/*.mm" "${PROJECT_SOURCE_DIR}/src/*.cpp") diff --git a/plugins/Window/GLFW/CMakeLists.txt b/plugins/Window/GLFW/CMakeLists.txt index 48cae68..56ba02e 100644 --- a/plugins/Window/GLFW/CMakeLists.txt +++ b/plugins/Window/GLFW/CMakeLists.txt @@ -1,4 +1,4 @@ -project(cae-glfw +project(cae-window-glfw DESCRIPTION "CAE GLFW Window Plugin" LANGUAGES C CXX ) diff --git a/plugins/Window/X11/CMakeLists.txt b/plugins/Window/X11/CMakeLists.txt index b2df99c..24f1eee 100644 --- a/plugins/Window/X11/CMakeLists.txt +++ b/plugins/Window/X11/CMakeLists.txt @@ -1,4 +1,4 @@ -project(cae-x11 +project(cae-window-x11 DESCRIPTION "CAE X11 Window Plugin" LANGUAGES C CXX ) diff --git a/src/application.cpp b/src/application.cpp index 7d19559..bd2019a 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -53,7 +53,7 @@ cae::Application::Application(const ArgsConfig &argsConfig, const EnvConfig &env { m_appConfig.engineConfig = parseEngineConf(argsConfig.config_path); } - setupEngine(PLUGINS::NAME::RENDERER::OPENGL, PLUGINS::NAME::WINDOW::COCOA, PLUGINS::NAME::SHADER::FRONTEND::GLSL, + setupEngine(PLUGINS::NAME::RENDERER::OPENGL, PLUGINS::NAME::WINDOW::GLFW, PLUGINS::NAME::SHADER::FRONTEND::GLSL, PLUGINS::NAME::SHADER::IR::SPIRV); } catch (const std::exception &e) From f2ea815cac4a3e95360bf2e968e7bd829c50e337 Mon Sep 17 00:00:00 2001 From: bobi Date: Tue, 20 Jan 2026 14:39:05 +0100 Subject: [PATCH 17/20] Build: cmake option for shaders frontend glsl and shader ir spirv --- CMakeLists.txt | 10 +---- include/CAE/Application.hpp | 4 +- modules/Engine/include/Engine/Camera.hpp | 43 +++++++++---------- modules/Engine/include/Engine/Engine.hpp | 4 +- .../Shader/Frontend/AShaderFrontend.hpp | 2 +- modules/Utils/include/Utils/Path.hpp | 1 - modules/Utils/include/Utils/PluginLoader.hpp | 1 + plugins/Renderer/Vulkan/CMakeLists.txt | 5 +-- plugins/Shader/Frontend/GLSL/CMakeLists.txt | 4 +- plugins/Shader/IR/SPIRV/CMakeLists.txt | 5 ++- plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp | 22 ++++++++-- plugins/Window/GLFW/src/glfw.cpp | 29 ++++++++----- plugins/Window/Win32/CMakeLists.txt | 6 +-- plugins/Window/Win32/include/Win32/Win32.hpp | 7 ++- plugins/Window/Win32/src/win32.cpp | 8 ++-- plugins/Window/X11/include/X11/X11.hpp | 4 ++ 16 files changed, 89 insertions(+), 66 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 33de981..3431e7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,8 +44,8 @@ FetchContent_Declare( GIT_PROGRESS TRUE ) FetchContent_MakeAvailable(nlohmann-json) -set(GLM_BUILD_TESTS OFF CACHE INTERNAL "") -set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "") +set(GLM_BUILD_TESTS OFF CACHE BOOL "" FORCE) +set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) FetchContent_Declare( glm GIT_REPOSITORY "https://github.com/g-truc/glm.git" @@ -103,9 +103,3 @@ if (MSVC) else () target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS} -O3) endif () - -copy_directory_to_target( - cae - "${CMAKE_SOURCE_DIR}/assets" - "assets" -) diff --git a/include/CAE/Application.hpp b/include/CAE/Application.hpp index e3297da..9e8b2e7 100644 --- a/include/CAE/Application.hpp +++ b/include/CAE/Application.hpp @@ -75,6 +75,9 @@ namespace cae /// static EngineConfig parseEngineConf(const std::string &path); + /// + /// @brief main loop + /// void mainLoop(); std::unique_ptr m_pluginLoader = nullptr; @@ -83,7 +86,6 @@ namespace cae AppConfig m_appConfig; std::unordered_map m_keyState; - }; // class Application } // namespace cae diff --git a/modules/Engine/include/Engine/Camera.hpp b/modules/Engine/include/Engine/Camera.hpp index 9387414..42aed98 100644 --- a/modules/Engine/include/Engine/Camera.hpp +++ b/modules/Engine/include/Engine/Camera.hpp @@ -23,7 +23,13 @@ namespace cae class Camera { public: - Camera() = default; + Camera(const glm::vec3 position, const glm::vec3 rotation, const glm::vec3 direction, const float moveSpeed = CAMERA::MOVE_SPEED, + const float lookSpeed = CAMERA::LOOK_SPEED, const float fov = CAMERA::FOV, const float nearPlane = CAMERA::NEAR_PLANE, + const float farPlane = CAMERA::FAR_PLANE) + : m_position(position), m_rotation(rotation), m_direction(direction), m_moveSpeed(moveSpeed), + m_lookSpeed(lookSpeed), m_fov(fov), m_near(nearPlane), m_far(farPlane) + { + } ~Camera() = default; Camera(const Camera &) = delete; @@ -31,14 +37,6 @@ namespace cae Camera(Camera &&) = delete; Camera &operator=(Camera &&) = delete; - Camera(glm::vec3 position, glm::vec3 rotation, glm::vec3 direction, float moveSpeed = CAMERA::MOVE_SPEED, - float lookSpeed = CAMERA::LOOK_SPEED, float fov = CAMERA::FOV, float nearPlane = CAMERA::NEAR_PLANE, - float farPlane = CAMERA::FAR_PLANE) - : m_position(position), m_rotation(rotation), m_direction(direction), m_moveSpeed(moveSpeed), - m_lookSpeed(lookSpeed), m_fov(fov), m_near(nearPlane), m_far(farPlane) - { - } - void setName(const std::string &name) { m_name = name; } void setPosition(const glm::vec3 &position) { m_position = position; } void setRotation(const glm::vec3 &rotation) { m_rotation = rotation; } @@ -61,7 +59,7 @@ namespace cae [[nodiscard]] glm::mat4 getViewMatrix() const { - return glm::lookAt(m_position, m_position + m_direction, glm::vec3(0.0f, 1.0f, 0.0f)); + return glm::lookAt(m_position, m_position + m_direction, glm::vec3(0.0F, 1.0F, 0.0F)); } [[nodiscard]] glm::mat4 getProjectionMatrix(const float aspectRatio) const { @@ -72,16 +70,6 @@ namespace cae return getProjectionMatrix(aspectRatio) * getViewMatrix(); } - void updateDirectionFromRotation() - { - const float yaw = glm::radians(m_rotation.y); - const float pitch = glm::radians(m_rotation.x); - - m_direction.x = cos(pitch) * sin(yaw); - m_direction.y = std::sin(pitch); - m_direction.z = -cos(pitch) * cos(yaw); - m_direction = glm::normalize(m_direction); - } /// /// @param direction Direction to move the camera /// @param deltaTime Time delta for movement @@ -103,8 +91,8 @@ namespace cae m_rotation.y += yawOffset * m_lookSpeed * deltaTime; m_rotation.x += pitchOffset * m_lookSpeed * deltaTime; - m_rotation.x = std::min(m_rotation.x, 89.0f); - m_rotation.x = std::max(m_rotation.x, -89.0f); + m_rotation.x = std::min(m_rotation.x, 89.0F); + m_rotation.x = std::max(m_rotation.x, -89.0F); updateDirectionFromRotation(); } @@ -123,6 +111,17 @@ namespace cae float m_near = CAMERA::NEAR_PLANE; float m_far = CAMERA::FAR_PLANE; + void updateDirectionFromRotation() + { + const float yaw = glm::radians(m_rotation.y); + const float pitch = glm::radians(m_rotation.x); + + m_direction.x = cos(pitch) * sin(yaw); + m_direction.y = std::sin(pitch); + m_direction.z = -cos(pitch) * cos(yaw); + m_direction = glm::normalize(m_direction); + } + }; // class Camera } // namespace cae diff --git a/modules/Engine/include/Engine/Engine.hpp b/modules/Engine/include/Engine/Engine.hpp index 085f909..eeedd5b 100644 --- a/modules/Engine/include/Engine/Engine.hpp +++ b/modules/Engine/include/Engine/Engine.hpp @@ -29,8 +29,8 @@ namespace cae float audio_master_volume = AUDIO::VOLUME; bool audio_muted = AUDIO::MUTED; - glm::vec3 camera_position = glm::vec3(0.0F, 0.0F, 5.0F); - glm::vec3 camera_rotation = glm::vec3(0.0F, 0.0F, -1.0F); + glm::vec3 camera_position = glm::vec3(0.0F, 0.0F, 0.0F); + glm::vec3 camera_rotation = glm::vec3(0.0F, 0.0F, 0.0F); glm::vec3 camera_direction = glm::vec3(0.0F, 0.0F, -1.0F); float camera_move_speed = CAMERA::MOVE_SPEED; float camera_look_speed = CAMERA::LOOK_SPEED; diff --git a/modules/Interfaces/include/Interfaces/Shader/Frontend/AShaderFrontend.hpp b/modules/Interfaces/include/Interfaces/Shader/Frontend/AShaderFrontend.hpp index a39772c..9a2c9bd 100644 --- a/modules/Interfaces/include/Interfaces/Shader/Frontend/AShaderFrontend.hpp +++ b/modules/Interfaces/include/Interfaces/Shader/Frontend/AShaderFrontend.hpp @@ -12,7 +12,7 @@ namespace cae { /// - /// @interface IShaderFrontend + /// @interface AShaderFrontend /// @brief Abstract class for shader frontend /// @namespace cae /// diff --git a/modules/Utils/include/Utils/Path.hpp b/modules/Utils/include/Utils/Path.hpp index 7b3be26..aa49f38 100644 --- a/modules/Utils/include/Utils/Path.hpp +++ b/modules/Utils/include/Utils/Path.hpp @@ -132,7 +132,6 @@ namespace utl return normalize(fs::current_path() / relativePath); } - }; // class Path } // namespace utl diff --git a/modules/Utils/include/Utils/PluginLoader.hpp b/modules/Utils/include/Utils/PluginLoader.hpp index e550965..f8582cf 100644 --- a/modules/Utils/include/Utils/PluginLoader.hpp +++ b/modules/Utils/include/Utils/PluginLoader.hpp @@ -143,6 +143,7 @@ namespace utl } catch (const std::exception &e) { + throw std::runtime_error(std::string("Unknown exception: ") + e.what()); return nullptr; } } diff --git a/plugins/Renderer/Vulkan/CMakeLists.txt b/plugins/Renderer/Vulkan/CMakeLists.txt index 78c4cac..08823b1 100644 --- a/plugins/Renderer/Vulkan/CMakeLists.txt +++ b/plugins/Renderer/Vulkan/CMakeLists.txt @@ -5,12 +5,9 @@ project(cae-renderer-vulkan find_package(Vulkan QUIET CONFIG) if(NOT Vulkan_FOUND) - message(STATUS "Vulkan SDK not found.") - include(FetchContent) - set(VULKAN_VERSION "v1.4.329") - + set(VULKAN_HEADERS_ENABLE_TESTS OFF CACHE BOOL "" FORCE) FetchContent_Declare( VulkanHeaders GIT_REPOSITORY "https://github.com/KhronosGroup/Vulkan-Headers.git" diff --git a/plugins/Shader/Frontend/GLSL/CMakeLists.txt b/plugins/Shader/Frontend/GLSL/CMakeLists.txt index 5087cb0..92170d9 100644 --- a/plugins/Shader/Frontend/GLSL/CMakeLists.txt +++ b/plugins/Shader/Frontend/GLSL/CMakeLists.txt @@ -5,12 +5,12 @@ project(cae-shaders-frontend-glsl find_package(glslang QUIET CONFIG) if (NOT glslang_FOUND) - message(STATUS "glslang not found.") - include(FetchContent) + set(BUILD_EXTERNAL OFF CACHE BOOL "" FORCE) set(ENABLE_HLSL OFF CACHE BOOL "" FORCE) set(ENABLE_OPT OFF CACHE BOOL "" FORCE) set(ENABLE_SPIRV ON CACHE BOOL "" FORCE) + set(ENABLE_GLSLANG_BINARIES ON CACHE BOOL "" FORCE) set(GLSLANG_TESTS OFF CACHE BOOL "" FORCE) FetchContent_Declare( glslang diff --git a/plugins/Shader/IR/SPIRV/CMakeLists.txt b/plugins/Shader/IR/SPIRV/CMakeLists.txt index 2099e4a..1d7d3ec 100644 --- a/plugins/Shader/IR/SPIRV/CMakeLists.txt +++ b/plugins/Shader/IR/SPIRV/CMakeLists.txt @@ -20,7 +20,7 @@ include(FetchContent) find_package(SPIRV-Headers QUIET CONFIG) if(NOT SPIRV-Headers_FOUND) - message(STATUS "SPIRV-Headers not found.") + set(SPIRV_HEADERS_ENABLE_TESTS OFF CACHE BOOL "" FORCE) FetchContent_Declare( spirv-headers GIT_REPOSITORY "https://github.com/KhronosGroup/SPIRV-Headers.git" @@ -38,7 +38,8 @@ endif() find_package(SPIRV-Cross QUIET CONFIG) if(NOT SPIRV-Cross_FOUND) - message(STATUS "SPIRV-Cross not found.") + set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE BOOL "" FORCE) + set(SPIRV_CROSS_CLI OFF CACHE BOOL "" FORCE) FetchContent_Declare( spirv-cross GIT_REPOSITORY "https://github.com/KhronosGroup/SPIRV-Cross.git" diff --git a/plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp b/plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp index af021d0..dd308ba 100644 --- a/plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp +++ b/plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp @@ -1,13 +1,25 @@ +/// +/// @file Cocoa.hpp +/// @brief This file contains the hpp class declaration +/// @namespace cae +/// + #pragma once +#ifdef __APPLE__ + #include "Interfaces/Window/AWindow.hpp" #include -#ifdef __APPLE__ - namespace cae { + + /// + /// @class Cocoa + /// @brief Class for the Cocoa plugin + /// @namespace cae + /// class Cocoa final : public AWindow { public: @@ -46,7 +58,9 @@ namespace cae std::queue m_eventQueue; WindowSize m_size{}; - }; -} + + }; // class Cocoa + +} // namespace cae #endif diff --git a/plugins/Window/GLFW/src/glfw.cpp b/plugins/Window/GLFW/src/glfw.cpp index fa1d925..9aaab49 100644 --- a/plugins/Window/GLFW/src/glfw.cpp +++ b/plugins/Window/GLFW/src/glfw.cpp @@ -4,6 +4,7 @@ #include "Utils/Logger.hpp" #include + #include static cae::KeyCode translateKey(const int key) @@ -67,16 +68,18 @@ static cae::KeyCode translateKey(const int key) void cae::GLFW::keyCallback(GLFWwindow *window, const int key, int, const int action, int) { auto *self = static_cast(glfwGetWindowUserPointer(window)); - if (!self) + if (self == nullptr) { return; + } WindowEvent e{}; - if (action == GLFW_PRESS) + if (action == GLFW_PRESS) { e.type = WindowEventType::KeyDown; - else if (action == GLFW_RELEASE) + } else if (action == GLFW_RELEASE) { e.type = WindowEventType::KeyUp; - else + } else { return; + } e.key.key = translateKey(key); self->m_eventQueue.push(e); @@ -85,8 +88,9 @@ void cae::GLFW::keyCallback(GLFWwindow *window, const int key, int, const int ac void cae::GLFW::mouseButtonCallback(GLFWwindow *window, int button, const int action, int) { auto *self = static_cast(glfwGetWindowUserPointer(window)); - if (!self) + if (self == nullptr) { return; + } WindowEvent e{}; e.type = (action == GLFW_PRESS) ? WindowEventType::MouseButtonDown : WindowEventType::MouseButtonUp; @@ -98,8 +102,9 @@ void cae::GLFW::mouseButtonCallback(GLFWwindow *window, int button, const int ac void cae::GLFW::cursorPosCallback(GLFWwindow *window, const double x, const double y) { auto *self = static_cast(glfwGetWindowUserPointer(window)); - if (!self) + if (self == nullptr) { return; + } WindowEvent e{}; e.type = WindowEventType::MouseMove; @@ -112,8 +117,9 @@ void cae::GLFW::cursorPosCallback(GLFWwindow *window, const double x, const doub void cae::GLFW::scrollCallback(GLFWwindow *window, const double xoffset, const double yoffset) { auto *self = static_cast(glfwGetWindowUserPointer(window)); - if (!self) + if (self == nullptr) { return; + } WindowEvent e{}; e.type = WindowEventType::MouseScroll; @@ -126,11 +132,12 @@ void cae::GLFW::scrollCallback(GLFWwindow *window, const double xoffset, const d void cae::GLFW::frameBufferResizeCallback(GLFWwindow *window, const int width, const int height) { auto *self = static_cast(glfwGetWindowUserPointer(window)); - if (!self) + if (self == nullptr) { return; + } self->m_frameBufferResized = true; - self->m_frameBufferSize = {static_cast(width), static_cast(height)}; + self->m_frameBufferSize = {.width=static_cast(width), .height=static_cast(height)}; WindowEvent e{}; e.type = WindowEventType::Resize; @@ -214,6 +221,7 @@ void cae::GLFW::setIcon(const std::string &path) const if (image.pixels == nullptr) { utl::Logger::log("Failed to create icon.", utl::LogLevel::WARNING); + return; } static const GLFWimage appIcon{.width = image.width, .height = image.height, .pixels = image.pixels}; glfwSetWindowIcon(m_window, 1, &appIcon); @@ -221,8 +229,9 @@ void cae::GLFW::setIcon(const std::string &path) const bool cae::GLFW::pollEvent(WindowEvent &event) { - if (m_eventQueue.empty()) + if (m_eventQueue.empty()) { return false; + } event = m_eventQueue.front(); m_eventQueue.pop(); diff --git a/plugins/Window/Win32/CMakeLists.txt b/plugins/Window/Win32/CMakeLists.txt index d34d0a0..8b00dc6 100644 --- a/plugins/Window/Win32/CMakeLists.txt +++ b/plugins/Window/Win32/CMakeLists.txt @@ -22,12 +22,8 @@ endif() file(GLOB_RECURSE SOURCE "${PROJECT_SOURCE_DIR}/src/*.cpp") -file(GLOB_RECURSE HEADERS "${PROJECT_SOURCE_DIR}/include/*.hpp") -add_library(${PROJECT_NAME} SHARED - ${SOURCE} - ${HEADERS} -) +add_library(${PROJECT_NAME} SHARED ${SOURCE}) target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include") target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) diff --git a/plugins/Window/Win32/include/Win32/Win32.hpp b/plugins/Window/Win32/include/Win32/Win32.hpp index b51764c..b91ef53 100644 --- a/plugins/Window/Win32/include/Win32/Win32.hpp +++ b/plugins/Window/Win32/include/Win32/Win32.hpp @@ -6,6 +6,8 @@ #pragma once +#ifdef _WIN32 + #include "Interfaces/Window/AWindow.hpp" #include @@ -64,4 +66,7 @@ namespace cae bool m_shouldClose = false; }; // class Win32 -} // namespace cae \ No newline at end of file + +} // namespace cae + +#endif diff --git a/plugins/Window/Win32/src/win32.cpp b/plugins/Window/Win32/src/win32.cpp index 6b2edca..686395f 100644 --- a/plugins/Window/Win32/src/win32.cpp +++ b/plugins/Window/Win32/src/win32.cpp @@ -7,6 +7,7 @@ #include #include +#include constexpr wchar_t WINDOW_CLASS_NAME[] = L"CAE_WindowsWindowClass"; @@ -86,8 +87,9 @@ LRESULT CALLBACK cae::Win32::WindowProc(const HWND hwnd, const UINT msg, const W } self = reinterpret_cast(GetWindowLongPtrW(hwnd, GWLP_USERDATA)); - if (!self) + if (self == nullptr) { return DefWindowProcW(hwnd, msg, wParam, lParam); +} WindowEvent e{}; switch (msg) @@ -203,7 +205,7 @@ void cae::Win32::setIcon(const std::string &path) const { const utl::Image image(path); - for (size_t i = 0; i < static_cast(image.width * image.height); ++i) + for (size_t i = 0; std::cmp_less(i ,image.width * image.height); ++i) { std::swap(image.pixels[(i * 4) + 0], image.pixels[(i * 4) + 2]); } @@ -231,7 +233,7 @@ void cae::Win32::setIcon(const std::string &path) const if (hBitmap == nullptr) { - utl::Logger::log("Failed to create window icon", utl::LogLevel::WARNING); + utl::Logger::log("Failed to create window icon.", utl::LogLevel::WARNING); return; } diff --git a/plugins/Window/X11/include/X11/X11.hpp b/plugins/Window/X11/include/X11/X11.hpp index 4ca79c9..b9b1129 100644 --- a/plugins/Window/X11/include/X11/X11.hpp +++ b/plugins/Window/X11/include/X11/X11.hpp @@ -6,6 +6,8 @@ #pragma once +#ifdef __unix__ + #include "Interfaces/Window/AWindow.hpp" #include @@ -66,3 +68,5 @@ namespace cae }; // class X11 } // namespace cae + +#endif From 94cc6b6e02ebbb8ca0d80f5d74d1382ad921bdfb Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Tue, 20 Jan 2026 20:20:39 +0100 Subject: [PATCH 18/20] Build: clean compile options --- .gitignore | 2 - CMakeLists.txt | 91 ++++++-------- cmake/modules/CompileOptions.cmake | 113 ++++++++++++++++++ include/CAE/Common.hpp | 2 +- modules/CMakeLists.txt | 1 + modules/Engine/CMakeLists.txt | 3 +- modules/Utils/CMakeLists.txt | 6 +- plugins/Renderer/OpenGL/CMakeLists.txt | 2 - .../OpenGL/src/context/WGLContext.cpp | 16 +-- plugins/Renderer/Vulkan/CMakeLists.txt | 2 - plugins/Shader/Frontend/GLSL/CMakeLists.txt | 3 +- plugins/Shader/Frontend/HLSL/CMakeLists.txt | 2 - plugins/Shader/Frontend/MSL/CMakeLists.txt | 2 - plugins/Shader/Frontend/WGSL/CMakeLists.txt | 2 - plugins/Shader/IR/DXC/CMakeLists.txt | 2 - plugins/Shader/IR/SPIRV/CMakeLists.txt | 2 - plugins/Window/Cocoa/CMakeLists.txt | 2 - plugins/Window/GLFW/CMakeLists.txt | 2 - plugins/Window/Win32/CMakeLists.txt | 4 +- plugins/Window/X11/CMakeLists.txt | 7 +- plugins/Window/X11/include/X11/X11.hpp | 2 +- tests/CMakeLists.txt | 3 +- 22 files changed, 172 insertions(+), 99 deletions(-) create mode 100644 cmake/modules/CompileOptions.cmake diff --git a/.gitignore b/.gitignore index d9875ce..880e9cf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,3 @@ .vs/ cmake-build-* - -include/CAE/Generated/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 3431e7f..1439057 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/lib") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/lib") set(PLUGIN_DIR "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") -set(PATH_VERSION "${PROJECT_SOURCE_DIR}/include/CAE/Generated/Version.hpp") +set(PATH_VERSION "${PROJECT_BINARY_DIR}/include/CAE/Version.hpp") set(TEMPLATE_PATH "${PROJECT_SOURCE_DIR}/cmake/config/Version.hpp.in") add_compile_definitions(PLUGINS_DIR="${PLUGIN_DIR}") @@ -34,26 +34,33 @@ include(MakeDoc) include(ClangTidy) include(ClangFormat) include(CopyAssets) +include(CompileOptions) -include(FetchContent) -FetchContent_Declare( - nlohmann-json - GIT_REPOSITORY "https://github.com/nlohmann/json.git" - GIT_TAG "v3.12.0" - GIT_SHALLOW TRUE - GIT_PROGRESS TRUE -) -FetchContent_MakeAvailable(nlohmann-json) -set(GLM_BUILD_TESTS OFF CACHE BOOL "" FORCE) -set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) -FetchContent_Declare( - glm - GIT_REPOSITORY "https://github.com/g-truc/glm.git" - GIT_TAG 1.0.3 - GIT_SHALLOW TRUE - GIT_PROGRESS TRUE -) -FetchContent_MakeAvailable(glm) +find_package(nlohmann_json QUIET CONFIG) +if (NOT nlohmann_json_FOUND) + include(FetchContent) + FetchContent_Declare( + nlohmann-json + GIT_REPOSITORY "https://github.com/nlohmann/json.git" + GIT_TAG "v3.12.0" + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + ) + FetchContent_MakeAvailable(nlohmann-json) +endif () +find_package(glm QUIET CONFIG) +if (NOT glm_FOUND) + FetchContent_Declare( + glm + GIT_REPOSITORY "https://github.com/g-truc/glm.git" + GIT_TAG 1.0.3 + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + ) + set(GLM_BUILD_TESTS OFF CACHE BOOL "" FORCE) + set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(glm) +endif () add_subdirectory(modules) add_subdirectory(plugins) @@ -61,45 +68,15 @@ add_subdirectory(tests) add_executable(${PROJECT_NAME} ${SOURCES}) add_dependencies(${PROJECT_NAME} cae-modules) -target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ${glm_SOURCE_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" "${PROJECT_BINARY_DIR}/include" ${glm_SOURCE_DIR}) target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules nlohmann_json::nlohmann_json glm::glm ) -if (NOT WIN32 AND NOT APPLE) - set(WARNING_FLAGS - -Wall - -Wextra - -Wdeprecated-copy - -Wmisleading-indentation - -Wnull-dereference - -Woverloaded-virtual - -Wpedantic - -Wshadow - -Wsign-conversion - -Wnon-virtual-dtor - -Wunused - -Wcast-align - -Wno-padded - -Wconversion - -Wformat - -Winit-self - -Wmissing-include-dirs - -Wold-style-cast - -Wredundant-decls - -Wswitch-default - -Wundef - ) -else () - if (MSVC) - set(WARNING_FLAGS /W3) - else() - set(WARNING_FLAGS -Wno-error) - endif() -endif() -if (MSVC) - target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS} /O2) -else () - target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS} -O3) -endif () + +copy_directory_to_target( + cae + "${CMAKE_SOURCE_DIR}/assets" + "assets" +) diff --git a/cmake/modules/CompileOptions.cmake b/cmake/modules/CompileOptions.cmake new file mode 100644 index 0000000..5b0bc68 --- /dev/null +++ b/cmake/modules/CompileOptions.cmake @@ -0,0 +1,113 @@ +add_library(cae-compile-options INTERFACE) + +target_compile_features(cae-compile-options INTERFACE cxx_std_23) + +option(CAE_STRICT_WARNINGS "Enable strict warning level" OFF) +option(CAE_ENABLE_SANITIZERS "Enable address and undefined sanitizers" OFF) +option(CAE_ENABLE_LTO "Enable LTO on final targets" OFF) + +target_compile_options(cae-compile-options INTERFACE + # Strict warnings + $<$,$,$>>: + -Wall + -Wextra + -Wpedantic + -Wshadow + -Wconversion + -Wsign-conversion + -Wold-style-cast + -Woverloaded-virtual + -Wnull-dereference + -Wformat=2 + -Wundef + -Wswitch-default + > + # mobile / web + $<$,$,$>: + -Wall + -Wextra + -Wshadow + -Wsign-conversion + -Wold-style-cast + > + # Default warnings + $<$,$>>: + -Wall + -Wextra + > + # MSVC + $<$: + /W4 + /permissive- + /Zc:__cplusplus + /Zc:preprocessor + > +) + +# GCC / Clang +target_compile_options(cae-compile-options INTERFACE + $<$,$>:-O2> + $<$,$>:-O0 -g> +) + +# MSVC +target_compile_options(cae-compile-options INTERFACE + $<$,$>:/O2> + $<$,$>:/O2 /Zi> + $<$,$>:/Od /Zi> +) + +target_compile_definitions(cae-compile-options INTERFACE + $<$: + CAE_DEBUG + > +) + +if(CAE_ENABLE_SANITIZERS) + target_compile_options(cae-compile-options INTERFACE + $<$,$>>: + -fsanitize=address,undefined + > + ) + target_link_options(cae-compile-options INTERFACE + $<$,$>>: + -fsanitize=address,undefined + > + ) +endif() + +function(cae_enable_lto target) + if (CAE_ENABLE_LTO) + include(CheckIPOSupported) + check_ipo_supported(RESULT CAE_LTO_SUPPORTED OUTPUT CAE_LTO_ERROR) + if (CAE_LTO_SUPPORTED) + set_property(TARGET ${target} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) + else() + message(WARNING "CAE: LTO not supported: ${CAE_LTO_ERROR}") + endif() + endif() +endfunction() + +if (EMSCRIPTEN) + target_compile_definitions(cae-compile-options INTERFACE + CAE_PLATFORM_WEB + CAE_PLATFORM_EMSCRIPTEN + ) +elseif (ANDROID) + target_compile_definitions(cae-compile-options INTERFACE CAE_PLATFORM_ANDROID) +elseif (APPLE) + if (IOS) + target_compile_definitions(cae-compile-options INTERFACE CAE_PLATFORM_IOS) + else() + target_compile_definitions(cae-compile-options INTERFACE CAE_PLATFORM_MACOS) + endif() +elseif (WIN32) + target_compile_definitions(cae-compile-options INTERFACE + CAE_PLATFORM_WINDOWS + NOMINMAX + WIN32_LEAN_AND_MEAN + ) +elseif (UNIX) + target_compile_definitions(cae-compile-options INTERFACE CAE_PLATFORM_LINUX) +endif() + diff --git a/include/CAE/Common.hpp b/include/CAE/Common.hpp index e5547b4..934e0c6 100644 --- a/include/CAE/Common.hpp +++ b/include/CAE/Common.hpp @@ -6,7 +6,7 @@ #pragma once -#include "CAE/Generated/Version.hpp" +#include "CAE/Version.hpp" #include "Engine/Common.hpp" diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 60e8e7f..44f2461 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -6,6 +6,7 @@ add_subdirectory(Engine) target_link_libraries(cae-modules INTERFACE cae-utils cae-engine + cae-compile-options ) target_include_directories(cae-modules SYSTEM INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/Interfaces/include" diff --git a/modules/Engine/CMakeLists.txt b/modules/Engine/CMakeLists.txt index cca2c57..138bbf4 100644 --- a/modules/Engine/CMakeLists.txt +++ b/modules/Engine/CMakeLists.txt @@ -21,6 +21,7 @@ target_sources(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE cae-utils + cae-compile-options glm::glm ) target_include_directories(${PROJECT_NAME} @@ -32,8 +33,6 @@ target_include_directories(${PROJECT_NAME} "${CMAKE_SOURCE_DIR}/modules/Interfaces/include" ) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON CXX_EXTENSIONS OFF diff --git a/modules/Utils/CMakeLists.txt b/modules/Utils/CMakeLists.txt index af82eb4..0add7fe 100644 --- a/modules/Utils/CMakeLists.txt +++ b/modules/Utils/CMakeLists.txt @@ -29,6 +29,10 @@ target_sources(${PROJECT_NAME} FILES ${HEADERS} ) +target_link_libraries(${PROJECT_NAME} PRIVATE + cae-compile-options +) + target_include_directories(${PROJECT_NAME} PUBLIC $ @@ -36,8 +40,6 @@ target_include_directories(${PROJECT_NAME} PRIVATE $ ) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON CXX_EXTENSIONS OFF diff --git a/plugins/Renderer/OpenGL/CMakeLists.txt b/plugins/Renderer/OpenGL/CMakeLists.txt index 38885b2..a395d0f 100644 --- a/plugins/Renderer/OpenGL/CMakeLists.txt +++ b/plugins/Renderer/OpenGL/CMakeLists.txt @@ -55,8 +55,6 @@ elseif (APPLE) endif () target_link_libraries(${PROJECT_NAME} PRIVATE ${PLATFORM_LIBS}) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) set_target_properties(${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${PLUGIN_DIR}" RUNTIME_OUTPUT_DIRECTORY "${PLUGIN_DIR}" diff --git a/plugins/Renderer/OpenGL/src/context/WGLContext.cpp b/plugins/Renderer/OpenGL/src/context/WGLContext.cpp index 57c2b33..fb0f146 100644 --- a/plugins/Renderer/OpenGL/src/context/WGLContext.cpp +++ b/plugins/Renderer/OpenGL/src/context/WGLContext.cpp @@ -4,8 +4,6 @@ #include "Utils/Logger.hpp" -#include - #include typedef HGLRC(WINAPI *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int *); @@ -67,8 +65,9 @@ void cae::WGLContext::initialize(const NativeWindowHandle &window) { m_hwnd = static_cast(window.window); m_hdc = GetDC(m_hwnd); - if (m_hdc == nullptr) + if (m_hdc == nullptr) { throw std::runtime_error("Failed to get HDC from HWND"); + } PIXELFORMATDESCRIPTOR pfd{}; pfd.nSize = sizeof(pfd); @@ -90,10 +89,12 @@ void cae::WGLContext::initialize(const NativeWindowHandle &window) } const HGLRC tempContext = wglCreateContext(m_hdc); - if (tempContext == nullptr) + if (tempContext == nullptr) { throw std::runtime_error("Failed to create temporary WGL context"); - if (wglMakeCurrent(m_hdc, tempContext) == 0) + } + if (wglMakeCurrent(m_hdc, tempContext) == 0) { throw std::runtime_error("Failed to make temporary context current"); + } const auto wglCreateContextAttribsARB = reinterpret_cast(wglGetProcAddress("wglCreateContextAttribsARB")); @@ -142,10 +143,11 @@ void cae::WGLContext::initialize(const NativeWindowHandle &window) if (gl.Enable != nullptr) { gl.Enable(GL_DEBUG_OUTPUT); +#ifdef CAE_DEBUG gl.DebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) - { utl::Logger::log("[GL DEBUG] " + std::string(message), utl::LogLevel::WARNING); }, - nullptr); + { utl::Logger::log("[GL DEBUG] " + std::string(message), utl::LogLevel::WARNING); }, nullptr); +#endif } } diff --git a/plugins/Renderer/Vulkan/CMakeLists.txt b/plugins/Renderer/Vulkan/CMakeLists.txt index 08823b1..a863d67 100644 --- a/plugins/Renderer/Vulkan/CMakeLists.txt +++ b/plugins/Renderer/Vulkan/CMakeLists.txt @@ -40,8 +40,6 @@ target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ${Vulkan_INCLUDE_DIRS} ) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules ${Vulkan_LIBRARIES} diff --git a/plugins/Shader/Frontend/GLSL/CMakeLists.txt b/plugins/Shader/Frontend/GLSL/CMakeLists.txt index 92170d9..201c203 100644 --- a/plugins/Shader/Frontend/GLSL/CMakeLists.txt +++ b/plugins/Shader/Frontend/GLSL/CMakeLists.txt @@ -12,6 +12,7 @@ if (NOT glslang_FOUND) set(ENABLE_SPIRV ON CACHE BOOL "" FORCE) set(ENABLE_GLSLANG_BINARIES ON CACHE BOOL "" FORCE) set(GLSLANG_TESTS OFF CACHE BOOL "" FORCE) + set(ENABLE_PCH ON CACHE BOOL "" FORCE) FetchContent_Declare( glslang GIT_REPOSITORY "https://github.com/KhronosGroup/glslang.git" @@ -29,8 +30,6 @@ add_library(${PROJECT_NAME} SHARED ${SOURCES}) target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules glslang::glslang diff --git a/plugins/Shader/Frontend/HLSL/CMakeLists.txt b/plugins/Shader/Frontend/HLSL/CMakeLists.txt index 69c24a2..2968a32 100644 --- a/plugins/Shader/Frontend/HLSL/CMakeLists.txt +++ b/plugins/Shader/Frontend/HLSL/CMakeLists.txt @@ -10,8 +10,6 @@ add_library(${PROJECT_NAME} SHARED ${SOURCES}) target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules ) diff --git a/plugins/Shader/Frontend/MSL/CMakeLists.txt b/plugins/Shader/Frontend/MSL/CMakeLists.txt index b226d8a..084f52a 100644 --- a/plugins/Shader/Frontend/MSL/CMakeLists.txt +++ b/plugins/Shader/Frontend/MSL/CMakeLists.txt @@ -10,8 +10,6 @@ add_library(${PROJECT_NAME} SHARED ${SOURCES}) target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules ) diff --git a/plugins/Shader/Frontend/WGSL/CMakeLists.txt b/plugins/Shader/Frontend/WGSL/CMakeLists.txt index 7c455b2..ac47e38 100644 --- a/plugins/Shader/Frontend/WGSL/CMakeLists.txt +++ b/plugins/Shader/Frontend/WGSL/CMakeLists.txt @@ -10,8 +10,6 @@ add_library(${PROJECT_NAME} SHARED ${SOURCES}) target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules ) diff --git a/plugins/Shader/IR/DXC/CMakeLists.txt b/plugins/Shader/IR/DXC/CMakeLists.txt index 1a2f962..71f7eae 100644 --- a/plugins/Shader/IR/DXC/CMakeLists.txt +++ b/plugins/Shader/IR/DXC/CMakeLists.txt @@ -10,8 +10,6 @@ add_library(${PROJECT_NAME} SHARED ${SOURCES}) target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules ) diff --git a/plugins/Shader/IR/SPIRV/CMakeLists.txt b/plugins/Shader/IR/SPIRV/CMakeLists.txt index 1d7d3ec..c4877b5 100644 --- a/plugins/Shader/IR/SPIRV/CMakeLists.txt +++ b/plugins/Shader/IR/SPIRV/CMakeLists.txt @@ -82,8 +82,6 @@ target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules ${SPIRV_CROSS_LIBS} ) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) set_target_properties(${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${PLUGIN_DIR}" RUNTIME_OUTPUT_DIRECTORY "${PLUGIN_DIR}" diff --git a/plugins/Window/Cocoa/CMakeLists.txt b/plugins/Window/Cocoa/CMakeLists.txt index eac2724..edbdaf0 100644 --- a/plugins/Window/Cocoa/CMakeLists.txt +++ b/plugins/Window/Cocoa/CMakeLists.txt @@ -17,8 +17,6 @@ add_library(${PROJECT_NAME} SHARED ${SOURCES}) target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules "-framework Cocoa" diff --git a/plugins/Window/GLFW/CMakeLists.txt b/plugins/Window/GLFW/CMakeLists.txt index 56ba02e..eb241ce 100644 --- a/plugins/Window/GLFW/CMakeLists.txt +++ b/plugins/Window/GLFW/CMakeLists.txt @@ -44,8 +44,6 @@ target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ${GLFW_INCLUDE_DIR} ) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules ${GLFW_LIB} diff --git a/plugins/Window/Win32/CMakeLists.txt b/plugins/Window/Win32/CMakeLists.txt index 8b00dc6..77a22d2 100644 --- a/plugins/Window/Win32/CMakeLists.txt +++ b/plugins/Window/Win32/CMakeLists.txt @@ -4,7 +4,7 @@ project(cae-window-win32 ) if (NOT WIN32) - message(WARNING "${PROJECT_NAME} can only be build on windows") + message(WARNING "${PROJECT_NAME} can only be build on Windows") return() endif () @@ -26,8 +26,6 @@ file(GLOB_RECURSE SOURCE "${PROJECT_SOURCE_DIR}/src/*.cpp") add_library(${PROJECT_NAME} SHARED ${SOURCE}) target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include") -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules ${USER32_LIB} diff --git a/plugins/Window/X11/CMakeLists.txt b/plugins/Window/X11/CMakeLists.txt index 24f1eee..008bcd9 100644 --- a/plugins/Window/X11/CMakeLists.txt +++ b/plugins/Window/X11/CMakeLists.txt @@ -3,6 +3,11 @@ project(cae-window-x11 LANGUAGES C CXX ) +if (NOT LINUX) + message(WARNING "${PROJECT_NAME} can only be build on Linux") + return() +endif () + find_package(X11) if (NOT X11_FOUND) message(WARNING "X11 not found, skipping ${PROJECT_NAME} build") @@ -17,8 +22,6 @@ target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" ${X11_INCLUDE_DIR} ) -target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS}) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) target_link_libraries(${PROJECT_NAME} PRIVATE cae-modules ${X11_LIBRARIES} diff --git a/plugins/Window/X11/include/X11/X11.hpp b/plugins/Window/X11/include/X11/X11.hpp index b9b1129..b23ccf5 100644 --- a/plugins/Window/X11/include/X11/X11.hpp +++ b/plugins/Window/X11/include/X11/X11.hpp @@ -6,7 +6,7 @@ #pragma once -#ifdef __unix__ +#ifdef __linux__ #include "Interfaces/Window/AWindow.hpp" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 86b8fbc..7eb2560 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -20,11 +20,10 @@ if (BUILD_CAE_TESTS) add_executable(${PROJECT_NAME} ${SOURCES}) - target_link_libraries(${PROJECT_NAME} PRIVATE GTest::gtest_main) + target_link_libraries(${PROJECT_NAME} PRIVATE GTest::gtest_main cae-compile-options) target_include_directories(${PROJECT_NAME} PRIVATE ${INCLUDE_DIR}) include(GoogleTest) gtest_discover_tests(${PROJECT_NAME}) - target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) set_property(TARGET ${PROJECT_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON) endif() From 09f23533838b591a85087ab7c22033e20e2ab31b Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Wed, 21 Jan 2026 10:20:50 +0100 Subject: [PATCH 19/20] Refactor: format --- modules/Engine/include/Engine/Camera.hpp | 13 ++++---- modules/Engine/src/engine.cpp | 4 +-- modules/Utils/include/Utils/Path.hpp | 3 +- modules/Utils/include/Utils/PluginLoader.hpp | 1 - .../OpenGL/src/context/WGLContext.cpp | 12 ++++--- plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp | 16 ++++----- plugins/Window/GLFW/src/glfw.cpp | 33 ++++++++++++------- plugins/Window/Win32/src/win32.cpp | 10 +++--- plugins/Window/X11/src/x11.cpp | 2 +- src/application.cpp | 5 +-- 10 files changed, 58 insertions(+), 41 deletions(-) diff --git a/modules/Engine/include/Engine/Camera.hpp b/modules/Engine/include/Engine/Camera.hpp index 42aed98..cef7348 100644 --- a/modules/Engine/include/Engine/Camera.hpp +++ b/modules/Engine/include/Engine/Camera.hpp @@ -23,13 +23,14 @@ namespace cae class Camera { public: - Camera(const glm::vec3 position, const glm::vec3 rotation, const glm::vec3 direction, const float moveSpeed = CAMERA::MOVE_SPEED, - const float lookSpeed = CAMERA::LOOK_SPEED, const float fov = CAMERA::FOV, const float nearPlane = CAMERA::NEAR_PLANE, - const float farPlane = CAMERA::FAR_PLANE) + Camera(const glm::vec3 position, const glm::vec3 rotation, const glm::vec3 direction, + const float moveSpeed = CAMERA::MOVE_SPEED, const float lookSpeed = CAMERA::LOOK_SPEED, + const float fov = CAMERA::FOV, const float nearPlane = CAMERA::NEAR_PLANE, + const float farPlane = CAMERA::FAR_PLANE) : m_position(position), m_rotation(rotation), m_direction(direction), m_moveSpeed(moveSpeed), - m_lookSpeed(lookSpeed), m_fov(fov), m_near(nearPlane), m_far(farPlane) - { - } + m_lookSpeed(lookSpeed), m_fov(fov), m_near(nearPlane), m_far(farPlane) + { + } ~Camera() = default; Camera(const Camera &) = delete; diff --git a/modules/Engine/src/engine.cpp b/modules/Engine/src/engine.cpp index 3d03de9..4268adf 100644 --- a/modules/Engine/src/engine.cpp +++ b/modules/Engine/src/engine.cpp @@ -64,8 +64,8 @@ void cae::Engine::render() constexpr auto model = glm::mat4(1.0F); const glm::mat4 mvp = m_camera->getViewProjection(static_cast(m_windowPlugin->getWindowSize().width) / - m_windowPlugin->getWindowSize().height) * - model; + m_windowPlugin->getWindowSize().height) * + model; m_rendererPlugin->draw(m_windowPlugin->getWindowSize(), "basic", mvp); } diff --git a/modules/Utils/include/Utils/Path.hpp b/modules/Utils/include/Utils/Path.hpp index aa49f38..461c4ff 100644 --- a/modules/Utils/include/Utils/Path.hpp +++ b/modules/Utils/include/Utils/Path.hpp @@ -128,7 +128,8 @@ namespace utl /// @return Resolved path relative to the user cwd /// @brief /// - static fs::path resolveRelativeToCwd(const fs::path& relativePath) { + static fs::path resolveRelativeToCwd(const fs::path &relativePath) + { return normalize(fs::current_path() / relativePath); } diff --git a/modules/Utils/include/Utils/PluginLoader.hpp b/modules/Utils/include/Utils/PluginLoader.hpp index f8582cf..e550965 100644 --- a/modules/Utils/include/Utils/PluginLoader.hpp +++ b/modules/Utils/include/Utils/PluginLoader.hpp @@ -143,7 +143,6 @@ namespace utl } catch (const std::exception &e) { - throw std::runtime_error(std::string("Unknown exception: ") + e.what()); return nullptr; } } diff --git a/plugins/Renderer/OpenGL/src/context/WGLContext.cpp b/plugins/Renderer/OpenGL/src/context/WGLContext.cpp index fb0f146..f5fa8d8 100644 --- a/plugins/Renderer/OpenGL/src/context/WGLContext.cpp +++ b/plugins/Renderer/OpenGL/src/context/WGLContext.cpp @@ -65,7 +65,8 @@ void cae::WGLContext::initialize(const NativeWindowHandle &window) { m_hwnd = static_cast(window.window); m_hdc = GetDC(m_hwnd); - if (m_hdc == nullptr) { + if (m_hdc == nullptr) + { throw std::runtime_error("Failed to get HDC from HWND"); } @@ -89,10 +90,12 @@ void cae::WGLContext::initialize(const NativeWindowHandle &window) } const HGLRC tempContext = wglCreateContext(m_hdc); - if (tempContext == nullptr) { + if (tempContext == nullptr) + { throw std::runtime_error("Failed to create temporary WGL context"); } - if (wglMakeCurrent(m_hdc, tempContext) == 0) { + if (wglMakeCurrent(m_hdc, tempContext) == 0) + { throw std::runtime_error("Failed to make temporary context current"); } @@ -146,7 +149,8 @@ void cae::WGLContext::initialize(const NativeWindowHandle &window) #ifdef CAE_DEBUG gl.DebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) - { utl::Logger::log("[GL DEBUG] " + std::string(message), utl::LogLevel::WARNING); }, nullptr); + { utl::Logger::log("[GL DEBUG] " + std::string(message), utl::LogLevel::WARNING); }, + nullptr); #endif } } diff --git a/plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp b/plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp index dd308ba..ae9f8d7 100644 --- a/plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp +++ b/plugins/Window/Cocoa/include/Cocoa/Cocoa.hpp @@ -26,32 +26,32 @@ namespace cae Cocoa() = default; ~Cocoa() override; - Cocoa(const Cocoa&) = delete; - Cocoa& operator=(const Cocoa&) = delete; + Cocoa(const Cocoa &) = delete; + Cocoa &operator=(const Cocoa &) = delete; [[nodiscard]] std::string getName() const override { return "Cocoa"; } [[nodiscard]] utl::PluginType getType() const override { return utl::PluginType::WINDOW; } [[nodiscard]] utl::PluginPlatform getPlatform() const override { return utl::PluginPlatform::MACOSX; } - bool create(const std::string& name, WindowSize size) override; + bool create(const std::string &name, WindowSize size) override; void close() override; [[nodiscard]] NativeWindowHandle getNativeHandle() const override; [[nodiscard]] WindowSize getWindowSize() const override; - void setIcon(const std::string &path) const override {} + void setIcon(const std::string &path) const override {} [[nodiscard]] bool shouldClose() const override; void pollEvents() override; - bool pollEvent(WindowEvent& event) override; + bool pollEvent(WindowEvent &event) override; [[nodiscard]] bool wasResized() const override { return m_resized; } void resetResizedFlag() override { m_resized = false; } private: - void* m_window = nullptr; // NSWindow* - void* m_view = nullptr; // NSView* - void* m_app = nullptr; // NSApplication* + void *m_window = nullptr; // NSWindow* + void *m_view = nullptr; // NSView* + void *m_app = nullptr; // NSApplication* bool m_shouldClose = false; bool m_resized = false; diff --git a/plugins/Window/GLFW/src/glfw.cpp b/plugins/Window/GLFW/src/glfw.cpp index 9aaab49..f687fb6 100644 --- a/plugins/Window/GLFW/src/glfw.cpp +++ b/plugins/Window/GLFW/src/glfw.cpp @@ -68,16 +68,22 @@ static cae::KeyCode translateKey(const int key) void cae::GLFW::keyCallback(GLFWwindow *window, const int key, int, const int action, int) { auto *self = static_cast(glfwGetWindowUserPointer(window)); - if (self == nullptr) { + if (self == nullptr) + { return; } WindowEvent e{}; - if (action == GLFW_PRESS) { + if (action == GLFW_PRESS) + { e.type = WindowEventType::KeyDown; - } else if (action == GLFW_RELEASE) { + } + else if (action == GLFW_RELEASE) + { e.type = WindowEventType::KeyUp; - } else { + } + else + { return; } @@ -88,7 +94,8 @@ void cae::GLFW::keyCallback(GLFWwindow *window, const int key, int, const int ac void cae::GLFW::mouseButtonCallback(GLFWwindow *window, int button, const int action, int) { auto *self = static_cast(glfwGetWindowUserPointer(window)); - if (self == nullptr) { + if (self == nullptr) + { return; } @@ -102,7 +109,8 @@ void cae::GLFW::mouseButtonCallback(GLFWwindow *window, int button, const int ac void cae::GLFW::cursorPosCallback(GLFWwindow *window, const double x, const double y) { auto *self = static_cast(glfwGetWindowUserPointer(window)); - if (self == nullptr) { + if (self == nullptr) + { return; } @@ -117,7 +125,8 @@ void cae::GLFW::cursorPosCallback(GLFWwindow *window, const double x, const doub void cae::GLFW::scrollCallback(GLFWwindow *window, const double xoffset, const double yoffset) { auto *self = static_cast(glfwGetWindowUserPointer(window)); - if (self == nullptr) { + if (self == nullptr) + { return; } @@ -132,12 +141,13 @@ void cae::GLFW::scrollCallback(GLFWwindow *window, const double xoffset, const d void cae::GLFW::frameBufferResizeCallback(GLFWwindow *window, const int width, const int height) { auto *self = static_cast(glfwGetWindowUserPointer(window)); - if (self == nullptr) { + if (self == nullptr) + { return; } self->m_frameBufferResized = true; - self->m_frameBufferSize = {.width=static_cast(width), .height=static_cast(height)}; + self->m_frameBufferSize = {.width = static_cast(width), .height = static_cast(height)}; WindowEvent e{}; e.type = WindowEventType::Resize; @@ -176,7 +186,7 @@ bool cae::GLFW::create(const std::string &name, const WindowSize size) glfwSetCursorPosCallback(m_window, cursorPosCallback); glfwSetScrollCallback(m_window, scrollCallback); #ifdef __APPLE__ - glfwMakeContextCurrent((GLFWwindow*)m_window); + glfwMakeContextCurrent((GLFWwindow *)m_window); #endif return true; } @@ -229,7 +239,8 @@ void cae::GLFW::setIcon(const std::string &path) const bool cae::GLFW::pollEvent(WindowEvent &event) { - if (m_eventQueue.empty()) { + if (m_eventQueue.empty()) + { return false; } diff --git a/plugins/Window/Win32/src/win32.cpp b/plugins/Window/Win32/src/win32.cpp index 686395f..304195c 100644 --- a/plugins/Window/Win32/src/win32.cpp +++ b/plugins/Window/Win32/src/win32.cpp @@ -87,9 +87,10 @@ LRESULT CALLBACK cae::Win32::WindowProc(const HWND hwnd, const UINT msg, const W } self = reinterpret_cast(GetWindowLongPtrW(hwnd, GWLP_USERDATA)); - if (self == nullptr) { + if (self == nullptr) + { return DefWindowProcW(hwnd, msg, wParam, lParam); -} + } WindowEvent e{}; switch (msg) @@ -98,7 +99,7 @@ LRESULT CALLBACK cae::Win32::WindowProc(const HWND hwnd, const UINT msg, const W self->m_frameBufferResized = true; self->m_frameBufferSize = {.width = LOWORD(lParam), .height = HIWORD(lParam)}; e.type = WindowEventType::Resize; - e.resize = {.w=LOWORD(lParam), .h=HIWORD(lParam)}; + e.resize = {.w = LOWORD(lParam), .h = HIWORD(lParam)}; self->m_eventQueue.push(e); return 0; @@ -205,7 +206,7 @@ void cae::Win32::setIcon(const std::string &path) const { const utl::Image image(path); - for (size_t i = 0; std::cmp_less(i ,image.width * image.height); ++i) + for (size_t i = 0; std::cmp_less(i, image.width * image.height); ++i) { std::swap(image.pixels[(i * 4) + 0], image.pixels[(i * 4) + 2]); } @@ -255,7 +256,6 @@ void cae::Win32::setIcon(const std::string &path) const SendMessageW(m_hwnd, WM_SETICON, ICON_BIG, reinterpret_cast(hIcon)); SendMessageW(m_hwnd, WM_SETICON, ICON_SMALL, reinterpret_cast(hIcon)); - } catch (const std::exception &e) { diff --git a/plugins/Window/X11/src/x11.cpp b/plugins/Window/X11/src/x11.cpp index f3f1fa2..c7c055c 100644 --- a/plugins/Window/X11/src/x11.cpp +++ b/plugins/Window/X11/src/x11.cpp @@ -118,7 +118,7 @@ void cae::X11::setIcon(const std::string &path) const { const utl::Image image(path); - const auto pixelCount = static_cast(image.width * image.height); + const auto pixelCount = image.width * image.height; std::vector iconData; iconData.reserve(2 + pixelCount); diff --git a/src/application.cpp b/src/application.cpp index bd2019a..81401e7 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -211,7 +211,8 @@ void cae::Application::mainLoop() m_engine->getCamera()->rotate(lookDir.x, lookDir.y, 1.0F); } - glm::vec3 forward = glm::normalize(glm::vec3(m_engine->getCamera()->getDirection().x, 0.0F, m_engine->getCamera()->getDirection().z)); + glm::vec3 forward = glm::normalize( + glm::vec3(m_engine->getCamera()->getDirection().x, 0.0F, m_engine->getCamera()->getDirection().z)); glm::vec3 right = glm::normalize(glm::cross(forward, glm::vec3(0.0F, 1.0F, 0.0F))); if (m_keyState[KeyCode::W]) @@ -246,6 +247,6 @@ void cae::Application::mainLoop() m_engine->getCamera()->move(glm::vec3(0.0F, 1.0F, 0.0F), m_engine->getClock()->getDeltaSeconds()); } - m_engine->update(fpsBuffer, fpsIndex); + m_engine->update(fpsBuffer, fpsIndex); } } From 247c50ab00f9ac5213a422c4c5f322743b4b22ce Mon Sep 17 00:00:00 2001 From: MASINA Elliot Date: Wed, 21 Jan 2026 10:50:45 +0100 Subject: [PATCH 20/20] Fix: X11 and glfw missing key in keyboard mapping --- .../include/Interfaces/Input/Key/Keyboard.hpp | 4 + plugins/Window/GLFW/src/glfw.cpp | 216 +++++++++++++----- plugins/Window/X11/src/x11.cpp | 209 ++++++++++++++--- 3 files changed, 343 insertions(+), 86 deletions(-) diff --git a/modules/Interfaces/include/Interfaces/Input/Key/Keyboard.hpp b/modules/Interfaces/include/Interfaces/Input/Key/Keyboard.hpp index 8c9f8ea..e118894 100644 --- a/modules/Interfaces/include/Interfaces/Input/Key/Keyboard.hpp +++ b/modules/Interfaces/include/Interfaces/Input/Key/Keyboard.hpp @@ -116,6 +116,10 @@ namespace cae NumLock, ScrollLock, + PrintScreen, + Pause, + Menu, + Count }; } // namespace cae diff --git a/plugins/Window/GLFW/src/glfw.cpp b/plugins/Window/GLFW/src/glfw.cpp index f687fb6..fbf8052 100644 --- a/plugins/Window/GLFW/src/glfw.cpp +++ b/plugins/Window/GLFW/src/glfw.cpp @@ -9,60 +9,168 @@ static cae::KeyCode translateKey(const int key) { - static const std::unordered_map keyMap = { - {GLFW_KEY_A, cae::KeyCode::A}, - {GLFW_KEY_B, cae::KeyCode::B}, - {GLFW_KEY_C, cae::KeyCode::C}, - {GLFW_KEY_D, cae::KeyCode::D}, - {GLFW_KEY_E, cae::KeyCode::E}, - {GLFW_KEY_F, cae::KeyCode::F}, - {GLFW_KEY_G, cae::KeyCode::G}, - {GLFW_KEY_H, cae::KeyCode::H}, - {GLFW_KEY_I, cae::KeyCode::I}, - {GLFW_KEY_J, cae::KeyCode::J}, - {GLFW_KEY_K, cae::KeyCode::K}, - {GLFW_KEY_L, cae::KeyCode::L}, - {GLFW_KEY_M, cae::KeyCode::M}, - {GLFW_KEY_N, cae::KeyCode::N}, - {GLFW_KEY_O, cae::KeyCode::O}, - {GLFW_KEY_P, cae::KeyCode::P}, - {GLFW_KEY_Q, cae::KeyCode::Q}, - {GLFW_KEY_R, cae::KeyCode::R}, - {GLFW_KEY_S, cae::KeyCode::S}, - {GLFW_KEY_T, cae::KeyCode::T}, - {GLFW_KEY_U, cae::KeyCode::U}, - {GLFW_KEY_V, cae::KeyCode::V}, - {GLFW_KEY_W, cae::KeyCode::W}, - {GLFW_KEY_X, cae::KeyCode::X}, - {GLFW_KEY_Y, cae::KeyCode::Y}, - {GLFW_KEY_Z, cae::KeyCode::Z}, - - {GLFW_KEY_0, cae::KeyCode::Num0}, - {GLFW_KEY_1, cae::KeyCode::Num1}, - {GLFW_KEY_2, cae::KeyCode::Num2}, - {GLFW_KEY_3, cae::KeyCode::Num3}, - {GLFW_KEY_4, cae::KeyCode::Num4}, - {GLFW_KEY_5, cae::KeyCode::Num5}, - {GLFW_KEY_6, cae::KeyCode::Num6}, - {GLFW_KEY_7, cae::KeyCode::Num7}, - {GLFW_KEY_8, cae::KeyCode::Num8}, - {GLFW_KEY_9, cae::KeyCode::Num9}, - {GLFW_KEY_ESCAPE, cae::KeyCode::Escape}, - {GLFW_KEY_LEFT, cae::KeyCode::Left}, - {GLFW_KEY_RIGHT, cae::KeyCode::Right}, - {GLFW_KEY_UP, cae::KeyCode::Up}, - {GLFW_KEY_DOWN, cae::KeyCode::Down}, - {GLFW_KEY_SPACE, cae::KeyCode::Space}, - {GLFW_KEY_ENTER, cae::KeyCode::Enter}, - {GLFW_KEY_BACKSPACE, cae::KeyCode::Backspace}, - {GLFW_KEY_TAB, cae::KeyCode::Tab}, - {GLFW_KEY_LEFT_SHIFT, cae::KeyCode::LShift}, - {GLFW_KEY_LEFT_CONTROL, cae::KeyCode::LCtrl}, - {GLFW_KEY_LEFT_ALT, cae::KeyCode::LAlt} - // ... - }; - const auto it = keyMap.find(key); - return it != keyMap.end() ? it->second : cae::KeyCode::Count; + switch (key) + { + case GLFW_KEY_A: + return cae::KeyCode::A; + case GLFW_KEY_B: + return cae::KeyCode::B; + case GLFW_KEY_C: + return cae::KeyCode::C; + case GLFW_KEY_D: + return cae::KeyCode::D; + case GLFW_KEY_E: + return cae::KeyCode::E; + case GLFW_KEY_F: + return cae::KeyCode::F; + case GLFW_KEY_G: + return cae::KeyCode::G; + case GLFW_KEY_H: + return cae::KeyCode::H; + case GLFW_KEY_I: + return cae::KeyCode::I; + case GLFW_KEY_J: + return cae::KeyCode::J; + case GLFW_KEY_K: + return cae::KeyCode::K; + case GLFW_KEY_L: + return cae::KeyCode::L; + case GLFW_KEY_M: + return cae::KeyCode::M; + case GLFW_KEY_N: + return cae::KeyCode::N; + case GLFW_KEY_O: + return cae::KeyCode::O; + case GLFW_KEY_P: + return cae::KeyCode::P; + case GLFW_KEY_Q: + return cae::KeyCode::Q; + case GLFW_KEY_R: + return cae::KeyCode::R; + case GLFW_KEY_S: + return cae::KeyCode::S; + case GLFW_KEY_T: + return cae::KeyCode::T; + case GLFW_KEY_U: + return cae::KeyCode::U; + case GLFW_KEY_V: + return cae::KeyCode::V; + case GLFW_KEY_W: + return cae::KeyCode::W; + case GLFW_KEY_X: + return cae::KeyCode::X; + case GLFW_KEY_Y: + return cae::KeyCode::Y; + case GLFW_KEY_Z: + return cae::KeyCode::Z; + + case GLFW_KEY_0: + return cae::KeyCode::Num0; + case GLFW_KEY_1: + return cae::KeyCode::Num1; + case GLFW_KEY_2: + return cae::KeyCode::Num2; + case GLFW_KEY_3: + return cae::KeyCode::Num3; + case GLFW_KEY_4: + return cae::KeyCode::Num4; + case GLFW_KEY_5: + return cae::KeyCode::Num5; + case GLFW_KEY_6: + return cae::KeyCode::Num6; + case GLFW_KEY_7: + return cae::KeyCode::Num7; + case GLFW_KEY_8: + return cae::KeyCode::Num8; + case GLFW_KEY_9: + return cae::KeyCode::Num9; + + case GLFW_KEY_LEFT_SHIFT: + return cae::KeyCode::LShift; + case GLFW_KEY_RIGHT_SHIFT: + return cae::KeyCode::RShift; + case GLFW_KEY_LEFT_CONTROL: + return cae::KeyCode::LCtrl; + case GLFW_KEY_RIGHT_CONTROL: + return cae::KeyCode::RCtrl; + case GLFW_KEY_LEFT_ALT: + return cae::KeyCode::LAlt; + case GLFW_KEY_RIGHT_ALT: + return cae::KeyCode::RAlt; + case GLFW_KEY_LEFT_SUPER: + return cae::KeyCode::LSuper; + case GLFW_KEY_RIGHT_SUPER: + return cae::KeyCode::RSuper; + case GLFW_KEY_CAPS_LOCK: + return cae::KeyCode::CapsLock; + + case GLFW_KEY_UP: + return cae::KeyCode::Up; + case GLFW_KEY_DOWN: + return cae::KeyCode::Down; + case GLFW_KEY_LEFT: + return cae::KeyCode::Left; + case GLFW_KEY_RIGHT: + return cae::KeyCode::Right; + case GLFW_KEY_HOME: + return cae::KeyCode::Home; + case GLFW_KEY_END: + return cae::KeyCode::End; + case GLFW_KEY_PAGE_UP: + return cae::KeyCode::PageUp; + case GLFW_KEY_PAGE_DOWN: + return cae::KeyCode::PageDown; + + case GLFW_KEY_ENTER: + return cae::KeyCode::Enter; + case GLFW_KEY_BACKSPACE: + return cae::KeyCode::Backspace; + case GLFW_KEY_TAB: + return cae::KeyCode::Tab; + case GLFW_KEY_SPACE: + return cae::KeyCode::Space; + case GLFW_KEY_DELETE: + return cae::KeyCode::Delete; + case GLFW_KEY_INSERT: + return cae::KeyCode::Insert; + + case GLFW_KEY_F1: + return cae::KeyCode::F1; + case GLFW_KEY_F2: + return cae::KeyCode::F2; + case GLFW_KEY_F3: + return cae::KeyCode::F3; + case GLFW_KEY_F4: + return cae::KeyCode::F4; + case GLFW_KEY_F5: + return cae::KeyCode::F5; + case GLFW_KEY_F6: + return cae::KeyCode::F6; + case GLFW_KEY_F7: + return cae::KeyCode::F7; + case GLFW_KEY_F8: + return cae::KeyCode::F8; + case GLFW_KEY_F9: + return cae::KeyCode::F9; + case GLFW_KEY_F10: + return cae::KeyCode::F10; + case GLFW_KEY_F11: + return cae::KeyCode::F11; + case GLFW_KEY_F12: + return cae::KeyCode::F12; + + case GLFW_KEY_ESCAPE: + return cae::KeyCode::Escape; + case GLFW_KEY_PRINT_SCREEN: + return cae::KeyCode::PrintScreen; + case GLFW_KEY_PAUSE: + return cae::KeyCode::Pause; + case GLFW_KEY_MENU: + return cae::KeyCode::Menu; + + default: + return cae::KeyCode::Count; + } } void cae::GLFW::keyCallback(GLFWwindow *window, const int key, int, const int action, int) diff --git a/plugins/Window/X11/src/x11.cpp b/plugins/Window/X11/src/x11.cpp index c7c055c..f4561df 100644 --- a/plugins/Window/X11/src/x11.cpp +++ b/plugins/Window/X11/src/x11.cpp @@ -3,44 +3,179 @@ #include "Utils/Image.hpp" #include "Utils/Logger.hpp" -#include #include +#include +#include #include -static cae::KeyCode translateKeycode(const unsigned int keycode) +static cae::KeyCode translateKeysym(const KeySym sym) { - switch (keycode) + switch (sym) { - case 25: - return cae::KeyCode::W; - case 38: + case XK_a: return cae::KeyCode::A; - case 39: - return cae::KeyCode::S; - case 40: + case XK_b: + return cae::KeyCode::B; + case XK_c: + return cae::KeyCode::C; + case XK_d: return cae::KeyCode::D; - - case 111: + case XK_e: + return cae::KeyCode::E; + case XK_f: + return cae::KeyCode::F; + case XK_g: + return cae::KeyCode::G; + case XK_h: + return cae::KeyCode::H; + case XK_i: + return cae::KeyCode::I; + case XK_j: + return cae::KeyCode::J; + case XK_k: + return cae::KeyCode::K; + case XK_l: + return cae::KeyCode::L; + case XK_m: + return cae::KeyCode::M; + case XK_n: + return cae::KeyCode::N; + case XK_o: + return cae::KeyCode::O; + case XK_p: + return cae::KeyCode::P; + case XK_q: + return cae::KeyCode::Q; + case XK_r: + return cae::KeyCode::R; + case XK_s: + return cae::KeyCode::S; + case XK_t: + return cae::KeyCode::T; + case XK_u: + return cae::KeyCode::U; + case XK_v: + return cae::KeyCode::V; + case XK_w: + return cae::KeyCode::W; + case XK_x: + return cae::KeyCode::X; + case XK_y: + return cae::KeyCode::Y; + case XK_z: + return cae::KeyCode::Z; + + // Numbers + case XK_0: + return cae::KeyCode::Num0; + case XK_1: + return cae::KeyCode::Num1; + case XK_2: + return cae::KeyCode::Num2; + case XK_3: + return cae::KeyCode::Num3; + case XK_4: + return cae::KeyCode::Num4; + case XK_5: + return cae::KeyCode::Num5; + case XK_6: + return cae::KeyCode::Num6; + case XK_7: + return cae::KeyCode::Num7; + case XK_8: + return cae::KeyCode::Num8; + case XK_9: + return cae::KeyCode::Num9; + + // Modifiers + case XK_Shift_L: + return cae::KeyCode::LShift; + case XK_Shift_R: + return cae::KeyCode::RShift; + case XK_Control_L: + return cae::KeyCode::LCtrl; + case XK_Control_R: + return cae::KeyCode::RCtrl; + case XK_Alt_L: + return cae::KeyCode::LAlt; + case XK_Alt_R: + return cae::KeyCode::RAlt; + case XK_Super_L: + return cae::KeyCode::LSuper; + case XK_Super_R: + return cae::KeyCode::RSuper; + case XK_Caps_Lock: + return cae::KeyCode::CapsLock; + + // Navigation + case XK_Up: return cae::KeyCode::Up; - case 116: + case XK_Down: return cae::KeyCode::Down; - case 113: + case XK_Left: return cae::KeyCode::Left; - case 114: + case XK_Right: return cae::KeyCode::Right; - - case 65: + case XK_Home: + return cae::KeyCode::Home; + case XK_End: + return cae::KeyCode::End; + case XK_Page_Up: + return cae::KeyCode::PageUp; + case XK_Page_Down: + return cae::KeyCode::PageDown; + + // Editing + case XK_Return: + return cae::KeyCode::Enter; + case XK_BackSpace: + return cae::KeyCode::Backspace; + case XK_Tab: + return cae::KeyCode::Tab; + case XK_space: return cae::KeyCode::Space; - case 37: - return cae::KeyCode::LCtrl; - case 50: - return cae::KeyCode::LShift; - case 64: - return cae::KeyCode::LAlt; - - case 9: + case XK_Delete: + return cae::KeyCode::Delete; + case XK_Insert: + return cae::KeyCode::Insert; + + // Function keys + case XK_F1: + return cae::KeyCode::F1; + case XK_F2: + return cae::KeyCode::F2; + case XK_F3: + return cae::KeyCode::F3; + case XK_F4: + return cae::KeyCode::F4; + case XK_F5: + return cae::KeyCode::F5; + case XK_F6: + return cae::KeyCode::F6; + case XK_F7: + return cae::KeyCode::F7; + case XK_F8: + return cae::KeyCode::F8; + case XK_F9: + return cae::KeyCode::F9; + case XK_F10: + return cae::KeyCode::F10; + case XK_F11: + return cae::KeyCode::F11; + case XK_F12: + return cae::KeyCode::F12; + + // System + case XK_Escape: return cae::KeyCode::Escape; + case XK_Print: + return cae::KeyCode::PrintScreen; + case XK_Pause: + return cae::KeyCode::Pause; + case XK_Menu: + return cae::KeyCode::Menu; + default: return cae::KeyCode::Count; } @@ -126,12 +261,12 @@ void cae::X11::setIcon(const std::string &path) const iconData.push_back(static_cast(image.height)); const uint8_t *pixels = image.pixels; - for (size_t i = 0; i < pixelCount; ++i) + for (size_t i = 0; std::cmp_less(i, pixelCount); ++i) { - const uint8_t r = pixels[i * 4 + 0]; - const uint8_t g = pixels[i * 4 + 1]; - const uint8_t b = pixels[i * 4 + 2]; - const uint8_t a = pixels[i * 4 + 3]; + const uint8_t r = pixels[(i * 4) + 0]; + const uint8_t g = pixels[(i * 4) + 1]; + const uint8_t b = pixels[(i * 4) + 2]; + const uint8_t a = pixels[(i * 4) + 3]; const unsigned long argb = (static_cast(a) << 24) | (static_cast(r) << 16) | (static_cast(g) << 8) | (static_cast(b)); @@ -173,16 +308,26 @@ bool cae::X11::pollEvent(WindowEvent &outEvent) switch (event.type) { case KeyPress: + { e.type = WindowEventType::KeyDown; - e.key.key = translateKeycode(event.xkey.keycode); + + const KeySym sym = XkbKeycodeToKeysym(m_display, event.xkey.keycode, 0, 0); + + e.key.key = translateKeysym(sym); m_eventQueue.push(e); break; + } case KeyRelease: + { e.type = WindowEventType::KeyUp; - e.key.key = translateKeycode(event.xkey.keycode); + + const KeySym sym = XkbKeycodeToKeysym(m_display, event.xkey.keycode, 0, 0); + + e.key.key = translateKeysym(sym); m_eventQueue.push(e); break; + } case ConfigureNotify: m_frameBufferResized = true; @@ -195,7 +340,7 @@ bool cae::X11::pollEvent(WindowEvent &outEvent) break; case ClientMessage: - if (static_cast(event.xclient.data.l[0]) == m_wmDeleteMessage) + if (std::cmp_equal(event.xclient.data.l[0], m_wmDeleteMessage)) { m_shouldClose = true; e.type = WindowEventType::Close;