more updates
This commit is contained in:
parent
545975d6bb
commit
780a7301f5
|
@ -20,6 +20,7 @@ IndentWidth: 2
|
|||
NamespaceIndentation: All
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpacesBeforeTrailingComments: 1
|
||||
Standard: Latest
|
||||
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
|
|
128
src/main.cpp
128
src/main.cpp
|
@ -1,41 +1,59 @@
|
|||
// Time measurements
|
||||
#include <chrono>
|
||||
// String formatting
|
||||
#include <fmt/format.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
// Make depth go from 0 to 1 instead of -1 to 1
|
||||
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
// Provides various math-related data structures
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtx/hash.hpp>
|
||||
|
||||
// Used to load models
|
||||
#define TINYOBJLOADER_IMPLEMENTATION
|
||||
#include <tiny_obj_loader.h>
|
||||
|
||||
// Dynamic function loading
|
||||
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
|
||||
// Use the beta extensions
|
||||
#define VK_ENABLE_BETA_EXTENSIONS
|
||||
// Use {} instead of ()
|
||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
||||
// Vulkan itself
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
// Needed for dynamic function loading to work
|
||||
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
||||
|
||||
// Type aliases
|
||||
#include "util/types.h"
|
||||
|
||||
// STB image helper
|
||||
#include "util/unique_image.h"
|
||||
|
||||
#define VKFW_NO_STD_FUNCTION_CALLBACKS
|
||||
// Vertex class
|
||||
#include "util/vertex.h"
|
||||
|
||||
// Use {} instead of ()
|
||||
#define VKFW_NO_STRUCT_CONSTRUCTORS
|
||||
// GLFW C++ wrapper
|
||||
#include "vkfw.hpp"
|
||||
|
||||
// Initial width and height
|
||||
constexpr i32 WIDTH = 800;
|
||||
constexpr i32 HEIGHT = 600;
|
||||
|
||||
// Paths for the model and texture to render
|
||||
constexpr const char* MODEL_PATH = "models/viking_room.obj";
|
||||
constexpr const char* TEXTURE_PATH = "textures/viking_room.png";
|
||||
|
||||
// Paths for the shaders
|
||||
constexpr const char* FRAGMENT_SHADER_PATH = "shaders/frag.spv";
|
||||
constexpr const char* VERTEX_SHADER_PATH = "shaders/vert.spv";
|
||||
|
||||
// Maximum number of frames to be worked on at the same time
|
||||
constexpr i32 MAX_FRAMES_IN_FLIGHT = 2;
|
||||
|
||||
constexpr std::array<const char*, 1> validationLayers = { "VK_LAYER_KHRONOS_validation" };
|
||||
|
||||
// macOS requires the portability extension to be enabled
|
||||
#ifdef __APPLE__
|
||||
constexpr std::array<const char*, 2> deviceExtensions = { vk::KHRSwapchainExtensionName,
|
||||
vk::KHRPortabilitySubsetExtensionName };
|
||||
|
@ -43,56 +61,27 @@ constexpr std::array<const char*, 2> deviceExtensions = { vk::KHRSwapchainExtens
|
|||
constexpr std::array<const char*, 1> deviceExtensions = { vk::KHRSwapchainExtensionName };
|
||||
#endif
|
||||
|
||||
// Enable validation layers only in debug mode
|
||||
#ifdef NDEBUG
|
||||
constexpr bool enableValidationLayers = false;
|
||||
#else
|
||||
constexpr bool enableValidationLayers = true;
|
||||
constexpr std::array<const char*, 1> validationLayers = { "VK_LAYER_KHRONOS_validation" };
|
||||
constexpr bool enableValidationLayers = true;
|
||||
#endif
|
||||
|
||||
struct Vertex {
|
||||
glm::vec3 pos;
|
||||
glm::vec3 color;
|
||||
glm::vec2 tex_coord;
|
||||
|
||||
static fn getBindingDescription() -> vk::VertexInputBindingDescription {
|
||||
return { .binding = 0, .stride = sizeof(Vertex), .inputRate = vk::VertexInputRate::eVertex };
|
||||
}
|
||||
|
||||
static fn getAttributeDescriptions() -> std::array<vk::VertexInputAttributeDescription, 3> {
|
||||
using namespace vk;
|
||||
|
||||
return {
|
||||
VertexInputAttributeDescription { 0, 0, Format::eR32G32B32Sfloat, offsetof(Vertex, pos) },
|
||||
VertexInputAttributeDescription { 1, 0, Format::eR32G32B32Sfloat, offsetof(Vertex, color) },
|
||||
VertexInputAttributeDescription { 2, 0, Format::eR32G32Sfloat, offsetof(Vertex, tex_coord) }
|
||||
};
|
||||
}
|
||||
|
||||
fn operator==(const Vertex& other) const->bool {
|
||||
return pos == other.pos && color == other.color && tex_coord == other.tex_coord;
|
||||
}
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<Vertex> {
|
||||
fn operator()(Vertex const& vertex) const->size_t {
|
||||
return ((hash<glm::vec3>()(vertex.pos) ^ (hash<glm::vec3>()(vertex.color) << 1)) >> 1) ^
|
||||
(hash<glm::vec2>()(vertex.tex_coord) << 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class VulkanApp {
|
||||
public:
|
||||
fn run() -> void {
|
||||
// Create window
|
||||
initWindow();
|
||||
// Setup vulkan
|
||||
initVulkan();
|
||||
// Render loop
|
||||
mainLoop();
|
||||
}
|
||||
|
||||
private:
|
||||
vkfw::UniqueInstance mGLFWInstance;
|
||||
vkfw::UniqueInstance mVKFWInstance;
|
||||
vkfw::UniqueWindow mWindow;
|
||||
|
||||
vk::UniqueInstance mInstance;
|
||||
|
@ -101,7 +90,7 @@ class VulkanApp {
|
|||
vk::UniqueSurfaceKHR mSurface;
|
||||
|
||||
vk::PhysicalDevice mPhysicalDevice;
|
||||
vk::SampleCountFlagBits mMsaaSamples = vk::SampleCountFlagBits::e1;
|
||||
vk::SampleCountFlagBits mMsaaSamples;
|
||||
vk::UniqueDevice mDevice;
|
||||
|
||||
vk::Queue mGraphicsQueue;
|
||||
|
@ -195,21 +184,16 @@ class VulkanApp {
|
|||
}
|
||||
|
||||
fn initWindow() -> void {
|
||||
mGLFWInstance = vkfw::initUnique();
|
||||
mVKFWInstance = vkfw::initUnique();
|
||||
|
||||
vkfw::WindowHints hints;
|
||||
|
||||
hints.clientAPI = vkfw::ClientAPI::eNone;
|
||||
vkfw::WindowHints hints { .clientAPI = vkfw::ClientAPI::eNone };
|
||||
|
||||
mWindow = vkfw::createWindowUnique(WIDTH, HEIGHT, "Vulkan", hints);
|
||||
mWindow->setUserPointer(this);
|
||||
mWindow->setFramebufferSizeCallback(framebufferResizeCallback);
|
||||
}
|
||||
|
||||
static fn framebufferResizeCallback(GLFWwindow* window, int /*width*/, int /*height*/) -> void {
|
||||
auto* app = std::bit_cast<VulkanApp*>(glfwGetWindowUserPointer(window));
|
||||
|
||||
app->mFramebufferResized = true;
|
||||
mWindow->callbacks()->on_window_resize =
|
||||
[](const vkfw::Window& window, u32 /*width*/, u32 /*height*/) -> void {
|
||||
std::bit_cast<VulkanApp*>(window.getUserPointer())->mFramebufferResized = true;
|
||||
};
|
||||
}
|
||||
|
||||
fn initVulkan() -> void {
|
||||
|
@ -331,7 +315,7 @@ class VulkanApp {
|
|||
.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance,
|
||||
.pfnUserCallback = debugCallback,
|
||||
.pfnUserCallback = debugCallback
|
||||
};
|
||||
|
||||
mDebugMessenger = mInstance->createDebugUtilsMessengerEXTUnique(messengerCreateInfo, nullptr);
|
||||
|
@ -547,8 +531,8 @@ class VulkanApp {
|
|||
}
|
||||
|
||||
fn createGraphicsPipeline() -> void {
|
||||
std::vector<char> vertShaderCode = readFile("shaders/vert.spv");
|
||||
std::vector<char> fragShaderCode = readFile("shaders/frag.spv");
|
||||
std::vector<char> vertShaderCode = readFile(VERTEX_SHADER_PATH);
|
||||
std::vector<char> fragShaderCode = readFile(FRAGMENT_SHADER_PATH);
|
||||
|
||||
vk::UniqueShaderModule vertShaderModule = createShaderModule(vertShaderCode);
|
||||
vk::UniqueShaderModule fragShaderModule = createShaderModule(fragShaderCode);
|
||||
|
@ -670,10 +654,8 @@ class VulkanApp {
|
|||
fn createCommandPool() -> void {
|
||||
QueueFamilyIndices queueFamilyIndices = findQueueFamilies(mPhysicalDevice);
|
||||
|
||||
vk::CommandPoolCreateInfo poolInfo {
|
||||
.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer,
|
||||
.queueFamilyIndex = queueFamilyIndices.graphics_family.value(),
|
||||
};
|
||||
vk::CommandPoolCreateInfo poolInfo { .flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer,
|
||||
.queueFamilyIndex = queueFamilyIndices.graphics_family.value() };
|
||||
|
||||
mCommandPool = mDevice->createCommandPoolUnique(poolInfo);
|
||||
}
|
||||
|
@ -845,10 +827,15 @@ class VulkanApp {
|
|||
.mipLevel = i,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1 },
|
||||
.dstOffsets =
|
||||
std::array<vk::Offset3D, 2> {
|
||||
{ { .x = 0, .y = 0, .z = 0 },
|
||||
{ .x = mipWidth > 1 ? mipWidth / 2 : 1, .y = mipHeight > 1 ? mipHeight / 2 : 1, .z = 1 } } }
|
||||
.dstOffsets = std::array<vk::Offset3D, 2> { vk::Offset3D {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.z = 0,
|
||||
}, vk::Offset3D {
|
||||
.x = mipWidth > 1 ? mipWidth / 2 : 1,
|
||||
.y = mipHeight > 1 ? mipHeight / 2 : 1,
|
||||
.z = 1,
|
||||
} }
|
||||
};
|
||||
|
||||
commandBuffer->blitImage(
|
||||
|
@ -1653,10 +1640,7 @@ class VulkanApp {
|
|||
};
|
||||
|
||||
fn main() -> i32 {
|
||||
vk::DynamicLoader dynamicLoader;
|
||||
auto vkGetInstanceProcAddr =
|
||||
dynamicLoader.getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init();
|
||||
|
||||
VulkanApp app;
|
||||
|
||||
|
|
52
src/util/vertex.h
Normal file
52
src/util/vertex.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/hash.hpp>
|
||||
|
||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
// Vertex data for the model
|
||||
struct Vertex {
|
||||
// Position of the vertex
|
||||
glm::vec3 pos;
|
||||
// Color of the vertex (in RGB)
|
||||
glm::vec3 color;
|
||||
// Texture coordinates of the vertex
|
||||
glm::vec2 tex_coord;
|
||||
|
||||
// Returns the binding description for the vertex
|
||||
static fn getBindingDescription() -> vk::VertexInputBindingDescription {
|
||||
return { .binding = 0, .stride = sizeof(Vertex), .inputRate = vk::VertexInputRate::eVertex };
|
||||
}
|
||||
|
||||
// Returns the attribute descriptions for the vertex
|
||||
static fn getAttributeDescriptions() -> std::array<vk::VertexInputAttributeDescription, 3> {
|
||||
return {
|
||||
// Position attribute
|
||||
vk::VertexInputAttributeDescription { 0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, pos) },
|
||||
// Color attribute
|
||||
vk::VertexInputAttributeDescription { 1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, color) },
|
||||
// Texture coordinate attribute
|
||||
vk::VertexInputAttributeDescription { 2, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, tex_coord) }
|
||||
};
|
||||
}
|
||||
|
||||
// Overload the equality operator for the vertex
|
||||
fn operator==(const Vertex& other) const->bool {
|
||||
return pos == other.pos && color == other.color && tex_coord == other.tex_coord;
|
||||
}
|
||||
};
|
||||
|
||||
// Hash function for the vertex
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<Vertex> {
|
||||
fn operator()(Vertex const& vertex) const->size_t {
|
||||
return ((hash<glm::vec3>()(vertex.pos) ^ (hash<glm::vec3>()(vertex.color) << 1)) >> 1) ^
|
||||
(hash<glm::vec2>()(vertex.tex_coord) << 1);
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue