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-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,
|
||||
)
|
||||
)
|
203
src/main.cpp
203
src/main.cpp
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue