118 lines
4.1 KiB
C++
118 lines
4.1 KiB
C++
|
|
#pragma once
|
|
|
|
#define GLFW_INCLUDE_VULKAN
|
|
#include <GLFW/glfw3.h>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
#include <cstdlib>
|
|
#include <vector>
|
|
#include <optional>
|
|
#include <set>
|
|
|
|
struct QueueFamilyIndices {
|
|
std::optional<uint32_t> graphicsFamily;
|
|
std::optional<uint32_t> presentFamily;
|
|
|
|
bool isComplete() {
|
|
return graphicsFamily.has_value() && presentFamily.has_value();
|
|
}
|
|
};
|
|
|
|
class Application
|
|
{
|
|
private:
|
|
std::vector<char> readFile(const std::string &enginePath)
|
|
{
|
|
std::ifstream file{enginePath, std::ios::ate | std::ios::binary};
|
|
|
|
if (!file.is_open())
|
|
{
|
|
throw std::runtime_error("failed to open file: " + enginePath);
|
|
}
|
|
|
|
size_t fileSize = static_cast<size_t>(file.tellg());
|
|
std::vector<char> buffer(fileSize);
|
|
|
|
file.seekg(0);
|
|
file.read(buffer.data(), fileSize);
|
|
file.close();
|
|
return buffer;
|
|
}
|
|
VkShaderModule createShaderModule(const std::vector<char> &code)
|
|
{
|
|
VkShaderModuleCreateInfo createInfo{};
|
|
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
|
createInfo.codeSize = code.size();
|
|
createInfo.pCode = reinterpret_cast<const uint32_t *>(code.data());
|
|
|
|
VkShaderModule shaderModule;
|
|
if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS)
|
|
{
|
|
throw std::runtime_error("failed to create shader module!");
|
|
}
|
|
|
|
return shaderModule;
|
|
}
|
|
|
|
public:
|
|
void run();
|
|
|
|
private:
|
|
GLFWwindow *window;
|
|
VkInstance instance;
|
|
|
|
void initWindow();
|
|
void createSurface();
|
|
void initVulkan();
|
|
void mainLoop();
|
|
void cleanup();
|
|
void createInstance();
|
|
void createImageViews();
|
|
void createFramebuffers();
|
|
void createCommandPool();
|
|
void createCommandBuffer();
|
|
void setupDebugMessenger();
|
|
void pickPhysicalDevice();
|
|
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
|
|
bool isDeviceSuitable(VkPhysicalDevice device);
|
|
bool checkSwapChainSupport(VkPhysicalDevice device);
|
|
bool checkDeviceExtensionSupport(VkPhysicalDevice device);
|
|
bool checkValidationLayerSupport();
|
|
void createLogicalDevice();
|
|
void createSwapChain();
|
|
void createPipelineLayout();
|
|
void createGraphicsPipeline();
|
|
void createRenderPass();
|
|
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex);
|
|
void createSyncObjects();
|
|
void drawFrame();
|
|
private:
|
|
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; // 物理设备
|
|
VkDevice device; // 逻辑设备
|
|
VkQueue graphicsQueue; // 图形队列
|
|
VkSurfaceKHR surface; // 窗口表面
|
|
VkSwapchainKHR swapChain; // 交换链
|
|
std::vector<VkImage> swapChainImages; // 交换链图像
|
|
VkFormat swapChainImageFormat; // 交换链图像格式
|
|
VkExtent2D swapChainExtent; // 交换链图像分辨率
|
|
std::vector<VkImageView> swapChainImageViews; // 交换链图像视图
|
|
VkRenderPass renderPass; // 渲染流程
|
|
VkPipelineLayout pipelineLayout; // 管线布局
|
|
VkPipeline graphicsPipeline; // 图形管线
|
|
std::vector<VkFramebuffer> swapChainFramebuffers; // 帧缓冲区
|
|
VkCommandPool commandPool; // 命令池
|
|
VkCommandBuffer commandBuffer; // 命令缓冲区
|
|
VkSemaphore imageAvailableSemaphore; // 图像可用信号量
|
|
VkSemaphore renderFinishedSemaphore; // 渲染完成信号量
|
|
VkFence inFlightFence; // 同步栅栏
|
|
VkQueue presentQueue; // 呈现队列
|
|
VkDebugUtilsMessengerEXT debugMessenger;
|
|
const std::vector<const char*> validationLayers = {
|
|
"VK_LAYER_KHRONOS_validation"
|
|
};
|
|
const int kWidth = 480;
|
|
const int kHeight = 480;
|
|
}; |