#define GLFW_INCLUDE_VULKAN#include <GLFW/glfw3.h>#include <iostream>#include <stdexcept>#include <vector>#include <cstring>#include <cstdlib>const int WIDTH = 800;const int HEIGHT = 600;const std::vector<const char*> validationLayers = {"VK_LAYER_LUNARG_standard_validation"};#ifdef NDEBUGconst bool enableValidationLayers = false;#elseconst bool enableValidationLayers = true;#endifVkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) {auto func = (PFN_vkCreateDebugReportCallbackEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");if (func != nullptr) {return func(instance, pCreateInfo, pAllocator, pCallback);} else {return VK_ERROR_EXTENSION_NOT_PRESENT;}}void DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator) {auto func = (PFN_vkDestroyDebugReportCallbackEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");if (func != nullptr) {func(instance, callback, pAllocator);}}struct QueueFamilyIndices {int graphicsFamily = -1;bool isComplete() {return graphicsFamily >= 0;}};class HelloTriangleApplication {public:void run() {initWindow();initVulkan();mainLoop();cleanup();}private:GLFWwindow* window;VkInstance instance;VkDebugReportCallbackEXT callback;VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;VkDevice device;VkQueue graphicsQueue;void initWindow() {glfwInit();glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);}void initVulkan() {createInstance();setupDebugCallback();pickPhysicalDevice();createLogicalDevice();}void mainLoop() {while (!glfwWindowShouldClose(window)) {glfwPollEvents();}}void cleanup() {vkDestroyDevice(device, nullptr);if (enableValidationLayers) {DestroyDebugReportCallbackEXT(instance, callback, nullptr);}vkDestroyInstance(instance, nullptr);glfwDestroyWindow(window);glfwTerminate();}void createInstance() {if (enableValidationLayers && !checkValidationLayerSupport()) {throw std::runtime_error("validation layers requested, but not available!");}VkApplicationInfo appInfo = {};appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;appInfo.pApplicationName = "Hello Triangle";appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);appInfo.pEngineName = "No Engine";appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);appInfo.apiVersion = VK_API_VERSION_1_0;VkInstanceCreateInfo createInfo = {};createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;createInfo.pApplicationInfo = &appInfo;auto extensions = getRequiredExtensions();createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());createInfo.ppEnabledExtensionNames = extensions.data();if (enableValidationLayers) {createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());createInfo.ppEnabledLayerNames = validationLayers.data();} else {createInfo.enabledLayerCount = 0;}if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {throw std::runtime_error("failed to create instance!");}}void setupDebugCallback() {if (!enableValidationLayers) return;VkDebugReportCallbackCreateInfoEXT createInfo = {};createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;createInfo.pfnCallback = debugCallback;if (CreateDebugReportCallbackEXT(instance, &createInfo, nullptr, &callback) != VK_SUCCESS) {throw std::runtime_error("failed to set up debug callback!");}}void pickPhysicalDevice() {uint32_t deviceCount = 0;vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);if (deviceCount == 0) {throw std::runtime_error("failed to find GPUs with Vulkan support!");}std::vector<VkPhysicalDevice> devices(deviceCount);vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());for (const auto& device : devices) {if (isDeviceSuitable(device)) {physicalDevice = device;break;}}if (physicalDevice == VK_NULL_HANDLE) {throw std::runtime_error("failed to find a suitable GPU!");}}void createLogicalDevice() {QueueFamilyIndices indices = findQueueFamilies(physicalDevice);VkDeviceQueueCreateInfo queueCreateInfo = {};queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;queueCreateInfo.queueFamilyIndex = indices.graphicsFamily;queueCreateInfo.queueCount = 1;float queuePriority = 1.0f;queueCreateInfo.pQueuePriorities = &queuePriority;VkPhysicalDeviceFeatures deviceFeatures = {};VkDeviceCreateInfo createInfo = {};createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;createInfo.pQueueCreateInfos = &queueCreateInfo;createInfo.queueCreateInfoCount = 1;createInfo.pEnabledFeatures = &deviceFeatures;createInfo.enabledExtensionCount = 0;if (enableValidationLayers) {createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());createInfo.ppEnabledLayerNames = validationLayers.data();} else {createInfo.enabledLayerCount = 0;}if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {throw std::runtime_error("failed to create logical device!");}vkGetDeviceQueue(device, indices.graphicsFamily, 0, &graphicsQueue);}bool isDeviceSuitable(VkPhysicalDevice device) {QueueFamilyIndices indices = findQueueFamilies(device);return indices.isComplete();}QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) {QueueFamilyIndices indices;uint32_t queueFamilyCount = 0;vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());int i = 0;for (const auto& queueFamily : queueFamilies) {if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {indices.graphicsFamily = i;}if (indices.isComplete()) {break;}i++;}return indices;}std::vector<const char*> getRequiredExtensions() {uint32_t glfwExtensionCount = 0;const char** glfwExtensions;glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);std::vector<const char*> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);if (enableValidationLayers) {extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);}return extensions;}bool checkValidationLayerSupport() {uint32_t layerCount;vkEnumerateInstanceLayerProperties(&layerCount, nullptr);std::vector<VkLayerProperties> availableLayers(layerCount);vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());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;}static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userData) {std::cerr << "validation layer: " << msg << std::endl;return VK_FALSE;}};int main() {HelloTriangleApplication app;try {app.run();} catch (const std::runtime_error& e) {std::cerr << e.what() << std::endl;return EXIT_FAILURE;}return EXIT_SUCCESS;}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。