16#define GLFW_INCLUDE_VULKAN
17#include <GLFW/glfw3.h>
19#include <unordered_map>
37#define MATH_FORCE_DEPTH_ZERO_TO_ONE
41inline const char*
TITLE =
"scop";
48 "VK_LAYER_KHRONOS_validation",
50 "VK_LAYER_MESA_overlay",
55 VK_KHR_SWAPCHAIN_EXTENSION_NAME
64VkResult
CreateDebugUtilsMessengerEXT(VkInstance instance,
const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger);
108 VkVertexInputBindingDescription bindingDescription{};
109 bindingDescription.binding = 0;
110 bindingDescription.stride =
sizeof(
Vertex);
111 bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
113 return bindingDescription;
117 std::array<VkVertexInputAttributeDescription, 7> attributeDescriptions{};
119 attributeDescriptions[0].binding = 0;
120 attributeDescriptions[0].location = 0;
121 attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
122 attributeDescriptions[0].offset = offsetof(
Vertex,
pos);
124 attributeDescriptions[1].binding = 0;
125 attributeDescriptions[1].location = 1;
126 attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
127 attributeDescriptions[1].offset = offsetof(
Vertex,
color);
129 attributeDescriptions[2].binding = 0;
130 attributeDescriptions[2].location = 2;
131 attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
134 attributeDescriptions[3].binding = 0;
135 attributeDescriptions[3].location = 3;
136 attributeDescriptions[3].format = VK_FORMAT_R32G32B32_SFLOAT;
139 attributeDescriptions[4].binding = 0;
140 attributeDescriptions[4].location = 4;
141 attributeDescriptions[4].format = VK_FORMAT_R32G32B32_SFLOAT;
144 attributeDescriptions[5].binding = 0;
145 attributeDescriptions[5].location = 5;
146 attributeDescriptions[5].format = VK_FORMAT_R32_SFLOAT;
149 attributeDescriptions[6].binding = 0;
150 attributeDescriptions[6].location = 6;
151 attributeDescriptions[6].format = VK_FORMAT_R32_SFLOAT;
154 return attributeDescriptions;
194 void run(
const std::string& objFile1);
200 vec3(5.0f, 0.0f, 5.0f),
201 vec3(0.0f, 0.0f, 0.0f),
202 vec3(0.0f, 1.0f, 0.0f)
290 VkPrimitiveTopology
topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
365 uint32_t
findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
366 void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory);
367 void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size);
381 void createImage(uint32_t width, uint32_t height, uint32_t
mipLevels, VkSampleCountFlagBits numSamples, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory);
383 void copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height);
389 VkFormat
findSupportedFormat(
const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
398 void parseMtlFile(
const std::string& objFilePath,
const std::string& mtlFilename);
399 static std::vector<char>
readFile(
const std::string& filename);
403 auto app =
reinterpret_cast<VulkanApp*
>(glfwGetWindowUserPointer(
window));
405 if ((action == GLFW_PRESS || action == GLFW_REPEAT) && !(mods & GLFW_MOD_SHIFT)) {
412 app->cameraView.center +=
vec3(0, -1, 0);
415 app->cameraView.center +=
vec3(0, 0, 1);
418 app->cameraView.center +=
vec3(0, 0, -1);
422 app->positionModel +=
vec3(1.0f, 0.0f, 0.0f);
425 app->positionModel +=
vec3(0.0f, 1.0f, 0.0f);
428 app->positionModel +=
vec3(0.0f, 0.0f, 1.0f);
432 app->rotationModel +=
vec3(1.0f, 0.0f, 0.0f);
435 app->rotationModel +=
vec3(0.0f, 1.0f, 0.0f);
438 app->rotationModel +=
vec3(0.0f, 0.0f, 1.0f);
442 app->positionModel =
vec3(0.0f, 0.0f, 0.0f);
443 app->rotationModel =
vec3(0.0f, 0.0f, 0.0f);
444 app->cameraView.center =
vec3(0.0f, 0.0f, 0.0f);
448 for (
auto& vertex : app->vertices) {
449 if (app->colorMode ==
NONE)
450 vertex.original_color = vertex.color;
451 vertex.color =
vec3(0, 0, 0);
453 app->colorMode =
BLACK;
454 app->updateVertexBuffer();
458 for (
auto& vertex : app->vertices) {
459 if (app->colorMode ==
NONE)
460 vertex.original_color = vertex.color;
461 vertex.color =
vec3(1, 0.3, 0.3);
463 app->updateVertexBuffer();
464 app->colorMode =
RED;
467 for (
auto& vertex : app->vertices) {
468 if (app->colorMode ==
NONE)
469 vertex.original_color = vertex.color;
470 vertex.color =
vec3(0.3, 1, 0.3);
472 app->colorMode =
GREEN;
473 app->updateVertexBuffer();
476 for (
auto& vertex : app->vertices) {
477 if (app->colorMode ==
NONE)
478 vertex.original_color = vertex.color;
479 vertex.color =
vec3(0.3, 0.3, 1);
481 app->colorMode =
BLUE;
482 app->updateVertexBuffer();
485 app->enableDarkMode();
486 app->updateVertexBuffer();
489 app->disable_textures = !app->disable_textures;
490 app->transition_over =
false;
493 if (app->colorMode !=
NONE) {
494 app->colorMode =
NONE;
496 for (
auto& vertex : app->vertices) {
497 vertex.color = vertex.original_color;
499 app->updateVertexBuffer();
503 if (app->topology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) {
504 app->topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
505 }
else if (app->topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST) {
506 app->topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
508 app->topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
510 vkDestroyPipeline(app->device, app->graphicsPipeline,
nullptr);
511 app->createGraphicsPipeline();
516 }
else if ((action == GLFW_PRESS || action == GLFW_REPEAT) && (mods & GLFW_MOD_SHIFT)) {
520 app->positionModel +=
vec3(-1.0f, 0.0f, 0.0f);
523 app->positionModel +=
vec3(0.0f, -1.0f, 0.0f);
526 app->positionModel +=
vec3(0.0f, 0.0f, -1.0f);
530 app->rotationModel +=
vec3(-1.0f, 0.0f, 0.0f);
533 app->rotationModel +=
vec3(0.0f, -1.0f, 0.0f);
536 app->rotationModel +=
vec3(0.0f, 0.0f, -1.0f);
548 if (button == GLFW_MOUSE_BUTTON_LEFT) {
549 if (action == GLFW_PRESS) {
552 }
else if (action == GLFW_RELEASE) {
562 float deltaX =
static_cast<float>(xpos - app->
lastMouseX);
563 float deltaY =
static_cast<float>(ypos - app->
lastMouseY);
576 uint32_t queueFamilyCount = 0;
577 vkGetPhysicalDeviceQueueFamilyProperties(
device, &queueFamilyCount,
nullptr);
579 std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
580 vkGetPhysicalDeviceQueueFamilyProperties(
device, &queueFamilyCount, queueFamilies.data());
583 for (
const auto& queueFamily : queueFamilies) {
584 if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
588 VkBool32 presentSupport =
false;
589 vkGetPhysicalDeviceSurfaceSupportKHR(
device, i,
surface, &presentSupport);
591 if (presentSupport) {
605 static VKAPI_ATTR VkBool32 VKAPI_CALL
debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData) {
606 (void)messageSeverity;
609 std::cerr <<
"- Validation layer: " << pCallbackData->pMessage << std::endl;
616 auto app =
reinterpret_cast<VulkanApp*
>(glfwGetWindowUserPointer(
window));
void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks *pAllocator)
const int MAX_FRAMES_IN_FLIGHT
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pDebugMessenger)
const std::vector< const char * > validationLayers
const std::vector< const char * > deviceExtensions
static std::vector< char > readFile(const std::string &filename)
void createDescriptorSets()
std::vector< uint32_t > indices
void createDepthResources()
VkSampleCountFlagBits msaaSamples
void createVertexBuffer()
void createGraphicsPipeline()
static void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device)
VkImageView textureImageView
void createImage(uint32_t width, uint32_t height, uint32_t mipLevels, VkSampleCountFlagBits numSamples, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage &image, VkDeviceMemory &imageMemory)
void updateVertexBuffer()
std::vector< VkDeviceMemory > uniformBuffersMemory
VkPhysicalDevice physicalDevice
void createColorResources()
VkFormat findSupportedFormat(const std::vector< VkFormat > &candidates, VkImageTiling tiling, VkFormatFeatureFlags features)
void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size)
void cleanupVertexBuffer()
std::vector< VkSemaphore > renderFinishedSemaphores
VkImageView createImageView(VkImage image, VkFormat format, VkImageAspectFlags aspectFlags, uint32_t mipLevels)
void createTextureImageView()
static void cursorPosCallback(GLFWwindow *window, double xpos, double ypos)
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
bool checkValidationLayerSupport()
VkShaderModule createShaderModule(const std::vector< char > &code)
VkDeviceMemory textureImageMemory
std::vector< VkImage > swapChainImages
VkDeviceMemory colorImageMemory
VkPresentModeKHR chooseSwapPresentMode(const std::vector< VkPresentModeKHR > &availablePresentModes)
void run(const std::string &objFile1)
std::vector< VkFence > inFlightFences
std::vector< VkCommandBuffer > commandBuffers
VkPipelineLayout pipelineLayout
void pickPhysicalDevice()
void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer &buffer, VkDeviceMemory &bufferMemory)
std::vector< VkFramebuffer > swapChainFramebuffers
void createDescriptorSetLayout()
void transitionTextures()
VkExtent2D swapChainExtent
VkPipeline graphicsPipeline
std::vector< VkSemaphore > imageAvailableSemaphores
VkDescriptorPool descriptorPool
static void framebufferResizeCallback(GLFWwindow *window, int width, int height)
std::vector< VkBuffer > uniformBuffers
void createTextureImage()
void parseMtlFile(const std::string &objFilePath, const std::string &mtlFilename)
void setupDebugMessenger()
bool hasStencilComponent(VkFormat format)
std::vector< const char * > getRequiredExtensions()
void parseObjFile(const std::string &filename)
bool checkDeviceExtensionSupport(VkPhysicalDevice device)
VkDeviceMemory indexBufferMemory
VkDebugUtilsMessengerEXT debugMessenger
bool isDeviceSuitable(VkPhysicalDevice device)
void copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height)
VkCommandBuffer beginSingleTimeCommands()
VkDeviceMemory vertexBufferMemory
VkDeviceMemory depthImageMemory
VkFormat findDepthFormat()
void createCommandBuffers()
VkPrimitiveTopology topology
static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData)
VkCommandPool commandPool
VkImageView colorImageView
void createUniformBuffers()
std::vector< VkDescriptorSet > descriptorSets
VkImageView depthImageView
void endSingleTimeCommands(VkCommandBuffer commandBuffer)
void createLogicalDevice()
void createFramebuffers()
void createTextureSampler()
void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t mipLevels)
SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device)
std::vector< Vertex > vertices
std::vector< void * > uniformBuffersMapped
std::vector< VkImageView > swapChainImageViews
void generateMipmaps(VkImage image, VkFormat imageFormat, int32_t texWidth, int32_t texHeight, uint32_t mipLevels)
void createDescriptorPool()
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities)
void updateUniformBuffer(uint32_t currentImage)
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex)
void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT &createInfo)
static void mouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
VkDescriptorSetLayout descriptorSetLayout
VkFormat swapChainImageFormat
VkSampleCountFlagBits getMaxUsableSampleCount()
std::optional< uint32_t > graphicsFamily
std::optional< uint32_t > presentFamily
std::vector< VkSurfaceFormatKHR > formats
VkSurfaceCapabilitiesKHR capabilities
std::vector< VkPresentModeKHR > presentModes
std::string material_name
static VkVertexInputBindingDescription getBindingDescription()
static std::array< VkVertexInputAttributeDescription, 7 > getAttributeDescriptions()