int main(int argc, char** argv) { uint32_t vkExtensionCount = 0; Test1 test1; glfwInit(); if (glfwVulkanSupported() != GLFW_TRUE){ glfwTerminate(); //Send some message return 1; } glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); try{ test1.run(); }catch(const std::runtime_error& e){ std::cout << e.what() << std::endl; glfwTerminate(); return 1; } //vkEnumerateInstanceExtensionProperties(nullptr, &vkExtensionCount, nullptr); //std::cout << vkExtensionCount << " supported extensions." << std::endl; glfwTerminate(); return 0; }
ContextInitializer::ContextInitializer() { assert(glfwInit()); assert(glfwVulkanSupported()); mExtensions = glfwGetRequiredInstanceExtensions(&mCountExtensions); }
R3VAPI void test() { r3dVoxel::ILogger* test = r3vGetLogger("test"); r3dVoxel::IGameEngine* engine = r3vInitialize(); test->log(r3dVoxel::ELoggingLevel::DEBUG, "engine started at {0}", engine); test->log(r3dVoxel::ELoggingLevel::INFO, "Vulkan supported? {0:I}", glfwVulkanSupported()); unsigned extCount = 0; const char** extensions = glfwGetRequiredInstanceExtensions(&extCount); test->log(r3dVoxel::ELoggingLevel::DEBUG, "Got {0} extensions available.", extCount); for(unsigned i = 0; i < extCount; i++) test->log(r3dVoxel::ELoggingLevel::DEBUG, " #{0}: {1}", i, extensions[i]); auto _vkCreateInstance = (PFN_vkCreateInstance)glfwGetInstanceProcAddress(nullptr, "vkCreateInstance"); VkInstanceCreateInfo ici{}; ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; ici.enabledExtensionCount = extCount; ici.ppEnabledExtensionNames = extensions; VkInstance instance; if(VkResult error = _vkCreateInstance(&ici, nullptr, &instance)) { test->log(r3dVoxel::ELoggingLevel::SEVERE, "vkCreateInstance() failed with {0}", error); return; } glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* win = glfwCreateWindow(800, 600, "test", nullptr, nullptr); VkSurfaceKHR surface; if(VkResult error = glfwCreateWindowSurface(instance, win, nullptr, &surface)) { test->log(r3dVoxel::ELoggingLevel::SEVERE, "glfwCreateWindowSurface() failed with {0}", error); return; } while(!glfwWindowShouldClose(win)) { glfwPollEvents(); } auto _vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)glfwGetInstanceProcAddress(instance, "vkDestroySurfaceKHR"); _vkDestroySurfaceKHR(instance, surface, nullptr); glfwDestroyWindow(win); }
bool Application::create(std::string windowName,uint32_t width,uint32_t height) { m_width = width; m_height = height; glfwInit(); if(!glfwVulkanSupported()) { return false; } glfwWindowHint(GLFW_CLIENT_API,GLFW_NO_API); m_window = glfwCreateWindow(m_width,m_height,"test_vulkan",nullptr,nullptr); unsigned int glfwExtensionsCount; const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionsCount); std::vector<const char*> extensions(glfwExtensionsCount); for(size_t i=0;i<glfwExtensionsCount;++i) { extensions[i]=glfwExtensions[i]; } return initialize(extensions,m_window); }
// -------------------------------------------------------------------------------------------------------------------- window::builder::builder(/*allocator*/) : _win(nullptr) , _name("Marbles") , _width(1280) , _height(720) , _fullscreen(false) , _validation(false) { _pre.reserve(8); _pre.push_back(async(launch::deferred, [this]() -> int { glfwDefaultWindowHints(); if (glfwVulkanSupported()) { glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); // use vulkan } return 0; })); _post.reserve(8); _post.push_back(async(launch::deferred, [this]() -> int { GLFWwindow* glfwWin = this->_win->_internal->_window; glfwSetWindowUserPointer(glfwWin, this->_win); glfwSetWindowPosCallback(glfwWin, [](GLFWwindow* glfwWin, int x, int y) { window* win = reinterpret_cast<window*>(glfwGetWindowUserPointer(glfwWin)); win->onReposition(win, x, y); }); glfwSetWindowCloseCallback(glfwWin, [](GLFWwindow* glfwWin) { window* win = reinterpret_cast<window*>(glfwGetWindowUserPointer(glfwWin)); win->onClose(win); }); return 0; })); }
int main(int argc, char** argv) { g_validationLayers = std::vector<const char*> { "VK_LAYER_LUNARG_mem_tracker", "VK_LAYER_GOOGLE_unique_objects", }; // Init GLFW { // Handle GLFW errors glfwSetErrorCallback([](int error, const char* description) { std::cout << "GLFW error: " << error << " - " << description << std::endl; }); // Initialize GLFW if (!glfwInit()) error("Cannot initialize GLFW."); // Check Vulkan support if (!glfwVulkanSupported()) error("Cannot find compatible Vulkan client driver."); } // Get Validation layers { uint32_t numInstanceLayers = 0; // Get numInstanceLayers if (vkEnumerateInstanceLayerProperties(&numInstanceLayers, nullptr)) error("Vulkan: Could not enumerate instance layer properties."); if (numInstanceLayers > 0) { std::vector<VkLayerProperties> instanceLayers(numInstanceLayers); if (vkEnumerateInstanceLayerProperties(&numInstanceLayers, instanceLayers.data())) error("Vulkan: Could not enumerate instance layer properties."); // Print layers: std::cout << "Validation layers: " << std::endl; for (int i = 0; i < numInstanceLayers; ++i) { std::cout << "\t" << instanceLayers[i].layerName << std::endl; std::cout << "\t\t" << instanceLayers[i].description << std::endl; std::cout << std::endl; } std::cout << std::endl; } else std::cout << "No validation layers found!" << std::endl; // TODO: Check Layers } // Check instance extensions { int numRequiredExtensions; const char** requiredExtensions; // Get required extensions from GLFW { requiredExtensions = glfwGetRequiredInstanceExtensions((int*)&numRequiredExtensions); if (numRequiredExtensions > 0) { // Write to global g_extensions for (int i = 0; i < numRequiredExtensions; ++i) g_extensions.push_back(requiredExtensions[i]); // Print std::cout << "Required Instance Extensions(GLFW):" << std::endl; for (int i = 0; i < numRequiredExtensions; ++i) { std::cout << "\t" << requiredExtensions[i] << std::endl; } std::cout << std::endl; } // TODO: Check extensions } // Get Instance extensions { VkResult err; uint32_t numInstanceExtensions; err = vkEnumerateInstanceExtensionProperties(nullptr, &numInstanceExtensions, nullptr); if (numInstanceExtensions > 0) { std::vector<VkExtensionProperties> instanceExtensions(numInstanceExtensions); err = vkEnumerateInstanceExtensionProperties(NULL, &numInstanceExtensions, instanceExtensions.data()); // Print std::cout << "Instance Extensions: " << std::endl; for (int i = 0; i < numInstanceExtensions; ++i) { std::cout << "\t" <<instanceExtensions[i].extensionName << std::endl; std::cout << "\t\t" << instanceExtensions[i].specVersion << std::endl; std::cout << std::endl; } std::cout << std::endl; } // TODO: Check instance extensions(with required instance extensions) } } // Create Vulkan Instance { VkApplicationInfo app; { app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; app.pNext = nullptr; app.pApplicationName = "Vulkan test 1"; app.applicationVersion = 0; app.pEngineName = "Vulkan test 1"; app.engineVersion = 0; app.apiVersion = VK_API_VERSION; } VkInstanceCreateInfo instanceInfo; { instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instanceInfo.pNext = nullptr; instanceInfo.pApplicationInfo = &app; instanceInfo.enabledLayerCount = g_validationLayers.size(); instanceInfo.ppEnabledLayerNames = g_validationLayers.data(); instanceInfo.enabledExtensionCount = g_extensions.size(); instanceInfo.ppEnabledExtensionNames = g_extensions.data(); } // TODO: Aligned allocators VkAllocationCallbacks allocator; { allocator.pUserData = nullptr; allocator.pfnAllocation = [](void* pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)->void* { return malloc(size); }; allocator.pfnFree = [](void* pUserData, void* pMemory) { free(pMemory); }; allocator.pfnReallocation = [](void* pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope) { free(pOriginal); return malloc(size); }; allocator.pfnInternalAllocation = nullptr; allocator.pfnInternalFree = nullptr; allocator.pfnReallocation = nullptr; } // Create vulkan instance VkResult vkError = vkCreateInstance(&instanceInfo, &allocator, &g_vkInstance); // Handle errors switch (vkError) { case VK_ERROR_INCOMPATIBLE_DRIVER: error("Drivers do not support vulkan. Drivers could be outdated."); break; case VK_ERROR_EXTENSION_NOT_PRESENT: error("Cannot find specified extension."); break; case VK_SUCCESS: // Succes! (prevent default from catching success as error) std::cout << "Vulkan instance created!" << std::endl; break; default: error("Could not create vulkan Instance. Drivers could be outdated."); break; } } // Look for GPU device { uint32_t numGPUs; VkResult vkError = vkEnumeratePhysicalDevices(g_vkInstance, &numGPUs, nullptr); if (numGPUs < 0) error("vkEnumeratePhysicalDevices could not find any GPU devices."); if (vkError) error("vkEnumeratePhysicalDevices could not enumerate GPU devices."); if (numGPUs > 0) { std::vector<VkPhysicalDevice> physicalDevices(numGPUs); if (vkEnumeratePhysicalDevices(g_vkInstance, &numGPUs, physicalDevices.data())) error("vkEnumeratePhysicalDevices could not enumerate GPU devices."); g_vkGPU = physicalDevices[0]; std::cout << numGPUs << " GPUs found!" << std::endl; } } // Get queue properties { uint32_t numQueues; vkGetPhysicalDeviceProperties(g_vkGPU, &g_vkGPUProperties); vkGetPhysicalDeviceQueueFamilyProperties(g_vkGPU, &numQueues, nullptr); if (numQueues == 0) error("vkGetPhysicalDeviceQueueFamilyProperties could not find any queues."); g_vkQueueProperties = std::vector<VkQueueFamilyProperties>(numQueues); vkGetPhysicalDeviceQueueFamilyProperties(g_vkGPU, &numQueues, g_vkQueueProperties.data()); } // Look for device layers (Unecessary code that does nothing) { uint32_t numDeviceLayers; if (vkEnumerateDeviceLayerProperties(g_vkGPU, &numDeviceLayers, nullptr)) error("vkEnumerateDeviceLayerProperties failed!"); if (numDeviceLayers > 0) { std::vector<VkLayerProperties> deviceLayers(numDeviceLayers); if (vkEnumerateDeviceLayerProperties(g_vkGPU, &numDeviceLayers, deviceLayers.data())) error("vkEnumerateDeviceLayerProperties failed!"); // TODO: Check device layers. } } // Look for device extensions (swapchain extension) { uint32_t numDeviceExtensions; bool extensionSwapChainFound = false; if (vkEnumerateDeviceExtensionProperties(g_vkGPU, nullptr, &numDeviceExtensions, nullptr)) error("vkEnumerateDeviceExtensionProperties failed!"); if (numDeviceExtensions > 0) { std::vector<VkExtensionProperties> deviceExtensions(numDeviceExtensions); if (vkEnumerateDeviceExtensionProperties(g_vkGPU, nullptr, &numDeviceExtensions, deviceExtensions.data())) error("vkEnumerateDeviceExtensionProperties failed!"); // Search for swapchain extension for (VkExtensionProperties extension : deviceExtensions) { if (!strcmp(extension.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME)) extensionSwapChainFound = true; } // Print std::cout << std::endl << "Extensions:" << std::endl; for (VkExtensionProperties extension : deviceExtensions) { std::cout << extension.extensionName << "(" << extension.specVersion << ")" << std::endl; } std::cout << std::endl; } if (!extensionSwapChainFound) error("Failed to find the " VK_KHR_SWAPCHAIN_EXTENSION_NAME " extension!"); } // TODO: Validate // Get instance function adresses { GET_INSTANCE_PROC_ADDR(g_vkInstance, GetPhysicalDeviceSurfaceCapabilitiesKHR); GET_INSTANCE_PROC_ADDR(g_vkInstance, GetPhysicalDeviceSurfaceFormatsKHR); GET_INSTANCE_PROC_ADDR(g_vkInstance, GetPhysicalDeviceSurfacePresentModesKHR); GET_INSTANCE_PROC_ADDR(g_vkInstance, GetPhysicalDeviceSurfaceSupportKHR); GET_INSTANCE_PROC_ADDR(g_vkInstance, CreateSwapchainKHR); GET_INSTANCE_PROC_ADDR(g_vkInstance, DestroySwapchainKHR); GET_INSTANCE_PROC_ADDR(g_vkInstance, GetSwapchainImagesKHR); GET_INSTANCE_PROC_ADDR(g_vkInstance, AcquireNextImageKHR); GET_INSTANCE_PROC_ADDR(g_vkInstance, QueuePresentKHR); } // Create window { glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); g_window = glfwCreateWindow(g_width, g_height, "Vulkan test", NULL, NULL); if (!g_window) error("Could not create window!"); glfwSetWindowRefreshCallback(g_window, [](GLFWwindow* window) { // TODO: draw(); }); glfwSetFramebufferSizeCallback(g_window, [](GLFWwindow* window, int width, int height) { g_width = width; g_height = height; // TODO: resize(); }); } // Init swapchain { glfwCreateWindowSurface(g_vkInstance, g_window, nullptr, &g_vkSurface); std::vector<VkBool32> supportsPresent(g_vkQueueProperties.size()); for (uint32_t i = 0; i < g_vkQueueProperties.size(); ++i) g_vkFPGetPhysicalDeviceSurfaceSupportKHR(g_vkGPU, i, g_vkSurface, &supportsPresent[i]); uint32_t graphicsQueueNodeIndex = UINT32_MAX; uint32_t presentQueueNodeIndex = UINT32_MAX; for (uint32_t i = 0; i < g_vkQueueProperties.size(); ++i) { if (graphicsQueueNodeIndex == UINT32_MAX) { graphicsQueueNodeIndex = i; } if (supportsPresent[i] == VK_TRUE) { graphicsQueueNodeIndex = i; presentQueueNodeIndex = i; break; } } //if (presentQueueNodeIndex == UINT32_MAX) { // for (uint32_t i = 0; i < g_vkQueueProperties.size(); ++i) { // if (supportsPresent[i] == VK_TRUE) { // presentQueueNodeIndex = i; // } // } //} if (graphicsQueueNodeIndex == UINT32_MAX || presentQueueNodeIndex == UINT32_MAX) error("Could not find a graphics and a present queue."); if (graphicsQueueNodeIndex != presentQueueNodeIndex) error("Could not find a common graphics and present queue."); g_vkGraphicsQueueNodeIndex = graphicsQueueNodeIndex; //TODO: init device { float queuePriotities = 0.f; VkDeviceQueueCreateInfo queue; { queue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue.pNext = NULL; queue.queueFamilyIndex = g_vkGraphicsQueueNodeIndex; queue.queueCount = 1; queue.pQueuePriorities = &queuePriotities; } } //vkGetDeviceQueue(g_vkDevice, g_vkGraphicsQueueNodeIndex, 0, g_vkQueue); } std::cin.get(); return 0; }
int main(int, char**) { // Setup window glfwSetErrorCallback(error_callback); if (!glfwInit()) return 1; glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui Vulkan example", NULL, NULL); // Setup Vulkan if (!glfwVulkanSupported()) { printf("GLFW: Vulkan Not Supported\n"); return 1; } setup_vulkan(window); // Setup ImGui binding ImGui_ImplGlfwVulkan_Init_Data init_data = {}; init_data.allocator = g_Allocator; init_data.gpu = g_Gpu; init_data.device = g_Device; init_data.render_pass = g_RenderPass; init_data.pipeline_cache = g_PipelineCache; init_data.descriptor_pool = g_DescriptorPool; init_data.check_vk_result = check_vk_result; ImGui_ImplGlfwVulkan_Init(window, true, &init_data); // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. // - Read 'extra_fonts/README.txt' for more instructions and details. // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //ImGuiIO& io = ImGui::GetIO(); //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); // Upload Fonts { VkResult err; err = vkResetCommandPool(g_Device, g_CommandPool[g_FrameIndex], 0); check_vk_result(err); VkCommandBufferBeginInfo begin_info = {}; begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; err = vkBeginCommandBuffer(g_CommandBuffer[g_FrameIndex], &begin_info); check_vk_result(err); ImGui_ImplGlfwVulkan_CreateFontsTexture(g_CommandBuffer[g_FrameIndex]); VkSubmitInfo end_info = {}; end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; end_info.commandBufferCount = 1; end_info.pCommandBuffers = &g_CommandBuffer[g_FrameIndex]; err = vkEndCommandBuffer(g_CommandBuffer[g_FrameIndex]); check_vk_result(err); err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE); check_vk_result(err); err = vkDeviceWaitIdle(g_Device); check_vk_result(err); ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects(); } bool show_test_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // When IMGUI_UNLIMITED_FRAME_RATE is defined we render into latest image acquired from the swapchain but we display the image which was rendered before. // Hence we must render once and increase the g_FrameIndex without presenting, which we do before entering the render loop. // This is also the reason why frame_end() is split into frame_end() and frame_present(), the later one not being called here. #ifdef IMGUI_UNLIMITED_FRAME_RATE ImGui_ImplGlfwVulkan_NewFrame(); frame_begin(); ImGui_ImplGlfwVulkan_Render(g_CommandBuffer[g_FrameIndex]); frame_end(); g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES; #endif // IMGUI_UNLIMITED_FRAME_RATE // Main loop while (!glfwWindowShouldClose(window)) { // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. glfwPollEvents(); ImGui_ImplGlfwVulkan_NewFrame(); // 1. Show a simple window. // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". { static float f = 0.0f; ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::ColorEdit3("clear color", (float*)&clear_color); if (ImGui::Button("Test Window")) show_test_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello from another window!"); ImGui::End(); } // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). if (show_test_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); ImGui::ShowTestWindow(&show_test_window); } g_ClearValue.color.float32[0] = clear_color.x; g_ClearValue.color.float32[1] = clear_color.y; g_ClearValue.color.float32[2] = clear_color.z; g_ClearValue.color.float32[3] = clear_color.w; frame_begin(); ImGui_ImplGlfwVulkan_Render(g_CommandBuffer[g_FrameIndex]); frame_end(); frame_present(); } // Cleanup VkResult err = vkDeviceWaitIdle(g_Device); check_vk_result(err); ImGui_ImplGlfwVulkan_Shutdown(); cleanup_vulkan(); glfwTerminate(); return 0; }
int main(int, char**) { // Setup window glfwSetErrorCallback(glfw_error_callback); if (!glfwInit()) return 1; glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+Vulkan example", NULL, NULL); // Setup Vulkan if (!glfwVulkanSupported()) { printf("GLFW: Vulkan Not Supported\n"); return 1; } uint32_t extensions_count = 0; const char** extensions = glfwGetRequiredInstanceExtensions(&extensions_count); SetupVulkan(extensions, extensions_count); // Create Window Surface VkSurfaceKHR surface; VkResult err = glfwCreateWindowSurface(g_Instance, window, g_Allocator, &surface); check_vk_result(err); // Create Framebuffers int w, h; glfwGetFramebufferSize(window, &w, &h); glfwSetFramebufferSizeCallback(window, glfw_resize_callback); ImGui_ImplVulkanH_WindowData* wd = &g_WindowData; SetupVulkanWindowData(wd, surface, w, h); // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls // Setup Dear ImGui style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); // Setup Platform/Renderer bindings ImGui_ImplGlfw_InitForVulkan(window, true); ImGui_ImplVulkan_InitInfo init_info = {}; init_info.Instance = g_Instance; init_info.PhysicalDevice = g_PhysicalDevice; init_info.Device = g_Device; init_info.QueueFamily = g_QueueFamily; init_info.Queue = g_Queue; init_info.PipelineCache = g_PipelineCache; init_info.DescriptorPool = g_DescriptorPool; init_info.Allocator = g_Allocator; init_info.CheckVkResultFn = check_vk_result; ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. // - Read 'misc/fonts/README.txt' for more instructions and details. // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); // Upload Fonts { // Use any command queue VkCommandPool command_pool = wd->Frames[wd->FrameIndex].CommandPool; VkCommandBuffer command_buffer = wd->Frames[wd->FrameIndex].CommandBuffer; err = vkResetCommandPool(g_Device, command_pool, 0); check_vk_result(err); VkCommandBufferBeginInfo begin_info = {}; begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; err = vkBeginCommandBuffer(command_buffer, &begin_info); check_vk_result(err); ImGui_ImplVulkan_CreateFontsTexture(command_buffer); VkSubmitInfo end_info = {}; end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; end_info.commandBufferCount = 1; end_info.pCommandBuffers = &command_buffer; err = vkEndCommandBuffer(command_buffer); check_vk_result(err); err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE); check_vk_result(err); err = vkDeviceWaitIdle(g_Device); check_vk_result(err); ImGui_ImplVulkan_InvalidateFontUploadObjects(); } bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Main loop while (!glfwWindowShouldClose(window)) { // Poll and handle events (inputs, window resize, etc.) // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. glfwPollEvents(); if (g_ResizeWanted) { ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, g_ResizeWidth, g_ResizeHeight); g_ResizeWanted = false; } // Start the Dear ImGui frame ImGui_ImplVulkan_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). if (show_demo_window) ImGui::ShowDemoWindow(&show_demo_window); // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. { static float f = 0.0f; static int counter = 0; ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state ImGui::Checkbox("Another Window", &show_another_window); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) counter++; ImGui::SameLine(); ImGui::Text("counter = %d", counter); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); ImGui::End(); } // 3. Show another simple window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) ImGui::Text("Hello from another window!"); if (ImGui::Button("Close Me")) show_another_window = false; ImGui::End(); } // Rendering ImGui::Render(); memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); FrameRender(wd); FramePresent(wd); } // Cleanup err = vkDeviceWaitIdle(g_Device); check_vk_result(err); ImGui_ImplVulkan_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); CleanupVulkan(); glfwDestroyWindow(window); glfwTerminate(); return 0; }
int main(int argc, char** argv) { int ch, client, major, minor, revision, profile; GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits; int list_extensions = GLFW_FALSE, list_layers = GLFW_FALSE; GLenum error; GLFWwindow* window; enum { CLIENT, CONTEXT, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, LAYERS, MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION, REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS, ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS, AUXBUFFERS, SAMPLES, STEREO, SRGB, SINGLEBUFFER, NOERROR_SRSLY }; const struct option options[] = { { "behavior", 1, NULL, BEHAVIOR }, { "client-api", 1, NULL, CLIENT }, { "context-api", 1, NULL, CONTEXT }, { "debug", 0, NULL, DEBUG }, { "forward", 0, NULL, FORWARD }, { "help", 0, NULL, HELP }, { "list-extensions", 0, NULL, EXTENSIONS }, { "list-layers", 0, NULL, LAYERS }, { "major", 1, NULL, MAJOR }, { "minor", 1, NULL, MINOR }, { "profile", 1, NULL, PROFILE }, { "robustness", 1, NULL, ROBUSTNESS }, { "version", 0, NULL, VERSION }, { "red-bits", 1, NULL, REDBITS }, { "green-bits", 1, NULL, GREENBITS }, { "blue-bits", 1, NULL, BLUEBITS }, { "alpha-bits", 1, NULL, ALPHABITS }, { "depth-bits", 1, NULL, DEPTHBITS }, { "stencil-bits", 1, NULL, STENCILBITS }, { "accum-red-bits", 1, NULL, ACCUMREDBITS }, { "accum-green-bits", 1, NULL, ACCUMGREENBITS }, { "accum-blue-bits", 1, NULL, ACCUMBLUEBITS }, { "accum-alpha-bits", 1, NULL, ACCUMALPHABITS }, { "aux-buffers", 1, NULL, AUXBUFFERS }, { "samples", 1, NULL, SAMPLES }, { "stereo", 0, NULL, STEREO }, { "srgb", 0, NULL, SRGB }, { "singlebuffer", 0, NULL, SINGLEBUFFER }, { "no-error", 0, NULL, NOERROR_SRSLY }, { NULL, 0, NULL, 0 } }; // Initialize GLFW and create window if (!valid_version()) exit(EXIT_FAILURE); glfwSetErrorCallback(error_callback); if (!glfwInit()) exit(EXIT_FAILURE); while ((ch = getopt_long(argc, argv, "a:b:c:dfhlm:n:p:s:v", options, NULL)) != -1) { switch (ch) { case 'a': case CLIENT: if (strcasecmp(optarg, API_NAME_OPENGL) == 0) glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); else if (strcasecmp(optarg, API_NAME_OPENGL_ES) == 0) glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); else { usage(); exit(EXIT_FAILURE); } break; case 'b': case BEHAVIOR: if (strcasecmp(optarg, BEHAVIOR_NAME_NONE) == 0) { glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR, GLFW_RELEASE_BEHAVIOR_NONE); } else if (strcasecmp(optarg, BEHAVIOR_NAME_FLUSH) == 0) { glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR, GLFW_RELEASE_BEHAVIOR_FLUSH); } else { usage(); exit(EXIT_FAILURE); } break; case 'c': case CONTEXT: if (strcasecmp(optarg, API_NAME_NATIVE) == 0) glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API); else if (strcasecmp(optarg, API_NAME_EGL) == 0) glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API); else { usage(); exit(EXIT_FAILURE); } break; case 'd': case DEBUG: glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); break; case 'f': case FORWARD: glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); break; case 'h': case HELP: usage(); exit(EXIT_SUCCESS); case 'l': case EXTENSIONS: list_extensions = GLFW_TRUE; break; case LAYERS: list_layers = GLFW_TRUE; break; case 'm': case MAJOR: glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, atoi(optarg)); break; case 'n': case MINOR: glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, atoi(optarg)); break; case 'p': case PROFILE: if (strcasecmp(optarg, PROFILE_NAME_CORE) == 0) { glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); } else if (strcasecmp(optarg, PROFILE_NAME_COMPAT) == 0) { glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE); } else { usage(); exit(EXIT_FAILURE); } break; case 's': case ROBUSTNESS: if (strcasecmp(optarg, STRATEGY_NAME_NONE) == 0) { glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, GLFW_NO_RESET_NOTIFICATION); } else if (strcasecmp(optarg, STRATEGY_NAME_LOSE) == 0) { glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, GLFW_LOSE_CONTEXT_ON_RESET); } else { usage(); exit(EXIT_FAILURE); } break; case 'v': case VERSION: print_version(); exit(EXIT_SUCCESS); case REDBITS: if (strcmp(optarg, "-") == 0) glfwWindowHint(GLFW_RED_BITS, GLFW_DONT_CARE); else glfwWindowHint(GLFW_RED_BITS, atoi(optarg)); break; case GREENBITS: if (strcmp(optarg, "-") == 0) glfwWindowHint(GLFW_GREEN_BITS, GLFW_DONT_CARE); else glfwWindowHint(GLFW_GREEN_BITS, atoi(optarg)); break; case BLUEBITS: if (strcmp(optarg, "-") == 0) glfwWindowHint(GLFW_BLUE_BITS, GLFW_DONT_CARE); else glfwWindowHint(GLFW_BLUE_BITS, atoi(optarg)); break; case ALPHABITS: if (strcmp(optarg, "-") == 0) glfwWindowHint(GLFW_ALPHA_BITS, GLFW_DONT_CARE); else glfwWindowHint(GLFW_ALPHA_BITS, atoi(optarg)); break; case DEPTHBITS: if (strcmp(optarg, "-") == 0) glfwWindowHint(GLFW_DEPTH_BITS, GLFW_DONT_CARE); else glfwWindowHint(GLFW_DEPTH_BITS, atoi(optarg)); break; case STENCILBITS: if (strcmp(optarg, "-") == 0) glfwWindowHint(GLFW_STENCIL_BITS, GLFW_DONT_CARE); else glfwWindowHint(GLFW_STENCIL_BITS, atoi(optarg)); break; case ACCUMREDBITS: if (strcmp(optarg, "-") == 0) glfwWindowHint(GLFW_ACCUM_RED_BITS, GLFW_DONT_CARE); else glfwWindowHint(GLFW_ACCUM_RED_BITS, atoi(optarg)); break; case ACCUMGREENBITS: if (strcmp(optarg, "-") == 0) glfwWindowHint(GLFW_ACCUM_GREEN_BITS, GLFW_DONT_CARE); else glfwWindowHint(GLFW_ACCUM_GREEN_BITS, atoi(optarg)); break; case ACCUMBLUEBITS: if (strcmp(optarg, "-") == 0) glfwWindowHint(GLFW_ACCUM_BLUE_BITS, GLFW_DONT_CARE); else glfwWindowHint(GLFW_ACCUM_BLUE_BITS, atoi(optarg)); break; case ACCUMALPHABITS: if (strcmp(optarg, "-") == 0) glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, GLFW_DONT_CARE); else glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, atoi(optarg)); break; case AUXBUFFERS: if (strcmp(optarg, "-") == 0) glfwWindowHint(GLFW_AUX_BUFFERS, GLFW_DONT_CARE); else glfwWindowHint(GLFW_AUX_BUFFERS, atoi(optarg)); break; case SAMPLES: if (strcmp(optarg, "-") == 0) glfwWindowHint(GLFW_SAMPLES, GLFW_DONT_CARE); else glfwWindowHint(GLFW_SAMPLES, atoi(optarg)); break; case STEREO: glfwWindowHint(GLFW_STEREO, GLFW_TRUE); break; case SRGB: glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_TRUE); break; case SINGLEBUFFER: glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_FALSE); break; case NOERROR_SRSLY: glfwWindowHint(GLFW_CONTEXT_NO_ERROR, GLFW_TRUE); break; default: usage(); exit(EXIT_FAILURE); } } print_version(); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); window = glfwCreateWindow(200, 200, "Version", NULL, NULL); if (!window) { glfwTerminate(); exit(EXIT_FAILURE); } glfwMakeContextCurrent(window); gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); error = glGetError(); if (error != GL_NO_ERROR) printf("*** OpenGL error after make current: 0x%08x ***\n", error); // Report client API version client = glfwGetWindowAttrib(window, GLFW_CLIENT_API); major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR); minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR); revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION); profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE); printf("%s context version string: \"%s\"\n", get_api_name(client), glGetString(GL_VERSION)); printf("%s context version parsed by GLFW: %u.%u.%u\n", get_api_name(client), major, minor, revision); // Report client API context properties if (client == GLFW_OPENGL_API) { if (major >= 3) { GLint flags; glGetIntegerv(GL_CONTEXT_FLAGS, &flags); printf("%s context flags (0x%08x):", get_api_name(client), flags); if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) printf(" forward-compatible"); if (flags & 2/*GL_CONTEXT_FLAG_DEBUG_BIT*/) printf(" debug"); if (flags & GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB) printf(" robustness"); if (flags & 8/*GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR*/) printf(" no-error"); putchar('\n'); printf("%s context flags parsed by GLFW:", get_api_name(client)); if (glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT)) printf(" forward-compatible"); if (glfwGetWindowAttrib(window, GLFW_OPENGL_DEBUG_CONTEXT)) printf(" debug"); if (glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS) == GLFW_LOSE_CONTEXT_ON_RESET) printf(" robustness"); if (glfwGetWindowAttrib(window, GLFW_CONTEXT_NO_ERROR)) printf(" no-error"); putchar('\n'); } if (major >= 4 || (major == 3 && minor >= 2)) { GLint mask; glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); printf("%s profile mask (0x%08x): %s\n", get_api_name(client), mask, get_profile_name_gl(mask)); printf("%s profile mask parsed by GLFW: %s\n", get_api_name(client), get_profile_name_glfw(profile)); } if (GLAD_GL_ARB_robustness) { const int robustness = glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS); GLint strategy; glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy); printf("%s robustness strategy (0x%08x): %s\n", get_api_name(client), strategy, get_strategy_name_gl(strategy)); printf("%s robustness strategy parsed by GLFW: %s\n", get_api_name(client), get_strategy_name_glfw(robustness)); } } printf("%s context renderer string: \"%s\"\n", get_api_name(client), glGetString(GL_RENDERER)); printf("%s context vendor string: \"%s\"\n", get_api_name(client), glGetString(GL_VENDOR)); if (major >= 2) { printf("%s context shading language version: \"%s\"\n", get_api_name(client), glGetString(GL_SHADING_LANGUAGE_VERSION)); } printf("%s framebuffer:\n", get_api_name(client)); if (client == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE) { glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_BACK_LEFT, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, &redbits); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_BACK_LEFT, GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, &greenbits); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_BACK_LEFT, GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, &bluebits); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_BACK_LEFT, GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alphabits); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depthbits); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencilbits); } else { glGetIntegerv(GL_RED_BITS, &redbits); glGetIntegerv(GL_GREEN_BITS, &greenbits); glGetIntegerv(GL_BLUE_BITS, &bluebits); glGetIntegerv(GL_ALPHA_BITS, &alphabits); glGetIntegerv(GL_DEPTH_BITS, &depthbits); glGetIntegerv(GL_STENCIL_BITS, &stencilbits); } printf(" red: %u green: %u blue: %u alpha: %u depth: %u stencil: %u\n", redbits, greenbits, bluebits, alphabits, depthbits, stencilbits); if (client == GLFW_OPENGL_ES_API || GLAD_GL_ARB_multisample || major > 1 || minor >= 3) { GLint samples, samplebuffers; glGetIntegerv(GL_SAMPLES, &samples); glGetIntegerv(GL_SAMPLE_BUFFERS, &samplebuffers); printf(" samples: %u sample buffers: %u\n", samples, samplebuffers); } if (client == GLFW_OPENGL_API && profile != GLFW_OPENGL_CORE_PROFILE) { GLint accumredbits, accumgreenbits, accumbluebits, accumalphabits; GLint auxbuffers; glGetIntegerv(GL_ACCUM_RED_BITS, &accumredbits); glGetIntegerv(GL_ACCUM_GREEN_BITS, &accumgreenbits); glGetIntegerv(GL_ACCUM_BLUE_BITS, &accumbluebits); glGetIntegerv(GL_ACCUM_ALPHA_BITS, &accumalphabits); glGetIntegerv(GL_AUX_BUFFERS, &auxbuffers); printf(" accum red: %u accum green: %u accum blue: %u accum alpha: %u aux buffers: %u\n", accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers); } if (list_extensions) list_context_extensions(client, major, minor); printf("Vulkan loader: %s\n", glfwVulkanSupported() ? "available" : "missing"); if (glfwVulkanSupported()) { uint32_t i, re_count, pd_count; const char** re; VkApplicationInfo ai = {0}; VkInstanceCreateInfo ici = {0}; VkInstance instance; VkPhysicalDevice* pd; PFN_vkCreateInstance vkCreateInstance = (PFN_vkCreateInstance) glfwGetInstanceProcAddress(NULL, "vkCreateInstance"); PFN_vkDestroyInstance vkDestroyInstance; PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices; PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; re = glfwGetRequiredInstanceExtensions(&re_count); printf("Vulkan required instance extensions:"); for (i = 0; i < re_count; i++) printf(" %s", re[i]); putchar('\n'); if (list_extensions) list_vulkan_instance_extensions(); if (list_layers) list_vulkan_instance_layers(); ai.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; ai.pApplicationName = "glfwinfo"; ai.applicationVersion = GLFW_VERSION_MAJOR; ai.pEngineName = "GLFW"; ai.engineVersion = GLFW_VERSION_MAJOR; ai.apiVersion = VK_API_VERSION_1_0; ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; ici.pApplicationInfo = &ai; ici.enabledExtensionCount = re_count; ici.ppEnabledExtensionNames = re; if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS) { glfwTerminate(); exit(EXIT_FAILURE); } vkDestroyInstance = (PFN_vkDestroyInstance) glfwGetInstanceProcAddress(instance, "vkDestroyInstance"); vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) glfwGetInstanceProcAddress(instance, "vkEnumeratePhysicalDevices"); vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) glfwGetInstanceProcAddress(instance, "vkGetPhysicalDeviceProperties"); if (vkEnumeratePhysicalDevices(instance, &pd_count, NULL) != VK_SUCCESS) { vkDestroyInstance(instance, NULL); glfwTerminate(); exit(EXIT_FAILURE); } pd = calloc(pd_count, sizeof(VkPhysicalDevice)); if (vkEnumeratePhysicalDevices(instance, &pd_count, pd) != VK_SUCCESS) { free(pd); vkDestroyInstance(instance, NULL); glfwTerminate(); exit(EXIT_FAILURE); } for (i = 0; i < pd_count; i++) { VkPhysicalDeviceProperties pdp; vkGetPhysicalDeviceProperties(pd[i], &pdp); printf("Vulkan %s device: \"%s\"\n", get_device_type_name(pdp.deviceType), pdp.deviceName); if (list_extensions) list_vulkan_device_extensions(instance, pd[i]); if (list_layers) list_vulkan_device_layers(instance, pd[i]); } free(pd); vkDestroyInstance(instance, NULL); } glfwTerminate(); exit(EXIT_SUCCESS); }
int main(int, char**) { // Setup window glfwSetErrorCallback(glfw_error_callback); if (!glfwInit()) return 1; glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui GLFW+Vulkan example", NULL, NULL); // Setup Vulkan if (!glfwVulkanSupported()) { printf("GLFW: Vulkan Not Supported\n"); return 1; } setup_vulkan(window); glfwSetFramebufferSizeCallback(window, glfw_resize_callback); // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; ImGui_ImplGlfwVulkan_Init_Data init_data = {}; init_data.allocator = g_Allocator; init_data.gpu = g_Gpu; init_data.device = g_Device; init_data.render_pass = g_RenderPass; init_data.pipeline_cache = g_PipelineCache; init_data.descriptor_pool = g_DescriptorPool; init_data.check_vk_result = check_vk_result; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplGlfwVulkan_Init(window, true, &init_data); // Setup style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. // - Read 'misc/fonts/README.txt' for more instructions and details. // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); // Upload Fonts { VkResult err; err = vkResetCommandPool(g_Device, g_CommandPool[g_FrameIndex], 0); check_vk_result(err); VkCommandBufferBeginInfo begin_info = {}; begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; err = vkBeginCommandBuffer(g_CommandBuffer[g_FrameIndex], &begin_info); check_vk_result(err); ImGui_ImplGlfwVulkan_CreateFontsTexture(g_CommandBuffer[g_FrameIndex]); VkSubmitInfo end_info = {}; end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; end_info.commandBufferCount = 1; end_info.pCommandBuffers = &g_CommandBuffer[g_FrameIndex]; err = vkEndCommandBuffer(g_CommandBuffer[g_FrameIndex]); check_vk_result(err); err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE); check_vk_result(err); err = vkDeviceWaitIdle(g_Device); check_vk_result(err); ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects(); } bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Main loop while (!glfwWindowShouldClose(window)) { // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. glfwPollEvents(); if (g_ResizeWanted) resize_vulkan(g_ResizeWidth, g_ResizeHeight); g_ResizeWanted = false; ImGui_ImplGlfwVulkan_NewFrame(); // 1. Show a simple window. // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". { static float f = 0.0f; static int counter = 0; ImGui::Text("Hello, world!"); // Display some text (you can use a format string too) ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our windows open/close state ImGui::Checkbox("Another Window", &show_another_window); if (ImGui::Button("Button")) // Buttons return true when clicked (NB: most widgets return true when edited/activated) counter++; ImGui::SameLine(); ImGui::Text("counter = %d", counter); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name your windows. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello from another window!"); if (ImGui::Button("Close Me")) show_another_window = false; ImGui::End(); } // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). Read its code to learn more about Dear ImGui! if (show_demo_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowDemoWindow(&show_demo_window); } memcpy(&g_ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); frame_begin(); ImGui_ImplGlfwVulkan_Render(g_CommandBuffer[g_FrameIndex]); frame_end(); frame_present(); } // Cleanup VkResult err = vkDeviceWaitIdle(g_Device); check_vk_result(err); ImGui_ImplGlfwVulkan_Shutdown(); ImGui::DestroyContext(); cleanup_vulkan(); glfwTerminate(); return 0; }