diff --git a/.clang-tidy b/.clang-tidy index 1346ff1..1007bc7 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -11,6 +11,7 @@ Checks: > -cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-owning-memory, -cppcoreguidelines-pro-type-member-init, + -cppcoreguidelines-pro-type-union-access, -cppcoreguidelines-pro-type-vararg, -fuchsia-*, -google-*, diff --git a/flake.lock b/flake.lock index 05beee3..c1279ff 100644 --- a/flake.lock +++ b/flake.lock @@ -22,11 +22,11 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1729779640, - "narHash": "sha256-M9t4Ta9d76aVqd1mkLBl8zFSWYc8pv6AZTy1SU5bVp0=", + "lastModified": 1731536673, + "narHash": "sha256-bEkcE98/AwmKzlipCruFdf3KK3CBmtfzabquHtrKURM=", "owner": "zzywysm", "repo": "nixos-asahi", - "rev": "5f8823f3543cbf9566d5af49b3a3c18539681eac", + "rev": "09d4e26b7d49323faad37264763cf57988cfd720", "type": "github" }, "original": { @@ -37,11 +37,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1725103162, - "narHash": "sha256-Ym04C5+qovuQDYL/rKWSR+WESseQBbNAe5DsXNx5trY=", + "lastModified": 1731139594, + "narHash": "sha256-IigrKK3vYRpUu+HEjPL/phrfh7Ox881er1UEsZvw9Q4=", "owner": "nixos", "repo": "nixpkgs", - "rev": "12228ff1752d7b7624a54e9c1af4b222b3c1073b", + "rev": "76612b17c0ce71689921ca12d9ffdc9c23ce40b2", "type": "github" }, "original": { @@ -53,11 +53,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1730949988, - "narHash": "sha256-7AcEfVr+td+fRqFWZzqn1XbzhEYvotOAfyWLgVSoY70=", + "lastModified": 1731640008, + "narHash": "sha256-81hruQPQXZf1xtcyYct9XPvBWvKIk6/DSDCc5XcYKT4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5ed245d62a75ca9fc939b6fffe72af0e22ab8260", + "rev": "63de88ed5f65084bb5cde3bdcb716e28cc03a933", "type": "github" }, "original": { @@ -144,11 +144,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1726560853, - "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { diff --git a/src/main.cpp b/src/main.cpp index dea1277..f360294 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ // Include necessary headers +#include #include // For time-related functions #include // For string formatting #include // For shader compilation @@ -247,28 +248,69 @@ class VulkanApp { struct Camera { glm::dvec3 position; + glm::dvec3 front; glm::dvec3 up; - glm::dvec3 look_at; + glm::dvec3 right; + double yaw; + double pitch; - Camera() : position(2.0, 2.0, 2.0), up(0.0, 0.0, 1.0), look_at(0.0) {} + Camera() + : position(2.0, 2.0, 2.0), + front(glm::normalize(glm::dvec3(-2.0, -2.0, -2.0))), + up(0.0, 0.0, 1.0), + right(glm::normalize(glm::cross(front, up))), + yaw(-135.0) // -135 degrees to match the initial front vector + , + pitch(-35.26) // -35.26 degrees to match the initial front vector + { + updateCameraVectors(); + } [[nodiscard]] fn getPosition() const -> glm::dvec3 { return position; } - [[nodiscard]] fn getViewMatrix() const -> glm::mat4 { return glm::lookAt(position, look_at, up); } - - fn moveForward(f64 deltaTime) -> void { position += (look_at - position) * CAMERA_SPEED * deltaTime; } - - fn moveBackward(f64 deltaTime) -> void { position -= (look_at - position) * CAMERA_SPEED * deltaTime; } - - fn moveLeft(f64 deltaTime) -> void { - position -= glm::normalize(glm::cross((look_at - position), up)) * CAMERA_SPEED * deltaTime; + [[nodiscard]] fn getViewMatrix() const -> glm::mat4 { + return glm::lookAt(position, position + front, up); } - fn moveRight(f64 deltaTime) -> void { - position += glm::normalize(glm::cross((look_at - position), up)) * CAMERA_SPEED * deltaTime; + fn moveForward(f64 deltaTime) -> void { position += front * CAMERA_SPEED * deltaTime; } + + fn moveBackward(f64 deltaTime) -> void { position -= front * CAMERA_SPEED * deltaTime; } + + fn moveLeft(f64 deltaTime) -> void { position -= right * CAMERA_SPEED * deltaTime; } + + fn moveRight(f64 deltaTime) -> void { position += right * CAMERA_SPEED * deltaTime; } + + fn rotate(double xoffset, double yoffset) -> void { + const double sensitivity = 0.1; + yaw += xoffset * sensitivity; + pitch += yoffset * sensitivity; + + // Constrain pitch to avoid camera flipping + if (pitch > 89.0) + pitch = 89.0; + if (pitch < -89.0) + pitch = -89.0; + + updateCameraVectors(); + } + + private: + fn updateCameraVectors() -> void { + // Calculate new front vector + glm::dvec3 newFront; + newFront.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch)); + newFront.y = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); + newFront.z = sin(glm::radians(pitch)); + + front = glm::normalize(newFront); + // Recalculate right and up vectors + right = glm::normalize(glm::cross(front, glm::dvec3(0.0, 0.0, 1.0))); + up = glm::normalize(glm::cross(right, front)); } }; + Camera mCamera; ///< Camera object + static fn processInput(vkfw::Window& window, Camera& camera, const f64& deltaTime) -> void { if (window.getKey(vkfw::Key::eW) == vkfw::eTrue) camera.moveForward(deltaTime); @@ -284,34 +326,30 @@ class VulkanApp { ); } - /** - * @brief Update the FPS counter in the window title. - * - * @param window The window to update. - * @param baseTitle The base title string to prepend the FPS to. - * - * This function updates the window title with the current frames per second. - */ - static fn updateFPS(const vkfw::Window& window, const string& baseTitle) -> void { - static u32 FrameCount = 0; - static f64 LastTime = glfwGetTime(); - static f64 Fps = 0.0; + // static fn mouseCallback(const vkfw::Window& window, double xpos, double ypos) -> void { + // auto& camera = *static_cast(window.getUserPointer()); - // Get the current time - f64 currentTime = glfwGetTime(); - FrameCount++; + // static struct { + // bool first_mouse = true; + // double last_x = WIDTH / 2.0; + // double last_y = HEIGHT / 2.0; + // } MouseState; - // If one second has passed, calculate the FPS - if (currentTime - LastTime >= 0.1) { - Fps = FrameCount / (currentTime - LastTime); - LastTime = currentTime; - FrameCount = 0; + // if (MouseState.first_mouse) { + // MouseState.last_x = xpos; + // MouseState.last_y = ypos; + // MouseState.first_mouse = false; + // return; + // } - // Update window title - string newTitle = format("{} - {:.0F} FPS", baseTitle, Fps); - glfwSetWindowTitle(window, newTitle.c_str()); - } - } + // double xoffset = xpos - MouseState.last_x; + // double yoffset = MouseState.last_y - ypos; // Reversed since y-coordinates range from bottom to top + + // MouseState.last_x = xpos; + // MouseState.last_y = ypos; + + // camera.rotate(xoffset, yoffset); + // } /** * @brief Initializes the application window using GLFW. @@ -334,7 +372,13 @@ class VulkanApp { mWindow = vkfw::createWindowUnique(WIDTH, HEIGHT, "Vulkan", hints); // Set the user pointer to this instance, allowing us to access it in callbacks - mWindow->setUserPointer(this); + mWindow->setUserPointer(this); // Store camera pointer for callbacks + + // Configure cursor + // glfwSetInputMode(mWindow.get(), GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + // Set up mouse callback + // mWindow->callbacks()->on_cursor_move = mouseCallback; // Set up the window resize callback mWindow->callbacks()->on_window_resize = @@ -459,8 +503,6 @@ class VulkanApp { * polls for events and draws frames until the window is closed. */ fn mainLoop() -> void { - Camera camera; - // Set initial time variables f64 lastFrame = 0.0; f64 deltaTime = 0.0; @@ -473,13 +515,13 @@ class VulkanApp { lastFrame = currentFrame; // Process input for camera movement - processInput(mWindow.get(), camera, deltaTime); + processInput(mWindow.get(), mCamera, deltaTime); // Create view matrix from camera - mView = camera.getViewMatrix(); + mView = mCamera.getViewMatrix(); // Update the FPS counter - updateFPS(mWindow.get(), "Vulkan"); + // updateFPS(mWindow.get(), "Vulkan"); // Poll for events vkfw::pollEvents(); @@ -1201,14 +1243,14 @@ class VulkanApp { u8* pixels = image.getData(); i32 texWidth = image.getWidth(), texHeight = image.getHeight(); - vk::DeviceSize imageSize = - static_cast(texWidth) * static_cast(texHeight) * 4; - mMipLevels = static_cast(std::floor(std::log2(std::max(texWidth, texHeight)))) + 1; if (!pixels) throw std::runtime_error("Failed to load texture image!"); + vk::DeviceSize imageSize = + static_cast(texWidth) * static_cast(texHeight) * 4; + vk::UniqueBuffer stagingBuffer; vk::UniqueDeviceMemory stagingBufferMemory; @@ -2269,10 +2311,7 @@ class VulkanApp { * This function takes compiled shader code and creates a Vulkan shader module from it. */ fn createShaderModule(const std::vector& code) -> vk::UniqueShaderModule { - vk::ShaderModuleCreateInfo createInfo { - .codeSize = code.size() * sizeof(u32), - .pCode = code.data(), - }; + vk::ShaderModuleCreateInfo createInfo { .codeSize = code.size() * sizeof(u32), .pCode = code.data() }; return mDevice->createShaderModuleUnique(createInfo); }