camera movement yay
This commit is contained in:
parent
45e8a99bd1
commit
924fb0be7a
|
@ -14,7 +14,7 @@ common_cpp_args = [
|
||||||
'-Wno-c++98-compat-pedantic',
|
'-Wno-c++98-compat-pedantic',
|
||||||
'-Wno-pre-c++20-compat-pedantic',
|
'-Wno-pre-c++20-compat-pedantic',
|
||||||
'-Wno-padded',
|
'-Wno-padded',
|
||||||
'-mavx2'
|
'-mavx2',
|
||||||
]
|
]
|
||||||
|
|
||||||
add_project_arguments(cpp.get_supported_arguments(common_cpp_args), language: 'cpp')
|
add_project_arguments(cpp.get_supported_arguments(common_cpp_args), language: 'cpp')
|
||||||
|
|
195
src/main.cpp
195
src/main.cpp
|
@ -1,5 +1,4 @@
|
||||||
// Include necessary headers
|
// Include necessary headers
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <chrono> // For time-related functions
|
#include <chrono> // For time-related functions
|
||||||
#include <fmt/format.h> // For string formatting
|
#include <fmt/format.h> // For string formatting
|
||||||
#include <shaderc/shaderc.hpp> // For shader compilation
|
#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
|
#include "vkfw.hpp" // Include GLFW C++ bindings
|
||||||
|
|
||||||
// Constants for window dimensions
|
// Constants for window dimensions
|
||||||
constexpr i32 WIDTH = 800;
|
constexpr i32 WIDTH = 1920;
|
||||||
constexpr i32 HEIGHT = 600;
|
constexpr i32 HEIGHT = 1080;
|
||||||
|
|
||||||
// CAMERA_SPEED of camera movement
|
// CAMERA_SPEED of camera movement
|
||||||
constexpr f64 CAMERA_SPEED = 1.0;
|
constexpr f64 CAMERA_SPEED = 1.0;
|
||||||
|
@ -130,9 +129,9 @@ class VulkanApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shut down ImGui
|
// Shut down ImGui
|
||||||
ImGui_ImplVulkan_Shutdown();
|
// ImGui_ImplVulkan_Shutdown();
|
||||||
ImGui_ImplGlfw_Shutdown();
|
// ImGui_ImplGlfw_Shutdown();
|
||||||
ImGui::DestroyContext();
|
// ImGui::DestroyContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -206,6 +205,12 @@ class VulkanApp {
|
||||||
|
|
||||||
glm::mat4 mView; ///< View matrix
|
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.
|
* @brief Struct to store queue family indices.
|
||||||
*
|
*
|
||||||
|
@ -280,6 +285,10 @@ class VulkanApp {
|
||||||
|
|
||||||
fn moveRight(f64 deltaTime) -> void { position += right * CAMERA_SPEED * deltaTime; }
|
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 {
|
fn rotate(double xoffset, double yoffset) -> void {
|
||||||
const double sensitivity = 0.1;
|
const double sensitivity = 0.1;
|
||||||
yaw += xoffset * sensitivity;
|
yaw += xoffset * sensitivity;
|
||||||
|
@ -320,37 +329,16 @@ class VulkanApp {
|
||||||
camera.moveBackward(deltaTime);
|
camera.moveBackward(deltaTime);
|
||||||
if (window.getKey(vkfw::Key::eD) == vkfw::eTrue)
|
if (window.getKey(vkfw::Key::eD) == vkfw::eTrue)
|
||||||
camera.moveRight(deltaTime);
|
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(
|
fmt::println(
|
||||||
"New position: {} {} {}", camera.getPosition()[0], camera.getPosition()[1], camera.getPosition()[2]
|
"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.
|
* @brief Initializes the application window using GLFW.
|
||||||
*
|
*
|
||||||
|
@ -372,19 +360,67 @@ class VulkanApp {
|
||||||
mWindow = vkfw::createWindowUnique(WIDTH, HEIGHT, "Vulkan", hints);
|
mWindow = vkfw::createWindowUnique(WIDTH, HEIGHT, "Vulkan", hints);
|
||||||
|
|
||||||
// Set the user pointer to this instance, allowing us to access it in callbacks
|
// 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
|
// Configure cursor for FPS-style camera control
|
||||||
// glfwSetInputMode(mWindow.get(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
mWindow->set<vkfw::InputMode::eCursor>(vkfw::CursorMode::eDisabled);
|
||||||
|
|
||||||
// Set up mouse callback
|
// 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
|
// Set up the window resize callback
|
||||||
mWindow->callbacks()->on_window_resize =
|
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
|
// 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
|
createDescriptorSets(); // Allocate and update descriptor sets
|
||||||
createCommandBuffers(); // Create command buffers for rendering commands
|
createCommandBuffers(); // Create command buffers for rendering commands
|
||||||
createSyncObjects(); // Create synchronization objects (semaphores and fences)
|
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.
|
* sets up the style, initializes ImGui for GLFW and Vulkan, and creates a descriptor pool for ImGui.
|
||||||
*/
|
*/
|
||||||
fn initImGui() -> void {
|
fn initImGui() -> void {
|
||||||
|
// Temporarily disabled ImGui initialization
|
||||||
|
/*
|
||||||
// Create ImGui context
|
// Create ImGui context
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
|
@ -494,6 +532,7 @@ class VulkanApp {
|
||||||
};
|
};
|
||||||
|
|
||||||
ImGui_ImplVulkan_Init(&initInfo);
|
ImGui_ImplVulkan_Init(&initInfo);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -503,34 +542,32 @@ class VulkanApp {
|
||||||
* polls for events and draws frames until the window is closed.
|
* polls for events and draws frames until the window is closed.
|
||||||
*/
|
*/
|
||||||
fn mainLoop() -> void {
|
fn mainLoop() -> void {
|
||||||
// Set initial time variables
|
|
||||||
f64 lastFrame = 0.0;
|
f64 lastFrame = 0.0;
|
||||||
f64 deltaTime = 0.0;
|
f64 deltaTime = 0.0;
|
||||||
|
f64 lastFpsUpdate = 0.0;
|
||||||
|
i32 frameCounter = 0;
|
||||||
|
|
||||||
// While the window is open,
|
|
||||||
while (!mWindow->shouldClose()) {
|
while (!mWindow->shouldClose()) {
|
||||||
// Calculate time between frames
|
|
||||||
f64 currentFrame = vkfw::getTime();
|
f64 currentFrame = vkfw::getTime();
|
||||||
deltaTime = currentFrame - lastFrame;
|
deltaTime = currentFrame - lastFrame;
|
||||||
lastFrame = currentFrame;
|
lastFrame = currentFrame;
|
||||||
|
|
||||||
// Process input for camera movement
|
|
||||||
processInput(mWindow.get(), mCamera, deltaTime);
|
processInput(mWindow.get(), mCamera, deltaTime);
|
||||||
|
|
||||||
// Create view matrix from camera
|
|
||||||
mView = mCamera.getViewMatrix();
|
mView = mCamera.getViewMatrix();
|
||||||
|
|
||||||
// Update the FPS counter
|
if (currentFrame - lastFpsUpdate > 1.0) {
|
||||||
// updateFPS(mWindow.get(), "Vulkan");
|
mWindow->setTitle(
|
||||||
|
fmt::format("Vulkan - {:.0f}FPS", static_cast<f32>(frameCounter / (currentFrame - lastFpsUpdate)))
|
||||||
|
);
|
||||||
|
lastFpsUpdate = currentFrame;
|
||||||
|
frameCounter = 0;
|
||||||
|
}
|
||||||
|
++frameCounter;
|
||||||
|
|
||||||
// Poll for events
|
|
||||||
vkfw::pollEvents();
|
vkfw::pollEvents();
|
||||||
|
|
||||||
// Draw a frame
|
|
||||||
drawFrame();
|
drawFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the device to finish
|
|
||||||
mDevice->waitIdle();
|
mDevice->waitIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2118,18 +2155,62 @@ class VulkanApp {
|
||||||
nullptr
|
nullptr
|
||||||
);
|
);
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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
|
// Draw the indexed vertices
|
||||||
commandBuffer.drawIndexed(static_cast<u32>(mIndices.size()), 1, 0, 0, 0);
|
commandBuffer.drawIndexed(static_cast<u32>(mIndices.size()), 1, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
ImGui_ImplVulkan_NewFrame();
|
// ImGui_ImplVulkan_NewFrame();
|
||||||
ImGui_ImplGlfw_NewFrame();
|
// ImGui_ImplGlfw_NewFrame();
|
||||||
ImGui::NewFrame();
|
// ImGui::NewFrame();
|
||||||
|
|
||||||
// Your ImGui code here
|
// Your ImGui code here
|
||||||
ImGui::ShowDemoWindow();
|
// ImGui::ShowDemoWindow();
|
||||||
|
|
||||||
ImGui::Render();
|
// ImGui::Render();
|
||||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), commandBuffer);
|
// ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), commandBuffer);
|
||||||
|
|
||||||
// End the render pass
|
// End the render pass
|
||||||
commandBuffer.endRenderPass();
|
commandBuffer.endRenderPass();
|
||||||
|
@ -2193,7 +2274,7 @@ class VulkanApp {
|
||||||
.view = mView,
|
.view = mView,
|
||||||
// Projection matrix - glm::perspective(fov, aspect, near, far)
|
// Projection matrix - glm::perspective(fov, aspect, near, far)
|
||||||
.proj = glm::perspective(
|
.proj = glm::perspective(
|
||||||
glm::radians(45.0F),
|
glm::radians(90.0F),
|
||||||
static_cast<f32>(mSwapChainExtent.width) / static_cast<f32>(mSwapChainExtent.height),
|
static_cast<f32>(mSwapChainExtent.width) / static_cast<f32>(mSwapChainExtent.height),
|
||||||
0.1F,
|
0.1F,
|
||||||
100.0F
|
100.0F
|
||||||
|
|
Loading…
Reference in a new issue