(broken rn) ughghfgdhg
This commit is contained in:
parent
2b77ce40b5
commit
599eb29925
|
@ -37,7 +37,12 @@ deps += imgui_dep
|
|||
|
||||
executable(
|
||||
'graphics-test',
|
||||
sources: files('src/camera/camera.cpp', 'src/main.cpp'),
|
||||
sources: [
|
||||
'src/main.cpp',
|
||||
'src/camera/camera.cpp',
|
||||
'src/init/vulkan_instance.cpp',
|
||||
'src/init/debug_messenger.cpp',
|
||||
],
|
||||
include_directories: include_directories('include', is_system: true),
|
||||
dependencies: deps,
|
||||
)
|
|
@ -5,10 +5,6 @@
|
|||
|
||||
#include "../util/types.hpp"
|
||||
|
||||
struct CameraInfo {
|
||||
alignas(16) glm::vec3 position; ///< Camera position
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Camera class for handling 3D camera movement and perspective
|
||||
*/
|
||||
|
|
32
src/init/debug_messenger.cpp
Normal file
32
src/init/debug_messenger.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include <fmt/format.h>
|
||||
|
||||
#include "debug_messenger.hpp"
|
||||
|
||||
fn DebugMessenger::create(const vk::Instance& instance) -> vk::UniqueDebugUtilsMessengerEXT {
|
||||
#ifdef NDEBUG
|
||||
return nullptr;
|
||||
#else
|
||||
vk::DebugUtilsMessengerCreateInfoEXT createInfo {
|
||||
.messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError,
|
||||
.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance,
|
||||
.pfnUserCallback = debugCallback,
|
||||
.pUserData = nullptr,
|
||||
};
|
||||
|
||||
return instance.createDebugUtilsMessengerEXTUnique(createInfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL DebugMessenger::debugCallback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT /*messageSeverity*/,
|
||||
VkDebugUtilsMessageTypeFlagsEXT /*messageType*/,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* /*pUserData*/
|
||||
) {
|
||||
fmt::println("validation layer: {}", pCallbackData->pMessage);
|
||||
return VK_FALSE;
|
||||
}
|
27
src/init/debug_messenger.hpp
Normal file
27
src/init/debug_messenger.hpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 // Use dynamic dispatch for Vulkan functions
|
||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "../util/types.hpp"
|
||||
|
||||
class DebugMessenger {
|
||||
public:
|
||||
DebugMessenger() = default;
|
||||
DebugMessenger(const DebugMessenger&) = default;
|
||||
DebugMessenger(DebugMessenger&&) = delete;
|
||||
fn operator=(const DebugMessenger&)->DebugMessenger& = default;
|
||||
fn operator=(DebugMessenger&&)->DebugMessenger& = delete;
|
||||
~DebugMessenger() = default;
|
||||
|
||||
static fn create(const vk::Instance& instance) -> vk::UniqueDebugUtilsMessengerEXT;
|
||||
|
||||
private:
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* pUserData
|
||||
);
|
||||
};
|
101
src/init/vulkan_instance.cpp
Normal file
101
src/init/vulkan_instance.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include <fmt/format.h>
|
||||
|
||||
#include "vulkan_instance.hpp"
|
||||
|
||||
#include "../util/constants.hpp"
|
||||
|
||||
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
||||
|
||||
using namespace constants;
|
||||
|
||||
fn VulkanInstance::create() -> vk::UniqueInstance {
|
||||
#ifndef NDEBUG
|
||||
// Make sure validation layers are supported
|
||||
if (!checkValidationLayerSupport())
|
||||
throw std::runtime_error("Validation layers requested, but not available!");
|
||||
|
||||
#endif
|
||||
|
||||
// Application metadata
|
||||
vk::ApplicationInfo appInfo {
|
||||
.pApplicationName = "Vulkan App",
|
||||
.applicationVersion = 1,
|
||||
.pEngineName = "No Engine",
|
||||
.engineVersion = 1,
|
||||
.apiVersion = vk::ApiVersion13,
|
||||
};
|
||||
|
||||
// Get required extensions
|
||||
auto extensions = getRequiredExtensions();
|
||||
|
||||
#ifndef NDEBUG
|
||||
fmt::println("Available extensions:");
|
||||
for (const char* extension : extensions) { fmt::println("\t{}", extension); }
|
||||
#endif
|
||||
|
||||
// Create the instance
|
||||
vk::InstanceCreateInfo createInfo {
|
||||
#ifdef __APPLE__
|
||||
.flags = vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR,
|
||||
#endif
|
||||
.pApplicationInfo = &appInfo,
|
||||
#ifdef NDEBUG
|
||||
.enabledLayerCount = 0,
|
||||
.ppEnabledLayerNames = nullptr,
|
||||
#else
|
||||
.enabledLayerCount = static_cast<u32>(validationLayers.size()),
|
||||
.ppEnabledLayerNames = validationLayers.data(),
|
||||
#endif
|
||||
.enabledExtensionCount = static_cast<u32>(extensions.size()),
|
||||
.ppEnabledExtensionNames = extensions.data()
|
||||
};
|
||||
|
||||
auto instance = vk::createInstanceUnique(createInfo);
|
||||
|
||||
// Initialize the dynamic dispatcher with the instance
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance.get());
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
fn VulkanInstance::getRequiredExtensions() -> std::vector<const char*> {
|
||||
// Get the required extensions from GLFW
|
||||
std::span<const char*> extensionsSpan = vkfw::getRequiredInstanceExtensions();
|
||||
std::vector<const char*> extensions(extensionsSpan.begin(), extensionsSpan.end());
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Add debug utils extension in debug mode
|
||||
extensions.push_back(vk::EXTDebugUtilsExtensionName);
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Add required macOS extensions
|
||||
extensions.push_back(vk::KHRPortabilityEnumerationExtensionName);
|
||||
extensions.push_back("VK_KHR_get_physical_device_properties2");
|
||||
#endif
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
fn VulkanInstance::checkValidationLayerSupport() -> bool {
|
||||
// Get available layers
|
||||
auto availableLayers = vk::enumerateInstanceLayerProperties();
|
||||
|
||||
// Check if all requested validation layers are available
|
||||
for (const char* layerName : validationLayers) {
|
||||
bool layerFound = false;
|
||||
|
||||
for (const auto& layerProperties : availableLayers) {
|
||||
if (strcmp(layerName, layerProperties.layerName) == 0) {
|
||||
layerFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!layerFound) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
25
src/init/vulkan_instance.hpp
Normal file
25
src/init/vulkan_instance.hpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#define VKFW_NO_STRUCT_CONSTRUCTORS // Use aggregate initialization for GLFW structs
|
||||
#include <vkfw.hpp>
|
||||
|
||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "../util/types.hpp"
|
||||
|
||||
class VulkanInstance {
|
||||
public:
|
||||
VulkanInstance() = default;
|
||||
VulkanInstance(const VulkanInstance&) = default;
|
||||
VulkanInstance(VulkanInstance&&) = delete;
|
||||
fn operator=(const VulkanInstance&)->VulkanInstance& = default;
|
||||
fn operator=(VulkanInstance&&)->VulkanInstance& = delete;
|
||||
~VulkanInstance() = default;
|
||||
|
||||
static fn create() -> vk::UniqueInstance;
|
||||
|
||||
private:
|
||||
static fn getRequiredExtensions() -> std::vector<const char*>;
|
||||
static fn checkValidationLayerSupport() -> bool;
|
||||
};
|
154
src/main.cpp
154
src/main.cpp
|
@ -19,11 +19,15 @@
|
|||
#define VULKAN_HPP_NO_CONSTRUCTORS // Use aggregate initialization for Vulkan structs
|
||||
#include <vulkan/vulkan.hpp> // Include Vulkan C++ bindings
|
||||
|
||||
// Necessary for dynamic dispatch to work
|
||||
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
||||
|
||||
// Include custom utility headers
|
||||
#include "camera/camera.hpp" // Camera class
|
||||
#include "init/debug_messenger.hpp"
|
||||
#include "init/vulkan_instance.hpp"
|
||||
#include "structs/camera_info.hpp"
|
||||
#include "structs/light_info.hpp"
|
||||
#include "structs/queue_family_indices.hpp"
|
||||
#include "structs/swap_chain_support_details.hpp"
|
||||
#include "structs/uniform_buffer_object.hpp"
|
||||
#include "util/constants.hpp" // Constants definitions
|
||||
#include "util/crosshair.hpp" // Crosshair definitions
|
||||
#include "util/shaders.hpp" // Compiled shader code
|
||||
|
@ -156,23 +160,10 @@ class VulkanApp {
|
|||
Camera mCamera; ///< Camera object
|
||||
|
||||
// Light settings
|
||||
struct {
|
||||
glm::vec3 position = glm::vec3(2.0F, 2.0F, 2.0F);
|
||||
glm::vec3 color = glm::vec3(1.0F, 1.0F, 1.0F);
|
||||
float ambient_strength = 0.1F;
|
||||
float specular_strength = 0.5F;
|
||||
} mLightSettings;
|
||||
|
||||
std::vector<vk::UniqueSemaphore>
|
||||
mImageAvailableSemaphores; ///< Signals that an image is available for rendering
|
||||
std::vector<vk::UniqueSemaphore> mRenderFinishedSemaphores; ///< Signals that rendering has finished
|
||||
std::vector<vk::UniqueFence> mInFlightFences; ///< Ensures CPU-GPU synchronization
|
||||
std::vector<vk::Fence> mImagesInFlight; ///< Tracks which fences are in use by which swap chain images
|
||||
|
||||
bool mFramebufferResized = false; ///< Flag indicating if the framebuffer was resized
|
||||
u32 mCurrentFrame = 0; ///< Index of the current frame being rendered
|
||||
|
||||
glm::mat4 mView; ///< View matrix
|
||||
LightInfo mLightSettings { .position = glm::vec3(2.0F, 2.0F, 2.0F),
|
||||
.color = glm::vec3(1.0F, 1.0F, 1.0F),
|
||||
.ambient_strength = 0.1F,
|
||||
.specular_strength = 0.5F };
|
||||
|
||||
// Mouse input tracking
|
||||
bool mFirstMouse = true; ///< Flag for first mouse movement
|
||||
|
@ -188,52 +179,16 @@ class VulkanApp {
|
|||
f32 mMaxLineWidth = 1.0F; ///< Maximum supported line width
|
||||
bool mWideLineSupport = false; ///< Whether wide lines are supported
|
||||
|
||||
/**
|
||||
* @brief Struct to store queue family indices.
|
||||
*
|
||||
* This struct contains the indices of the graphics and presentation queue families.
|
||||
*/
|
||||
struct QueueFamilyIndices {
|
||||
std::optional<u32> graphics_family; ///< Index of graphics queue family
|
||||
std::optional<u32> present_family; ///< Index of presentation queue family
|
||||
std::vector<vk::UniqueSemaphore>
|
||||
mImageAvailableSemaphores; ///< Signals that an image is available for rendering
|
||||
std::vector<vk::UniqueSemaphore> mRenderFinishedSemaphores; ///< Signals that rendering has finished
|
||||
std::vector<vk::UniqueFence> mInFlightFences; ///< Ensures CPU-GPU synchronization
|
||||
std::vector<vk::Fence> mImagesInFlight; ///< Tracks which fences are in use by which swap chain images
|
||||
|
||||
/**
|
||||
* @brief Check if all required queue families are found.
|
||||
*
|
||||
* @return True if both graphics and presentation families are found, false otherwise.
|
||||
*/
|
||||
fn isComplete() -> bool { return graphics_family.has_value() && present_family.has_value(); }
|
||||
};
|
||||
bool mFramebufferResized = false; ///< Flag indicating if the framebuffer was resized
|
||||
u32 mCurrentFrame = 0; ///< Index of the current frame being rendered
|
||||
|
||||
/**
|
||||
* @brief Struct to hold swap chain support details.
|
||||
*
|
||||
* This struct contains information about the surface capabilities,
|
||||
* supported formats, and presentation modes.
|
||||
*/
|
||||
struct SwapChainSupportDetails {
|
||||
vk::SurfaceCapabilitiesKHR capabilities; ///< Surface capabilities
|
||||
std::vector<vk::SurfaceFormatKHR> formats; ///< Supported surface formats
|
||||
std::vector<vk::PresentModeKHR> present_modes; ///< Supported presentation modes
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Struct representing a uniform buffer object.
|
||||
*
|
||||
* This struct holds the model, view, and projection matrices for use in shaders.
|
||||
*/
|
||||
struct UniformBufferObject {
|
||||
alignas(16) glm::mat4 model; ///< Model transformation matrix
|
||||
alignas(16) glm::mat4 view; ///< View transformation matrix
|
||||
alignas(16) glm::mat4 proj; ///< Projection matrix
|
||||
};
|
||||
|
||||
struct LightInfo {
|
||||
alignas(16) glm::vec3 position; ///< Light position
|
||||
alignas(16) glm::vec3 color; ///< Light color
|
||||
alignas(4) float ambient_strength; ///< Ambient strength
|
||||
alignas(4) float specular_strength; ///< Specular strength
|
||||
};
|
||||
glm::mat4 mView; ///< View matrix
|
||||
|
||||
static fn processInput(vkfw::Window& window, Camera& camera, const f32& deltaTime, const f32& cameraSpeed)
|
||||
-> void {
|
||||
|
@ -699,63 +654,7 @@ class VulkanApp {
|
|||
throw std::runtime_error("Validation layers requested, but not available!");
|
||||
#endif
|
||||
|
||||
// Application metadata
|
||||
vk::ApplicationInfo appInfo {
|
||||
.pApplicationName = "Vulkan App",
|
||||
.applicationVersion = 1,
|
||||
.pEngineName = "No Engine",
|
||||
.engineVersion = 1,
|
||||
.apiVersion = vk::ApiVersion13,
|
||||
};
|
||||
|
||||
// Get the required extensions
|
||||
std::span<const char*> extensionsSpan = vkfw::getRequiredInstanceExtensions();
|
||||
|
||||
// Convert the span to a vector
|
||||
std::vector extensions(extensionsSpan.begin(), extensionsSpan.end());
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Add the debug utils extension
|
||||
extensions.emplace_back(vk::EXTDebugUtilsExtensionName);
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Add the portability extension
|
||||
extensions.emplace_back(vk::KHRPortabilityEnumerationExtensionName);
|
||||
// Technically deprecated but Vulkan complains if I don't include it for macOS,
|
||||
// so instead of using the vk::KHRPortabilitySubsetExtensionName, I just use
|
||||
// the direct string.
|
||||
extensions.emplace_back("VK_KHR_get_physical_device_properties2");
|
||||
#endif
|
||||
|
||||
// Create the instance
|
||||
vk::InstanceCreateInfo createInfo {
|
||||
#ifdef __APPLE__
|
||||
// Enable the portability extension
|
||||
.flags = vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR,
|
||||
#endif
|
||||
.pApplicationInfo = &appInfo,
|
||||
#ifdef NDEBUG
|
||||
.enabledLayerCount = 0,
|
||||
.ppEnabledLayerNames = nullptr,
|
||||
#else
|
||||
.enabledLayerCount = static_cast<u32>(validationLayers.size()),
|
||||
.ppEnabledLayerNames = validationLayers.data(),
|
||||
#endif
|
||||
.enabledExtensionCount = static_cast<u32>(extensions.size()),
|
||||
.ppEnabledExtensionNames = extensions.data()
|
||||
};
|
||||
|
||||
#ifndef NDEBUG
|
||||
fmt::println("Available extensions:");
|
||||
for (const char* extension : extensions) fmt::println("\t{}", extension);
|
||||
#endif
|
||||
|
||||
// Create the instance
|
||||
mInstance = vk::createInstanceUnique(createInfo);
|
||||
|
||||
// Load the instance functions
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(mInstance.get());
|
||||
mInstance = VulkanInstance::create();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -768,17 +667,7 @@ class VulkanApp {
|
|||
return;
|
||||
#endif
|
||||
|
||||
vk::DebugUtilsMessengerCreateInfoEXT messengerCreateInfo {
|
||||
.messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError,
|
||||
.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance,
|
||||
.pfnUserCallback = debugCallback
|
||||
};
|
||||
|
||||
mDebugMessenger = mInstance->createDebugUtilsMessengerEXTUnique(messengerCreateInfo, nullptr);
|
||||
mDebugMessenger = DebugMessenger::create(mInstance.get());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1188,7 +1077,6 @@ class VulkanApp {
|
|||
|
||||
vk::PipelineColorBlendStateCreateInfo colorBlending {
|
||||
.logicOpEnable = vk::False,
|
||||
.logicOp = vk::LogicOp::eCopy,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments = &colorBlendAttachment,
|
||||
.blendConstants = std::array<f32, 4> { 0.0F, 0.0F, 0.0F, 0.0F },
|
||||
|
|
10
src/structs/camera_info.hpp
Normal file
10
src/structs/camera_info.hpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
/**
|
||||
* @brief Struct containing camera information for shading.
|
||||
*/
|
||||
struct CameraInfo {
|
||||
alignas(16) glm::vec3 position; ///< Camera position in world space
|
||||
};
|
13
src/structs/light_info.hpp
Normal file
13
src/structs/light_info.hpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
/**
|
||||
* @brief Struct containing light information for shading.
|
||||
*/
|
||||
struct LightInfo {
|
||||
alignas(16) glm::vec3 position; ///< Light position
|
||||
alignas(16) glm::vec3 color; ///< Light color
|
||||
alignas(4) float ambient_strength; ///< Ambient strength
|
||||
alignas(4) float specular_strength; ///< Specular strength
|
||||
};
|
23
src/structs/queue_family_indices.hpp
Normal file
23
src/structs/queue_family_indices.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include "../util/types.hpp"
|
||||
|
||||
/**
|
||||
* @brief Struct to store queue family indices.
|
||||
*
|
||||
* This struct contains the indices of the graphics and presentation queue families.
|
||||
*/
|
||||
struct QueueFamilyIndices {
|
||||
std::optional<u32> graphics_family; ///< Index of graphics queue family
|
||||
std::optional<u32> present_family; ///< Index of presentation queue family
|
||||
|
||||
/**
|
||||
* @brief Check if all required queue families are found.
|
||||
*
|
||||
* @return True if both graphics and presentation families are found, false otherwise.
|
||||
*/
|
||||
[[nodiscard]] fn isComplete() const -> bool {
|
||||
return graphics_family.has_value() && present_family.has_value();
|
||||
}
|
||||
};
|
16
src/structs/swap_chain_support_details.hpp
Normal file
16
src/structs/swap_chain_support_details.hpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
/**
|
||||
* @brief Struct to hold swap chain support details.
|
||||
*
|
||||
* This struct contains information about the surface capabilities,
|
||||
* supported formats, and presentation modes.
|
||||
*/
|
||||
struct SwapChainSupportDetails {
|
||||
vk::SurfaceCapabilitiesKHR capabilities; ///< Surface capabilities
|
||||
std::vector<vk::SurfaceFormatKHR> formats; ///< Supported surface formats
|
||||
std::vector<vk::PresentModeKHR> present_modes; ///< Supported presentation modes
|
||||
};
|
14
src/structs/uniform_buffer_object.hpp
Normal file
14
src/structs/uniform_buffer_object.hpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
/**
|
||||
* @brief Struct representing a uniform buffer object.
|
||||
*
|
||||
* This struct holds the model, view, and projection matrices for use in shaders.
|
||||
*/
|
||||
struct UniformBufferObject {
|
||||
alignas(16) glm::mat4 model; ///< Model transformation matrix
|
||||
alignas(16) glm::mat4 view; ///< View transformation matrix
|
||||
alignas(16) glm::mat4 proj; ///< Projection matrix
|
||||
};
|
Loading…
Reference in a new issue