camera movement yay

This commit is contained in:
Mars 2024-11-15 12:40:13 -05:00
parent 45e8a99bd1
commit 924fb0be7a
2 changed files with 144 additions and 63 deletions

View file

@ -14,7 +14,7 @@ common_cpp_args = [
'-Wno-c++98-compat-pedantic',
'-Wno-pre-c++20-compat-pedantic',
'-Wno-padded',
'-mavx2'
'-mavx2',
]
add_project_arguments(cpp.get_supported_arguments(common_cpp_args), language: 'cpp')
@ -40,4 +40,4 @@ executable(
sources: files('src/main.cpp'),
include_directories: include_directories('include', is_system: true),
dependencies: deps,
)
)

View file

@ -1,5 +1,4 @@
// Include necessary headers
#include <GLFW/glfw3.h>
#include <chrono> // For time-related functions
#include <fmt/format.h> // For string formatting
#include <shaderc/shaderc.hpp> // For shader compilation
@ -39,8 +38,8 @@ VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
#include "vkfw.hpp" // Include GLFW C++ bindings
// Constants for window dimensions
constexpr i32 WIDTH = 800;
constexpr i32 HEIGHT = 600;
constexpr i32 WIDTH = 1920;
constexpr i32 HEIGHT = 1080;
// CAMERA_SPEED of camera movement
constexpr f64 CAMERA_SPEED = 1.0;
@ -130,9 +129,9 @@ class VulkanApp {
}
// Shut down ImGui
ImGui_ImplVulkan_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
// ImGui_ImplVulkan_Shutdown();
// ImGui_ImplGlfw_Shutdown();
// ImGui::DestroyContext();
}
private:
@ -206,6 +205,12 @@ class VulkanApp {
glm::mat4 mView; ///< View matrix
// Mouse input tracking
bool mFirstMouse = true; ///< Flag for first mouse movement
f64 mLastX = WIDTH / 2.0; ///< Last mouse X position
f64 mLastY = HEIGHT / 2.0; ///< Last mouse Y position
bool mCursorCaptured = true; ///< Flag indicating if cursor is captured
/**
* @brief Struct to store queue family indices.
*
@ -280,6 +285,10 @@ class VulkanApp {
fn moveRight(f64 deltaTime) -> void { position += right * CAMERA_SPEED * deltaTime; }
fn moveUp(f64 deltaTime) -> void { position += glm::dvec3(0.0, 0.0, 1.0) * CAMERA_SPEED * deltaTime; }
fn moveDown(f64 deltaTime) -> void { position -= glm::dvec3(0.0, 0.0, 1.0) * CAMERA_SPEED * deltaTime; }
fn rotate(double xoffset, double yoffset) -> void {
const double sensitivity = 0.1;
yaw += xoffset * sensitivity;
@ -320,37 +329,16 @@ class VulkanApp {
camera.moveBackward(deltaTime);
if (window.getKey(vkfw::Key::eD) == vkfw::eTrue)
camera.moveRight(deltaTime);
if (window.getKey(vkfw::Key::eSpace) == vkfw::eTrue)
camera.moveUp(deltaTime);
if (window.getKey(vkfw::Key::eLeftShift) == vkfw::eTrue)
camera.moveDown(deltaTime);
fmt::println(
"New position: {} {} {}", camera.getPosition()[0], camera.getPosition()[1], camera.getPosition()[2]
);
}
// static fn mouseCallback(const vkfw::Window& window, double xpos, double ypos) -> void {
// auto& camera = *static_cast<Camera*>(window.getUserPointer());
// static struct {
// bool first_mouse = true;
// double last_x = WIDTH / 2.0;
// double last_y = HEIGHT / 2.0;
// } MouseState;
// if (MouseState.first_mouse) {
// MouseState.last_x = xpos;
// MouseState.last_y = ypos;
// MouseState.first_mouse = false;
// return;
// }
// 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.
*
@ -372,19 +360,67 @@ 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); // Store camera pointer for callbacks
mWindow->setUserPointer(this);
// Configure cursor
// glfwSetInputMode(mWindow.get(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// Configure cursor for FPS-style camera control
mWindow->set<vkfw::InputMode::eCursor>(vkfw::CursorMode::eDisabled);
// Set up mouse callback
// mWindow->callbacks()->on_cursor_move = mouseCallback;
mWindow->callbacks()->on_cursor_move =
[this](const vkfw::Window& /*window*/, f64 xpos, f64 ypos) -> void {
if (!mCursorCaptured)
return; // Skip camera movement when cursor is not captured
if (mFirstMouse) {
mLastX = xpos;
mLastY = ypos;
mFirstMouse = false;
return;
}
f64 xoffset = xpos - mLastX;
f64 yoffset = mLastY - ypos; // Reversed since y-coordinates range from bottom to top
mLastX = xpos;
mLastY = ypos;
mCamera.rotate(-xoffset, yoffset); // Invert xoffset for correct horizontal movement
};
// Set up key callback for escape
mWindow->callbacks()->on_key = [this](
const vkfw::Window& window,
const vkfw::Key& key,
const i32& /*scancode*/,
const vkfw::KeyAction& action,
const vkfw::ModifierKeyFlags& /*mods*/
) -> void {
if (key == vkfw::Key::eEscape && action == vkfw::KeyAction::ePress) {
mCursorCaptured = false;
window.set<vkfw::InputMode::eCursor>(vkfw::CursorMode::eNormal);
}
};
// Set up mouse button callback for re-capture
mWindow->callbacks()->on_mouse_button = [this](
const vkfw::Window& window,
const vkfw::MouseButton& button,
const vkfw::MouseButtonAction& action,
const vkfw::ModifierKeyFlags& /*mods*/
) -> void {
if (button == vkfw::MouseButton::eLeft && action == vkfw::MouseButtonAction::ePress &&
!mCursorCaptured) {
mCursorCaptured = true;
mFirstMouse = true; // Reset first mouse flag to avoid jumps
window.set<vkfw::InputMode::eCursor>(vkfw::CursorMode::eDisabled);
}
};
// Set up the window resize callback
mWindow->callbacks()->on_window_resize =
[](const vkfw::Window& window, usize /*width*/, usize /*height*/) -> void {
[this](const vkfw::Window& /*window*/, usize /*width*/, usize /*height*/) -> void {
// Set the framebuffer resized flag when the window is resized
std::bit_cast<VulkanApp*>(window.getUserPointer())->mFramebufferResized = true;
mFramebufferResized = true;
};
}
@ -431,7 +467,7 @@ class VulkanApp {
createDescriptorSets(); // Allocate and update descriptor sets
createCommandBuffers(); // Create command buffers for rendering commands
createSyncObjects(); // Create synchronization objects (semaphores and fences)
initImGui(); // Initialize Dear ImGui for GUI rendering
// initImGui(); // Initialize Dear ImGui for GUI rendering
}
/**
@ -441,6 +477,8 @@ class VulkanApp {
* sets up the style, initializes ImGui for GLFW and Vulkan, and creates a descriptor pool for ImGui.
*/
fn initImGui() -> void {
// Temporarily disabled ImGui initialization
/*
// Create ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
@ -494,6 +532,7 @@ class VulkanApp {
};
ImGui_ImplVulkan_Init(&initInfo);
*/
}
/**
@ -503,34 +542,32 @@ class VulkanApp {
* polls for events and draws frames until the window is closed.
*/
fn mainLoop() -> void {
// Set initial time variables
f64 lastFrame = 0.0;
f64 deltaTime = 0.0;
f64 lastFrame = 0.0;
f64 deltaTime = 0.0;
f64 lastFpsUpdate = 0.0;
i32 frameCounter = 0;
// While the window is open,
while (!mWindow->shouldClose()) {
// Calculate time between frames
f64 currentFrame = vkfw::getTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
// Process input for camera movement
processInput(mWindow.get(), mCamera, deltaTime);
// Create view matrix from camera
mView = mCamera.getViewMatrix();
// Update the FPS counter
// updateFPS(mWindow.get(), "Vulkan");
if (currentFrame - lastFpsUpdate > 1.0) {
mWindow->setTitle(
fmt::format("Vulkan - {:.0f}FPS", static_cast<f32>(frameCounter / (currentFrame - lastFpsUpdate)))
);
lastFpsUpdate = currentFrame;
frameCounter = 0;
}
++frameCounter;
// Poll for events
vkfw::pollEvents();
// Draw a frame
drawFrame();
}
// Wait for the device to finish
mDevice->waitIdle();
}
@ -2118,18 +2155,62 @@ class VulkanApp {
nullptr
);
// Draw the indexed vertices
commandBuffer.drawIndexed(static_cast<u32>(mIndices.size()), 1, 0, 0, 0);
UniformBufferObject ubo {
// Model matrix - glm::rotate(matrix, angle, axis)
.model = glm::mat4(1.0F),
// View matrix - glm::lookAt(eye, center, up)
.view = mView,
// Projection matrix - glm::perspective(fov, aspect, near, far)
.proj = glm::perspective(
glm::radians(90.0F),
static_cast<f32>(mSwapChainExtent.width) / static_cast<f32>(mSwapChainExtent.height),
0.1F,
100.0F
)
};
ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// Flip the Y axis, because glm was designed for OpenGL
ubo.proj[1][1] *= -1;
// Copy the uniform buffer object to the mapped memory
memcpy(mUniformBuffersMapped[mCurrentFrame], &ubo, sizeof(ubo));
// Example: Add extra clones with different translations
std::vector<glm::mat4> modelMatrices = {
glm::translate(glm::mat4(1.0F), glm::vec3(2.0F, 0.0F, 0.0F)),
glm::translate(glm::mat4(1.0F), glm::vec3(-2.0F, 0.0F, 0.0F)),
glm::translate(glm::mat4(1.0F), glm::vec3(0.0F, 2.0F, 0.0F))
};
for (const auto& modelMatrix : modelMatrices) {
// Update model matrix for each clone
ubo.model = modelMatrix;
memcpy(mUniformBuffersMapped[mCurrentFrame], &ubo, sizeof(ubo));
// Bind the descriptor sets
commandBuffer.bindDescriptorSets(
vk::PipelineBindPoint::eGraphics,
mPipelineLayout.get(),
0,
1,
&mDescriptorSets[mCurrentFrame],
0,
nullptr
);
// Draw the indexed vertices
commandBuffer.drawIndexed(static_cast<u32>(mIndices.size()), 1, 0, 0, 0);
}
// ImGui_ImplVulkan_NewFrame();
// ImGui_ImplGlfw_NewFrame();
// ImGui::NewFrame();
// Your ImGui code here
ImGui::ShowDemoWindow();
// ImGui::ShowDemoWindow();
ImGui::Render();
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), commandBuffer);
// ImGui::Render();
// ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), commandBuffer);
// End the render pass
commandBuffer.endRenderPass();
@ -2193,7 +2274,7 @@ class VulkanApp {
.view = mView,
// Projection matrix - glm::perspective(fov, aspect, near, far)
.proj = glm::perspective(
glm::radians(45.0F),
glm::radians(90.0F),
static_cast<f32>(mSwapChainExtent.width) / static_cast<f32>(mSwapChainExtent.height),
0.1F,
100.0F