commit
26be1511e9
13 changed files with 3220 additions and 651 deletions
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@ -0,0 +1,36 @@ |
||||
cmake_minimum_required(VERSION 2.8) |
||||
project(ImGuiGLFWVulkanExample C CXX) |
||||
|
||||
if(NOT CMAKE_BUILD_TYPE) |
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE) |
||||
endif() |
||||
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES") |
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_PROTOTYPES") |
||||
|
||||
# GLFW |
||||
set(GLFW_DIR ../../../glfw) # Set this to point to a up-to-date GLFW repo |
||||
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" OFF) |
||||
option(GLFW_BUILD_TESTS "Build the GLFW test programs" OFF) |
||||
option(GLFW_BUILD_DOCS "Build the GLFW documentation" OFF) |
||||
option(GLFW_INSTALL "Generate installation target" OFF) |
||||
option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF) |
||||
add_subdirectory(${GLFW_DIR} binary_dir EXCLUDE_FROM_ALL) |
||||
include_directories(${GLFW_DIR}/include) |
||||
|
||||
# ImGui |
||||
set(IMGUI_DIR ../../) |
||||
include_directories(${IMGUI_DIR}) |
||||
|
||||
# Libraries |
||||
find_library(VULKAN_LIBRARY |
||||
NAMES vulkan vulkan-1) |
||||
set(LIBRARIES "glfw;${VULKAN_LIBRARY}") |
||||
|
||||
# Use vulkan headers from glfw: |
||||
include_directories(${GLFW_DIR}/deps) |
||||
|
||||
file(GLOB sources *.cpp) |
||||
|
||||
add_executable(vulkan_example ${sources} ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp) |
||||
target_link_libraries(vulkan_example ${LIBRARIES}) |
@ -0,0 +1,4 @@ |
||||
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. |
||||
mkdir Debug |
||||
cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\*.cpp /FeDebug/vulkan_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\bin32 glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib |
||||
|
@ -0,0 +1,4 @@ |
||||
#!/bin/bash |
||||
glslangValidator -V -o glsl_shader.frag.spv glsl_shader.frag |
||||
glslangValidator -V -o glsl_shader.vert.spv glsl_shader.vert |
||||
spirv-remap --map all --dce all --strip-all --input glsl_shader.frag.spv glsl_shader.vert.spv --output ./ |
@ -0,0 +1,14 @@ |
||||
#version 450 core |
||||
layout(location = 0, index = 0) out vec4 fColor; |
||||
|
||||
layout(set=0, binding=0) uniform sampler2D sTexture; |
||||
|
||||
in block{ |
||||
vec4 Color; |
||||
vec2 UV; |
||||
} In; |
||||
|
||||
void main() |
||||
{ |
||||
fColor = In.Color * texture(sTexture, In.UV.st); |
||||
} |
@ -0,0 +1,21 @@ |
||||
#version 450 core |
||||
layout(location = 0) in vec2 aPos; |
||||
layout(location = 1) in vec2 aUV; |
||||
layout(location = 2) in vec4 aColor; |
||||
|
||||
layout(push_constant) uniform uPushConstant{ |
||||
vec2 uScale; |
||||
vec2 uTranslate; |
||||
} pc; |
||||
|
||||
out block{ |
||||
vec4 Color; |
||||
vec2 UV; |
||||
} Out; |
||||
|
||||
void main() |
||||
{ |
||||
Out.Color = aColor; |
||||
Out.UV = aUV; |
||||
gl_Position = vec4(aPos*pc.uScale+pc.uTranslate, 0, 1); |
||||
} |
@ -0,0 +1,935 @@ |
||||
// ImGui GLFW binding with Vulkan + shaders
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
|
||||
// If you use this binding you'll need to call 5 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXX_CreateFontsTexture(), ImGui_ImplXXXX_NewFrame(), ImGui_ImplXXXX_Render() and ImGui_ImplXXXX_Shutdown().
|
||||
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
|
||||
// https://github.com/ocornut/imgui
|
||||
|
||||
#include <imgui.h> |
||||
|
||||
// GLFW
|
||||
#define GLFW_INCLUDE_NONE |
||||
#define GLFW_INCLUDE_VULKAN |
||||
#include <GLFW/glfw3.h> |
||||
#ifdef _WIN32 |
||||
#undef APIENTRY |
||||
#define GLFW_EXPOSE_NATIVE_WIN32 |
||||
#define GLFW_EXPOSE_NATIVE_WGL |
||||
#include <GLFW/glfw3native.h> |
||||
#endif |
||||
|
||||
#include "imgui_impl_glfw_vulkan.h" |
||||
|
||||
// GLFW Data
|
||||
static GLFWwindow* g_Window = NULL; |
||||
static double g_Time = 0.0f; |
||||
static bool g_MousePressed[3] = { false, false, false }; |
||||
static float g_MouseWheel = 0.0f; |
||||
|
||||
// Vulkan Data
|
||||
static VkAllocationCallbacks* g_Allocator = NULL; |
||||
static VkPhysicalDevice g_Gpu = VK_NULL_HANDLE; |
||||
static VkDevice g_Device = VK_NULL_HANDLE; |
||||
static VkRenderPass g_RenderPass = VK_NULL_HANDLE; |
||||
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; |
||||
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; |
||||
static void (*g_CheckVkResult)(VkResult err) = NULL; |
||||
|
||||
static VkCommandBuffer g_CommandBuffer = VK_NULL_HANDLE; |
||||
static size_t g_BufferMemoryAlignment = 256; |
||||
static VkPipelineCreateFlags g_PipelineCreateFlags = 0; |
||||
static int g_FrameIndex = 0; |
||||
|
||||
static VkDescriptorSetLayout g_DescriptorSetLayout = VK_NULL_HANDLE; |
||||
static VkPipelineLayout g_PipelineLayout = VK_NULL_HANDLE; |
||||
static VkDescriptorSet g_DescriptorSet = VK_NULL_HANDLE; |
||||
static VkPipeline g_Pipeline = VK_NULL_HANDLE; |
||||
|
||||
static VkSampler g_FontSampler = VK_NULL_HANDLE; |
||||
static VkDeviceMemory g_FontMemory = VK_NULL_HANDLE; |
||||
static VkImage g_FontImage = VK_NULL_HANDLE; |
||||
static VkImageView g_FontView = VK_NULL_HANDLE; |
||||
|
||||
static VkDeviceMemory g_VertexBufferMemory[IMGUI_VK_QUEUED_FRAMES] = {}; |
||||
static VkDeviceMemory g_IndexBufferMemory[IMGUI_VK_QUEUED_FRAMES] = {}; |
||||
static size_t g_VertexBufferSize[IMGUI_VK_QUEUED_FRAMES] = {}; |
||||
static size_t g_IndexBufferSize[IMGUI_VK_QUEUED_FRAMES] = {}; |
||||
static VkBuffer g_VertexBuffer[IMGUI_VK_QUEUED_FRAMES] = {}; |
||||
static VkBuffer g_IndexBuffer[IMGUI_VK_QUEUED_FRAMES] = {}; |
||||
|
||||
static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE; |
||||
static VkBuffer g_UploadBuffer = VK_NULL_HANDLE; |
||||
|
||||
static unsigned char __glsl_shader_vert_spv[] =
|
||||
{ |
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, |
||||
0x6c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, |
||||
0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, |
||||
0x11, 0x00, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, |
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, |
||||
0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0a, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x1f, 0x16, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, |
||||
0x00, 0x00, 0x00, 0x00, 0x47, 0x11, 0x00, 0x00, 0x41, 0x14, 0x00, 0x00, |
||||
0x6a, 0x16, 0x00, 0x00, 0x42, 0x13, 0x00, 0x00, 0x80, 0x14, 0x00, 0x00, |
||||
0x47, 0x00, 0x03, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, |
||||
0x47, 0x00, 0x04, 0x00, 0x41, 0x14, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, |
||||
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x6a, 0x16, 0x00, 0x00, |
||||
0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, |
||||
0xb1, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xb1, 0x02, 0x00, 0x00, |
||||
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, |
||||
0x48, 0x00, 0x05, 0x00, 0xb1, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, |
||||
0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, |
||||
0xb1, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, |
||||
0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0xb1, 0x02, 0x00, 0x00, |
||||
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x80, 0x14, 0x00, 0x00, |
||||
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, |
||||
0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x06, 0x04, 0x00, 0x00, |
||||
0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, |
||||
0x47, 0x00, 0x03, 0x00, 0x06, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, |
||||
0x47, 0x00, 0x04, 0x00, 0xfa, 0x16, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, |
||||
0x21, 0x00, 0x03, 0x00, 0x02, 0x05, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, |
||||
0x16, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, |
||||
0x17, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, |
||||
0x04, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, |
||||
0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x00, |
||||
0x1a, 0x04, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, |
||||
0x20, 0x00, 0x04, 0x00, 0x97, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, |
||||
0x1a, 0x04, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x97, 0x06, 0x00, 0x00, |
||||
0x47, 0x11, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, |
||||
0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, |
||||
0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x9a, 0x02, 0x00, 0x00, |
||||
0x01, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, |
||||
0x9a, 0x02, 0x00, 0x00, 0x41, 0x14, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, |
||||
0x20, 0x00, 0x04, 0x00, 0x9b, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, |
||||
0x1d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, |
||||
0x0e, 0x0a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, |
||||
0x90, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, |
||||
0x3b, 0x00, 0x04, 0x00, 0x90, 0x02, 0x00, 0x00, 0x6a, 0x16, 0x00, 0x00, |
||||
0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x91, 0x02, 0x00, 0x00, |
||||
0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, |
||||
0x0b, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0x2b, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0x00, 0x00, |
||||
0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x7f, 0x02, 0x00, 0x00, |
||||
0x0d, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0x00, 0x00, 0x1e, 0x00, 0x06, 0x00, |
||||
0xb1, 0x02, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, |
||||
0x7f, 0x02, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, |
||||
0x2e, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb1, 0x02, 0x00, 0x00, |
||||
0x3b, 0x00, 0x04, 0x00, 0x2e, 0x05, 0x00, 0x00, 0x42, 0x13, 0x00, 0x00, |
||||
0x03, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x90, 0x02, 0x00, 0x00, |
||||
0x80, 0x14, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x00, |
||||
0x06, 0x04, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, |
||||
0x20, 0x00, 0x04, 0x00, 0x83, 0x06, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, |
||||
0x06, 0x04, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x83, 0x06, 0x00, 0x00, |
||||
0xfa, 0x16, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, |
||||
0x92, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, |
||||
0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, |
||||
0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x05, 0x00, |
||||
0x08, 0x00, 0x00, 0x00, 0x1f, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0x02, 0x05, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x6b, 0x60, 0x00, 0x00, |
||||
0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x71, 0x4e, 0x00, 0x00, |
||||
0x41, 0x14, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x9b, 0x02, 0x00, 0x00, |
||||
0xaa, 0x26, 0x00, 0x00, 0x47, 0x11, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00, |
||||
0x3e, 0x00, 0x03, 0x00, 0xaa, 0x26, 0x00, 0x00, 0x71, 0x4e, 0x00, 0x00, |
||||
0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0xda, 0x35, 0x00, 0x00, |
||||
0x6a, 0x16, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x91, 0x02, 0x00, 0x00, |
||||
0xea, 0x50, 0x00, 0x00, 0x47, 0x11, 0x00, 0x00, 0x0e, 0x0a, 0x00, 0x00, |
||||
0x3e, 0x00, 0x03, 0x00, 0xea, 0x50, 0x00, 0x00, 0xda, 0x35, 0x00, 0x00, |
||||
0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0xc7, 0x35, 0x00, 0x00, |
||||
0x80, 0x14, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x92, 0x02, 0x00, 0x00, |
||||
0xef, 0x56, 0x00, 0x00, 0xfa, 0x16, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00, |
||||
0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0xe0, 0x29, 0x00, 0x00, |
||||
0xef, 0x56, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x13, 0x00, 0x00, 0x00, |
||||
0xa0, 0x22, 0x00, 0x00, 0xc7, 0x35, 0x00, 0x00, 0xe0, 0x29, 0x00, 0x00, |
||||
0x41, 0x00, 0x05, 0x00, 0x92, 0x02, 0x00, 0x00, 0x42, 0x2c, 0x00, 0x00, |
||||
0xfa, 0x16, 0x00, 0x00, 0x0e, 0x0a, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, |
||||
0x13, 0x00, 0x00, 0x00, 0x09, 0x60, 0x00, 0x00, 0x42, 0x2c, 0x00, 0x00, |
||||
0x81, 0x00, 0x05, 0x00, 0x13, 0x00, 0x00, 0x00, 0xd1, 0x4e, 0x00, 0x00, |
||||
0xa0, 0x22, 0x00, 0x00, 0x09, 0x60, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, |
||||
0x0d, 0x00, 0x00, 0x00, 0xa1, 0x41, 0x00, 0x00, 0xd1, 0x4e, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, |
||||
0x84, 0x36, 0x00, 0x00, 0xd1, 0x4e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, |
||||
0x50, 0x00, 0x07, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x54, 0x47, 0x00, 0x00, |
||||
0xa1, 0x41, 0x00, 0x00, 0x84, 0x36, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, |
||||
0x8a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x9b, 0x02, 0x00, 0x00, |
||||
0x17, 0x2f, 0x00, 0x00, 0x42, 0x13, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00, |
||||
0x3e, 0x00, 0x03, 0x00, 0x17, 0x2f, 0x00, 0x00, 0x54, 0x47, 0x00, 0x00, |
||||
0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 |
||||
}; |
||||
static unsigned int __glsl_shader_vert_spv_len = 1172; |
||||
|
||||
static unsigned char __glsl_shader_frag_spv[] =
|
||||
{ |
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, |
||||
0x6c, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, |
||||
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, |
||||
0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, |
||||
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, |
||||
0x1f, 0x16, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, |
||||
0x7a, 0x0c, 0x00, 0x00, 0x35, 0x16, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, |
||||
0x1f, 0x16, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, |
||||
0x7a, 0x0c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0x47, 0x00, 0x04, 0x00, 0x7a, 0x0c, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x1a, 0x04, 0x00, 0x00, |
||||
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xec, 0x14, 0x00, 0x00, |
||||
0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, |
||||
0xec, 0x14, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0x13, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, |
||||
0x02, 0x05, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, |
||||
0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, |
||||
0x1d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, |
||||
0x20, 0x00, 0x04, 0x00, 0x9a, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, |
||||
0x1d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x9a, 0x02, 0x00, 0x00, |
||||
0x7a, 0x0c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, |
||||
0x13, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, |
||||
0x1e, 0x00, 0x04, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, |
||||
0x13, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x97, 0x06, 0x00, 0x00, |
||||
0x01, 0x00, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, |
||||
0x97, 0x06, 0x00, 0x00, 0x35, 0x16, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, |
||||
0x15, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, |
||||
0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, |
||||
0x0b, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, |
||||
0x9b, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, |
||||
0x19, 0x00, 0x09, 0x00, 0x96, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, |
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0x1b, 0x00, 0x03, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, |
||||
0x20, 0x00, 0x04, 0x00, 0x7b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0xfe, 0x01, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x7b, 0x04, 0x00, 0x00, |
||||
0xec, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, |
||||
0x0c, 0x00, 0x00, 0x00, 0x0e, 0x0a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, |
||||
0x20, 0x00, 0x04, 0x00, 0x90, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, |
||||
0x13, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, |
||||
0x1f, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, |
||||
0xf8, 0x00, 0x02, 0x00, 0x6b, 0x5d, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, |
||||
0x9b, 0x02, 0x00, 0x00, 0x8d, 0x1b, 0x00, 0x00, 0x35, 0x16, 0x00, 0x00, |
||||
0x0b, 0x0a, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, |
||||
0x0b, 0x40, 0x00, 0x00, 0x8d, 0x1b, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, |
||||
0xfe, 0x01, 0x00, 0x00, 0xc0, 0x36, 0x00, 0x00, 0xec, 0x14, 0x00, 0x00, |
||||
0x41, 0x00, 0x05, 0x00, 0x90, 0x02, 0x00, 0x00, 0xc2, 0x43, 0x00, 0x00, |
||||
0x35, 0x16, 0x00, 0x00, 0x0e, 0x0a, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, |
||||
0x13, 0x00, 0x00, 0x00, 0x02, 0x4e, 0x00, 0x00, 0xc2, 0x43, 0x00, 0x00, |
||||
0x57, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xb9, 0x46, 0x00, 0x00, |
||||
0xc0, 0x36, 0x00, 0x00, 0x02, 0x4e, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, |
||||
0x1d, 0x00, 0x00, 0x00, 0xe4, 0x23, 0x00, 0x00, 0x0b, 0x40, 0x00, 0x00, |
||||
0xb9, 0x46, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x7a, 0x0c, 0x00, 0x00, |
||||
0xe4, 0x23, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 |
||||
}; |
||||
static unsigned int __glsl_shader_frag_spv_len = 660; |
||||
|
||||
static uint32_t ImGui_ImplGlfwVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits) |
||||
{ |
||||
VkPhysicalDeviceMemoryProperties prop; |
||||
vkGetPhysicalDeviceMemoryProperties(g_Gpu, &prop); |
||||
for (uint32_t i = 0; i < prop.memoryTypeCount; i++) |
||||
if ((prop.memoryTypes[i].propertyFlags & properties) == properties && type_bits & (1<<i)) |
||||
return i; |
||||
return 0xffffffff; // Unable to find memoryType
|
||||
} |
||||
|
||||
static void ImGui_ImplGlfwVulkan_VkResult(VkResult err) |
||||
{ |
||||
if (g_CheckVkResult) |
||||
g_CheckVkResult(err); |
||||
} |
||||
|
||||
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
|
||||
void ImGui_ImplGlfwVulkan_RenderDrawLists(ImDrawData* draw_data) |
||||
{ |
||||
VkResult err; |
||||
ImGuiIO& io = ImGui::GetIO(); |
||||
|
||||
// Create the Vertex Buffer:
|
||||
size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert); |
||||
if (!g_VertexBuffer[g_FrameIndex] || g_VertexBufferSize[g_FrameIndex] < vertex_size) |
||||
{ |
||||
if (g_VertexBuffer[g_FrameIndex]) |
||||
vkDestroyBuffer(g_Device, g_VertexBuffer[g_FrameIndex], g_Allocator); |
||||
if (g_VertexBufferMemory[g_FrameIndex]) |
||||
vkFreeMemory(g_Device, g_VertexBufferMemory[g_FrameIndex], g_Allocator); |
||||
size_t vertex_buffer_size = ((vertex_size-1) / g_BufferMemoryAlignment+1) * g_BufferMemoryAlignment; |
||||
VkBufferCreateInfo buffer_info = {}; |
||||
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; |
||||
buffer_info.size = vertex_buffer_size; |
||||
buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; |
||||
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; |
||||
err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &g_VertexBuffer[g_FrameIndex]); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
VkMemoryRequirements req; |
||||
vkGetBufferMemoryRequirements(g_Device, g_VertexBuffer[g_FrameIndex], &req); |
||||
g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment; |
||||
VkMemoryAllocateInfo alloc_info = {}; |
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; |
||||
alloc_info.allocationSize = req.size; |
||||
alloc_info.memoryTypeIndex = ImGui_ImplGlfwVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits); |
||||
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_VertexBufferMemory[g_FrameIndex]); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
err = vkBindBufferMemory(g_Device, g_VertexBuffer[g_FrameIndex], g_VertexBufferMemory[g_FrameIndex], 0); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
g_VertexBufferSize[g_FrameIndex] = vertex_buffer_size; |
||||
} |
||||
|
||||
// Create the Index Buffer:
|
||||
size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx); |
||||
if (!g_IndexBuffer[g_FrameIndex] || g_IndexBufferSize[g_FrameIndex] < index_size) |
||||
{ |
||||
if (g_IndexBuffer[g_FrameIndex]) |
||||
vkDestroyBuffer(g_Device, g_IndexBuffer[g_FrameIndex], g_Allocator); |
||||
if (g_IndexBufferMemory[g_FrameIndex]) |
||||
vkFreeMemory(g_Device, g_IndexBufferMemory[g_FrameIndex], g_Allocator); |
||||
size_t index_buffer_size = ((index_size-1) / g_BufferMemoryAlignment+1) * g_BufferMemoryAlignment; |
||||
VkBufferCreateInfo buffer_info = {}; |
||||
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; |
||||
buffer_info.size = index_buffer_size; |
||||
buffer_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; |
||||
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; |
||||
err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &g_IndexBuffer[g_FrameIndex]); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
VkMemoryRequirements req; |
||||
vkGetBufferMemoryRequirements(g_Device, g_IndexBuffer[g_FrameIndex], &req); |
||||
g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment; |
||||
VkMemoryAllocateInfo alloc_info = {}; |
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; |
||||
alloc_info.allocationSize = req.size; |
||||
alloc_info.memoryTypeIndex = ImGui_ImplGlfwVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits); |
||||
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_IndexBufferMemory[g_FrameIndex]); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
err = vkBindBufferMemory(g_Device, g_IndexBuffer[g_FrameIndex], g_IndexBufferMemory[g_FrameIndex], 0); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
g_IndexBufferSize[g_FrameIndex] = index_buffer_size; |
||||
} |
||||
|
||||
// Upload Vertex and index Data:
|
||||
{ |
||||
ImDrawVert* vtx_dst; |
||||
ImDrawIdx* idx_dst; |
||||
err = vkMapMemory(g_Device, g_VertexBufferMemory[g_FrameIndex], 0, vertex_size, 0, (void**)(&vtx_dst)); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
err = vkMapMemory(g_Device, g_IndexBufferMemory[g_FrameIndex], 0, index_size, 0, (void**)(&idx_dst)); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
for (int n = 0; n < draw_data->CmdListsCount; n++) |
||||
{ |
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n]; |
||||
memcpy(vtx_dst, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); |
||||
memcpy(idx_dst, &cmd_list->IdxBuffer[0], cmd_list->IdxBuffer.size() * sizeof(ImDrawIdx)); |
||||
vtx_dst += cmd_list->VtxBuffer.size(); |
||||
idx_dst += cmd_list->IdxBuffer.size(); |
||||
} |
||||
VkMappedMemoryRange range[2] = {}; |
||||
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; |
||||
range[0].memory = g_VertexBufferMemory[g_FrameIndex]; |
||||
range[0].size = vertex_size; |
||||
range[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; |
||||
range[1].memory = g_IndexBufferMemory[g_FrameIndex]; |
||||
range[1].size = index_size; |
||||
err = vkFlushMappedMemoryRanges(g_Device, 2, range); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
vkUnmapMemory(g_Device, g_VertexBufferMemory[g_FrameIndex]); |
||||
vkUnmapMemory(g_Device, g_IndexBufferMemory[g_FrameIndex]); |
||||
} |
||||
|
||||
// Bind pipeline and descriptor sets:
|
||||
{ |
||||
vkCmdBindPipeline(g_CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_Pipeline); |
||||
VkDescriptorSet desc_set[1] = {g_DescriptorSet}; |
||||
vkCmdBindDescriptorSets(g_CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_PipelineLayout, 0, 1, desc_set, 0, NULL); |
||||
} |
||||
|
||||
// Bind Vertex And Index Buffer:
|
||||
{ |
||||
VkBuffer vertex_buffers[1] = {g_VertexBuffer[g_FrameIndex]}; |
||||
VkDeviceSize vertex_offset[1] = {0}; |
||||
vkCmdBindVertexBuffers(g_CommandBuffer, 0, 1, vertex_buffers, vertex_offset); |
||||
vkCmdBindIndexBuffer(g_CommandBuffer, g_IndexBuffer[g_FrameIndex], 0, VK_INDEX_TYPE_UINT16); |
||||
} |
||||
|
||||
// Setup viewport:
|
||||
{ |
||||
VkViewport viewport; |
||||
viewport.x = 0; |
||||
viewport.y = 0; |
||||
viewport.width = ImGui::GetIO().DisplaySize.x; |
||||
viewport.height = ImGui::GetIO().DisplaySize.y; |
||||
viewport.minDepth = 0.0f; |
||||
viewport.maxDepth = 1.0f; |
||||
vkCmdSetViewport(g_CommandBuffer, 0, 1, &viewport); |
||||
} |
||||
|
||||
// Setup scale and translation:
|
||||
{ |
||||
float scale[2]; |
||||
scale[0] = 2.0f/io.DisplaySize.x; |
||||
scale[1] = 2.0f/io.DisplaySize.y; |
||||
float translate[2]; |
||||
translate[0] = -1.0f; |
||||
translate[1] = -1.0f; |
||||
vkCmdPushConstants(g_CommandBuffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 0, sizeof(float) * 2, scale); |
||||
vkCmdPushConstants(g_CommandBuffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 2, sizeof(float) * 2, translate); |
||||
} |
||||
|
||||
// Render the command lists:
|
||||
int vtx_offset = 0; |
||||
int idx_offset = 0; |
||||
for (int n = 0; n < draw_data->CmdListsCount; n++) |
||||
{ |
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n]; |
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) |
||||
{ |
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; |
||||
if (pcmd->UserCallback) |
||||
{ |
||||
pcmd->UserCallback(cmd_list, pcmd); |
||||
} |
||||
else |
||||
{ |
||||
VkRect2D scissor; |
||||
scissor.offset.x = static_cast<int32_t>(pcmd->ClipRect.x); |
||||
scissor.offset.y = static_cast<int32_t>(pcmd->ClipRect.y); |
||||
scissor.extent.width = static_cast<uint32_t>(pcmd->ClipRect.z - pcmd->ClipRect.x); |
||||
scissor.extent.height = static_cast<uint32_t>(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // TODO: + 1??????
|
||||
vkCmdSetScissor(g_CommandBuffer, 0, 1, &scissor); |
||||
vkCmdDrawIndexed(g_CommandBuffer, pcmd->ElemCount, 1, idx_offset, vtx_offset, 0); |
||||
} |
||||
idx_offset += pcmd->ElemCount; |
||||
} |
||||
vtx_offset += cmd_list->VtxBuffer.size(); |
||||
} |
||||
} |
||||
|
||||
static const char* ImGui_ImplGlfwVulkan_GetClipboardText() |
||||
{ |
||||
return glfwGetClipboardString(g_Window); |
||||
} |
||||
|
||||
static void ImGui_ImplGlfwVulkan_SetClipboardText(const char* text) |
||||
{ |
||||
glfwSetClipboardString(g_Window, text); |
||||
} |
||||
|
||||
void ImGui_ImplGlfwVulkan_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) |
||||
{ |
||||
if (action == GLFW_PRESS && button >= 0 && button < 3) |
||||
g_MousePressed[button] = true; |
||||
} |
||||
|
||||
void ImGui_ImplGlfwVulkan_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) |
||||
{ |
||||
g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines.
|
||||
} |
||||
|
||||
void ImGui_ImplGlfwVulkan_KeyCallback(GLFWwindow*, int key, int, int action, int mods) |
||||
{ |
||||
ImGuiIO& io = ImGui::GetIO(); |
||||
if (action == GLFW_PRESS) |
||||
io.KeysDown[key] = true; |
||||
if (action == GLFW_RELEASE) |
||||
io.KeysDown[key] = false; |
||||
|
||||
(void)mods; // Modifiers are not reliable across systems
|
||||
io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; |
||||
io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; |
||||
io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; |
||||
io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; |
||||
} |
||||
|
||||
void ImGui_ImplGlfwVulkan_CharCallback(GLFWwindow*, unsigned int c) |
||||
{ |
||||
ImGuiIO& io = ImGui::GetIO(); |
||||
if (c > 0 && c < 0x10000) |
||||
io.AddInputCharacter((unsigned short)c); |
||||
} |
||||
|
||||
bool ImGui_ImplGlfwVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) |
||||
{ |
||||
ImGuiIO& io = ImGui::GetIO(); |
||||
|
||||
unsigned char* pixels; |
||||
int width, height; |
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); |
||||
size_t upload_size = width*height*4*sizeof(char); |
||||
|
||||
VkResult err; |
||||
|
||||
// Create the Image:
|
||||
{ |
||||
VkImageCreateInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; |
||||
info.imageType = VK_IMAGE_TYPE_2D; |
||||
info.format = VK_FORMAT_R8G8B8A8_UNORM; |
||||
info.extent.width = width; |
||||
info.extent.height = height; |
||||
info.extent.depth = 1; |
||||
info.mipLevels = 1; |
||||
info.arrayLayers = 1; |
||||
info.samples = VK_SAMPLE_COUNT_1_BIT; |
||||
info.tiling = VK_IMAGE_TILING_OPTIMAL; |
||||
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; |
||||
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
||||
err = vkCreateImage(g_Device, &info, g_Allocator, &g_FontImage); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
VkMemoryRequirements req; |
||||
vkGetImageMemoryRequirements(g_Device, g_FontImage, &req); |
||||
VkMemoryAllocateInfo alloc_info = {}; |
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; |
||||
alloc_info.allocationSize = req.size; |
||||
alloc_info.memoryTypeIndex = ImGui_ImplGlfwVulkan_MemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, req.memoryTypeBits); |
||||
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_FontMemory); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
err = vkBindImageMemory(g_Device, g_FontImage, g_FontMemory, 0); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
} |
||||
|
||||
// Create the Image View:
|
||||
{ |
||||
VkResult err; |
||||
VkImageViewCreateInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; |
||||
info.image = g_FontImage; |
||||
info.viewType = VK_IMAGE_VIEW_TYPE_2D; |
||||
info.format = VK_FORMAT_R8G8B8A8_UNORM; |
||||
info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
||||
info.subresourceRange.levelCount = 1; |
||||
info.subresourceRange.layerCount = 1; |
||||
err = vkCreateImageView(g_Device, &info, g_Allocator, &g_FontView); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
} |
||||
|
||||
// Update the Descriptor Set:
|
||||
{ |
||||
VkDescriptorImageInfo desc_image[1] = {}; |
||||
desc_image[0].sampler = g_FontSampler; |
||||
desc_image[0].imageView = g_FontView; |
||||
desc_image[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; |
||||
VkWriteDescriptorSet write_desc[1] = {}; |
||||
write_desc[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; |
||||
write_desc[0].dstSet = g_DescriptorSet; |
||||
write_desc[0].descriptorCount = 1; |
||||
write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; |
||||
write_desc[0].pImageInfo = desc_image; |
||||
vkUpdateDescriptorSets(g_Device, 1, write_desc, 0, NULL); |
||||
} |
||||
|
||||
// Create the Upload Buffer:
|
||||
{ |
||||
VkBufferCreateInfo buffer_info = {}; |
||||
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; |
||||
buffer_info.size = upload_size; |
||||
buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; |
||||
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; |
||||
err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &g_UploadBuffer); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
VkMemoryRequirements req; |
||||
vkGetBufferMemoryRequirements(g_Device, g_UploadBuffer, &req); |
||||
g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment; |
||||
VkMemoryAllocateInfo alloc_info = {}; |
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; |
||||
alloc_info.allocationSize = req.size; |
||||
alloc_info.memoryTypeIndex = ImGui_ImplGlfwVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits); |
||||
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_UploadBufferMemory); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
err = vkBindBufferMemory(g_Device, g_UploadBuffer, g_UploadBufferMemory, 0); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
} |
||||
|
||||
// Upload to Buffer:
|
||||
{ |
||||
char* map = NULL; |
||||
err = vkMapMemory(g_Device, g_UploadBufferMemory, 0, upload_size, 0, (void**)(&map)); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
memcpy(map, pixels, upload_size); |
||||
VkMappedMemoryRange range[1] = {}; |
||||
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; |
||||
range[0].memory = g_UploadBufferMemory; |
||||
range[0].size = upload_size; |
||||
err = vkFlushMappedMemoryRanges(g_Device, 1, range); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
vkUnmapMemory(g_Device, g_UploadBufferMemory); |
||||
} |
||||
// Copy to Image:
|
||||
{ |
||||
VkImageMemoryBarrier copy_barrier[1] = {}; |
||||
copy_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; |
||||
copy_barrier[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; |
||||
copy_barrier[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
||||
copy_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; |
||||
copy_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; |
||||
copy_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; |
||||
copy_barrier[0].image = g_FontImage; |
||||
copy_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
||||
copy_barrier[0].subresourceRange.levelCount = 1; |
||||
copy_barrier[0].subresourceRange.layerCount = 1; |
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, copy_barrier); |
||||
|
||||
VkBufferImageCopy region = {}; |
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
||||
region.imageSubresource.layerCount = 1; |
||||
region.imageExtent.width = width; |
||||
region.imageExtent.height = height; |
||||
vkCmdCopyBufferToImage(command_buffer, g_UploadBuffer, g_FontImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); |
||||
|
||||
VkImageMemoryBarrier use_barrier[1] = {}; |
||||
use_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; |
||||
use_barrier[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; |
||||
use_barrier[0].dstAccessMask = VK_ACCESS_SHADER_READ_BIT; |
||||
use_barrier[0].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; |
||||
use_barrier[0].newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; |
||||
use_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; |
||||
use_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; |
||||
use_barrier[0].image = g_FontImage; |
||||
use_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
||||
use_barrier[0].subresourceRange.levelCount = 1; |
||||
use_barrier[0].subresourceRange.layerCount = 1; |
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, use_barrier); |
||||
} |
||||
|
||||
// Store our identifier
|
||||
io.Fonts->TexID = (void *)(intptr_t)g_FontImage; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
bool ImGui_ImplGlfwVulkan_CreateDeviceObjects() |
||||
{ |
||||
VkResult err; |
||||
VkShaderModule vert_module; |
||||
VkShaderModule frag_module; |
||||
|
||||
// Create The Shader Modules:
|
||||
{ |
||||
VkShaderModuleCreateInfo vert_info = {}; |
||||
vert_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; |
||||
vert_info.codeSize = __glsl_shader_vert_spv_len; |
||||
vert_info.pCode = (uint32_t*)__glsl_shader_vert_spv; |
||||
err = vkCreateShaderModule(g_Device, &vert_info, g_Allocator, &vert_module); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
VkShaderModuleCreateInfo frag_info = {}; |
||||
frag_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; |
||||
frag_info.codeSize = __glsl_shader_frag_spv_len; |
||||
frag_info.pCode = (uint32_t*)__glsl_shader_frag_spv; |
||||
err = vkCreateShaderModule(g_Device, &frag_info, g_Allocator, &frag_module); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
} |
||||
|
||||
if (!g_FontSampler) |
||||
{ |
||||
VkSamplerCreateInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; |
||||
info.magFilter = VK_FILTER_LINEAR; |
||||
info.minFilter = VK_FILTER_LINEAR; |
||||
info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; |
||||
info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; |
||||
info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; |
||||
info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; |
||||
info.minLod = -1000; |
||||
info.maxLod = 1000; |
||||
err = vkCreateSampler(g_Device, &info, g_Allocator, &g_FontSampler); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
} |
||||
|
||||
if (!g_DescriptorSetLayout) |
||||
{ |
||||
VkSampler sampler[1] = {g_FontSampler}; |
||||
VkDescriptorSetLayoutBinding binding[1] = {}; |
||||
binding[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; |
||||
binding[0].descriptorCount = 1; |
||||
binding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; |
||||
binding[0].pImmutableSamplers = sampler; |
||||
VkDescriptorSetLayoutCreateInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; |
||||
info.bindingCount = 1; |
||||
info.pBindings = binding; |
||||
err = vkCreateDescriptorSetLayout(g_Device, &info, g_Allocator, &g_DescriptorSetLayout); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
} |
||||
|
||||
// Create Descriptor Set:
|
||||
{ |
||||
VkDescriptorSetAllocateInfo alloc_info = {}; |
||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; |
||||
alloc_info.descriptorPool = g_DescriptorPool; |
||||
alloc_info.descriptorSetCount = 1; |
||||
alloc_info.pSetLayouts = &g_DescriptorSetLayout; |
||||
err = vkAllocateDescriptorSets(g_Device, &alloc_info, &g_DescriptorSet); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
} |
||||
|
||||
if (!g_PipelineLayout) |
||||
{ |
||||
VkPushConstantRange push_constants[2] = {}; |
||||
push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; |
||||
push_constants[0].offset = sizeof(float) * 0; |
||||
push_constants[0].size = sizeof(float) * 2; |
||||
push_constants[1].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; |
||||
push_constants[1].offset = sizeof(float) * 2; |
||||
push_constants[1].size = sizeof(float) * 2; |
||||
VkDescriptorSetLayout set_layout[1] = {g_DescriptorSetLayout}; |
||||
VkPipelineLayoutCreateInfo layout_info = {}; |
||||
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; |
||||
layout_info.setLayoutCount = 1; |
||||
layout_info.pSetLayouts = set_layout; |
||||
layout_info.pushConstantRangeCount = 2; |
||||
layout_info.pPushConstantRanges = push_constants; |
||||
err = vkCreatePipelineLayout(g_Device, &layout_info, g_Allocator, &g_PipelineLayout); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
} |
||||
|
||||
VkPipelineShaderStageCreateInfo stage[2] = {}; |
||||
stage[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; |
||||
stage[0].stage = VK_SHADER_STAGE_VERTEX_BIT; |
||||
stage[0].module = vert_module; |
||||
stage[0].pName = "main"; |
||||
stage[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; |
||||
stage[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
||||
stage[1].module = frag_module; |
||||
stage[1].pName = "main"; |
||||
|
||||
VkVertexInputBindingDescription binding_desc[1] = {}; |
||||
binding_desc[0].stride = sizeof(ImDrawVert); |
||||
binding_desc[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
||||
|
||||
VkVertexInputAttributeDescription attribute_desc[3] = {}; |
||||
attribute_desc[0].location = 0; |
||||
attribute_desc[0].binding = binding_desc[0].binding; |
||||
attribute_desc[0].format = VK_FORMAT_R32G32_SFLOAT; |
||||
attribute_desc[0].offset = (size_t)(&((ImDrawVert*)0)->pos); |
||||
attribute_desc[1].location = 1; |
||||
attribute_desc[1].binding = binding_desc[0].binding; |
||||
attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT; |
||||
attribute_desc[1].offset = (size_t)(&((ImDrawVert*)0)->uv); |
||||
attribute_desc[2].location = 2; |
||||
attribute_desc[2].binding = binding_desc[0].binding; |
||||
attribute_desc[2].format = VK_FORMAT_R8G8B8A8_UNORM; |
||||
attribute_desc[2].offset = (size_t)(&((ImDrawVert*)0)->col); |
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertex_info = {}; |
||||
vertex_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; |
||||
vertex_info.vertexBindingDescriptionCount = 1; |
||||
vertex_info.pVertexBindingDescriptions = binding_desc; |
||||
vertex_info.vertexAttributeDescriptionCount = 3; |
||||
vertex_info.pVertexAttributeDescriptions = attribute_desc; |
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo ia_info = {}; |
||||
ia_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; |
||||
ia_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; |
||||
|
||||
VkPipelineViewportStateCreateInfo viewport_info = {}; |
||||
viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; |
||||
viewport_info.viewportCount = 1; |
||||
viewport_info.scissorCount = 1; |
||||
|
||||
VkPipelineRasterizationStateCreateInfo raster_info = {}; |
||||
raster_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; |
||||
raster_info.polygonMode = VK_POLYGON_MODE_FILL; |
||||
raster_info.cullMode = VK_CULL_MODE_NONE; |
||||
raster_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; |
||||
|
||||
VkPipelineMultisampleStateCreateInfo ms_info = {}; |
||||
ms_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; |
||||
ms_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; |
||||
|
||||
VkPipelineColorBlendAttachmentState color_attachment[1] = {}; |
||||
color_attachment[0].blendEnable = VK_TRUE; |
||||
color_attachment[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; |
||||
color_attachment[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; |
||||
color_attachment[0].colorBlendOp = VK_BLEND_OP_ADD; |
||||
color_attachment[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; |
||||
color_attachment[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; |
||||
color_attachment[0].alphaBlendOp = VK_BLEND_OP_ADD; |
||||
color_attachment[0].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; |
||||
|
||||
VkPipelineColorBlendStateCreateInfo blend_info = {}; |
||||
blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; |
||||
blend_info.attachmentCount = 1; |
||||
blend_info.pAttachments = color_attachment; |
||||
|
||||
VkDynamicState dynamic_states[2] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; |
||||
VkPipelineDynamicStateCreateInfo dynamic_state = {}; |
||||
dynamic_state.dynamicStateCount = 2; |
||||
dynamic_state.pDynamicStates = dynamic_states; |
||||
|
||||
VkGraphicsPipelineCreateInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; |
||||
info.flags = g_PipelineCreateFlags; |
||||
info.stageCount = 2; |
||||
info.pStages = stage; |
||||
info.pVertexInputState = &vertex_info; |
||||
info.pInputAssemblyState = &ia_info; |
||||
info.pViewportState = &viewport_info; |
||||
info.pRasterizationState = &raster_info; |
||||
info.pMultisampleState = &ms_info; |
||||
info.pColorBlendState = &blend_info; |
||||
info.pDynamicState = &dynamic_state; |
||||
info.layout = g_PipelineLayout; |
||||
info.renderPass = g_RenderPass; |
||||
err = vkCreateGraphicsPipelines(g_Device, g_PipelineCache, 1, &info, g_Allocator, &g_Pipeline); |
||||
ImGui_ImplGlfwVulkan_VkResult(err); |
||||
|
||||
vkDestroyShaderModule(g_Device, vert_module, g_Allocator); |
||||
vkDestroyShaderModule(g_Device, frag_module, g_Allocator); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects() |
||||
{ |
||||
if (g_UploadBuffer) |
||||
{ |
||||
vkDestroyBuffer(g_Device, g_UploadBuffer, g_Allocator); |
||||
g_UploadBuffer = VK_NULL_HANDLE; |
||||
} |
||||
if (g_UploadBufferMemory) |
||||
{ |
||||
vkFreeMemory(g_Device, g_UploadBufferMemory, g_Allocator); |
||||
g_UploadBufferMemory = VK_NULL_HANDLE; |
||||
} |
||||
} |
||||
|
||||
void ImGui_ImplGlfwVulkan_InvalidateDeviceObjects() |
||||
{ |
||||
ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects(); |
||||
for (int i=0; i<IMGUI_VK_QUEUED_FRAMES; i++) |
||||
{ |
||||
if (g_VertexBuffer[i]) |
||||
vkDestroyBuffer(g_Device, g_VertexBuffer[i], g_Allocator); |
||||
if (g_VertexBufferMemory[i]) |
||||
vkFreeMemory(g_Device, g_VertexBufferMemory[i], g_Allocator); |
||||
if (g_IndexBuffer[i]) |
||||
vkDestroyBuffer(g_Device, g_IndexBuffer[i], g_Allocator); |
||||
if (g_IndexBufferMemory[i]) |
||||
vkFreeMemory(g_Device, g_IndexBufferMemory[i], g_Allocator); |
||||
} |
||||
|
||||
if (g_FontView) |
||||
vkDestroyImageView(g_Device, g_FontView, g_Allocator); |
||||
if (g_FontImage) |
||||
vkDestroyImage(g_Device, g_FontImage, g_Allocator); |
||||
if (g_FontMemory) |
||||
vkFreeMemory(g_Device, g_FontMemory, g_Allocator); |
||||
if (g_FontSampler) |
||||
vkDestroySampler(g_Device, g_FontSampler, g_Allocator); |
||||
|
||||
if (g_DescriptorSetLayout) |
||||
vkDestroyDescriptorSetLayout(g_Device, g_DescriptorSetLayout, g_Allocator); |
||||
if (g_PipelineLayout) |
||||
vkDestroyPipelineLayout(g_Device, g_PipelineLayout, g_Allocator); |
||||
if (g_Pipeline) |
||||
vkDestroyPipeline(g_Device, g_Pipeline, g_Allocator); |
||||
} |
||||
|
||||
bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, ImGui_ImplGlfwVulkan_Init_Data *init_data) |
||||
{ |
||||
g_Allocator = init_data->allocator; |
||||
g_Gpu = init_data->gpu; |
||||
g_Device = init_data->device; |
||||
g_RenderPass = init_data->render_pass; |
||||
g_PipelineCache = init_data->pipeline_cache; |
||||
g_DescriptorPool = init_data->descriptor_pool; |
||||
g_CheckVkResult = init_data->check_vk_result; |
||||
|
||||
g_Window = window; |
||||
|
||||
ImGuiIO& io = ImGui::GetIO(); |
||||
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; |
||||
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; |
||||
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; |
||||
io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; |
||||
io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; |
||||
io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; |
||||
io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; |
||||
io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; |
||||
io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; |
||||
io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; |
||||
io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; |
||||
io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; |
||||
io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; |
||||
io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; |
||||
io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; |
||||
io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; |
||||
io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; |
||||
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; |
||||
|
||||
io.RenderDrawListsFn = ImGui_ImplGlfwVulkan_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer.
|
||||
io.SetClipboardTextFn = ImGui_ImplGlfwVulkan_SetClipboardText; |
||||
io.GetClipboardTextFn = ImGui_ImplGlfwVulkan_GetClipboardText; |
||||
#ifdef _WIN32 |
||||
io.ImeWindowHandle = glfwGetWin32Window(g_Window); |
||||
#endif |
||||
|
||||
if (install_callbacks) |
||||
{ |
||||
glfwSetMouseButtonCallback(window, ImGui_ImplGlfwVulkan_MouseButtonCallback); |
||||
glfwSetScrollCallback(window, ImGui_ImplGlfwVulkan_ScrollCallback); |
||||
glfwSetKeyCallback(window, ImGui_ImplGlfwVulkan_KeyCallback); |
||||
glfwSetCharCallback(window, ImGui_ImplGlfwVulkan_CharCallback); |
||||
} |
||||
|
||||
ImGui_ImplGlfwVulkan_CreateDeviceObjects(); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void ImGui_ImplGlfwVulkan_Shutdown() |
||||
{ |
||||
ImGui_ImplGlfwVulkan_InvalidateDeviceObjects(); |
||||
ImGui::Shutdown(); |
||||
} |
||||
|
||||
void ImGui_ImplGlfwVulkan_NewFrame() |
||||
{ |
||||
ImGuiIO& io = ImGui::GetIO(); |
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
int w, h; |
||||
int display_w, display_h; |
||||
glfwGetWindowSize(g_Window, &w, &h); |
||||
glfwGetFramebufferSize(g_Window, &display_w, &display_h); |
||||
io.DisplaySize = ImVec2((float)w, (float)h); |
||||
io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); |
||||
|
||||
// Setup time step
|
||||
double current_time = glfwGetTime(); |
||||
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); |
||||
g_Time = current_time; |
||||
|
||||
// Setup inputs
|
||||
// (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents())
|
||||
if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) |
||||
{ |
||||
double mouse_x, mouse_y; |
||||
glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); |
||||
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.)
|
||||
} |
||||
else |
||||
{ |
||||
io.MousePos = ImVec2(-1,-1); |
||||
} |
||||
|
||||
for (int i = 0; i < 3; i++) |
||||
{ |
||||
io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
|
||||
g_MousePressed[i] = false; |
||||
} |
||||
|
||||
io.MouseWheel = g_MouseWheel; |
||||
g_MouseWheel = 0.0f; |
||||
|
||||
// Hide OS mouse cursor if ImGui is drawing it
|
||||
glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); |
||||
|
||||
// Start the frame
|
||||
ImGui::NewFrame(); |
||||
} |
||||
void ImGui_ImplGlfwVulkan_Render(VkCommandBuffer command_buffer) |
||||
{ |
||||
g_CommandBuffer = command_buffer; |
||||
ImGui::Render(); |
||||
g_CommandBuffer = VK_NULL_HANDLE; |
||||
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES; |
||||
} |
@ -0,0 +1,40 @@ |
||||
// ImGui GLFW binding with Vulkan + shaders
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
|
||||
// If you use this binding you'll need to call 5 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXX_CreateFontsTexture(), ImGui_ImplXXXX_NewFrame(), ImGui_ImplXXXX_Render() and ImGui_ImplXXXX_Shutdown().
|
||||
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
|
||||
// https://github.com/ocornut/imgui
|
||||
|
||||
struct GLFWwindow; |
||||
|
||||
#define IMGUI_VK_QUEUED_FRAMES 2 |
||||
|
||||
struct ImGui_ImplGlfwVulkan_Init_Data |
||||
{ |
||||
VkAllocationCallbacks* allocator; |
||||
VkPhysicalDevice gpu; |
||||
VkDevice device; |
||||
VkRenderPass render_pass; |
||||
VkPipelineCache pipeline_cache; |
||||
VkDescriptorPool descriptor_pool; |
||||
void (*check_vk_result)(VkResult err); |
||||
}; |
||||
|
||||
IMGUI_API bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, ImGui_ImplGlfwVulkan_Init_Data *init_data); |
||||
IMGUI_API void ImGui_ImplGlfwVulkan_Shutdown(); |
||||
IMGUI_API void ImGui_ImplGlfwVulkan_NewFrame(); |
||||
IMGUI_API void ImGui_ImplGlfwVulkan_Render(VkCommandBuffer command_buffer); |
||||
|
||||
// Use if you want to reset your rendering device without losing ImGui state.
|
||||
IMGUI_API void ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects(); |
||||
IMGUI_API void ImGui_ImplGlfwVulkan_InvalidateDeviceObjects(); |
||||
IMGUI_API bool ImGui_ImplGlfwVulkan_CreateFontsTexture(VkCommandBuffer command_buffer); |
||||
IMGUI_API bool ImGui_ImplGlfwVulkan_CreateDeviceObjects(); |
||||
|
||||
// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization)
|
||||
// Provided here if you want to chain callbacks.
|
||||
// You can also handle inputs yourself and use those as a reference.
|
||||
IMGUI_API void ImGui_ImplGlfwVulkan_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); |
||||
IMGUI_API void ImGui_ImplGlfwVulkan_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); |
||||
IMGUI_API void ImGui_ImplGlfwVulkan_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); |
||||
IMGUI_API void ImGui_ImplGlfwVulkan_CharCallback(GLFWwindow* window, unsigned int c); |
||||
|
@ -0,0 +1,539 @@ |
||||
// ImGui - standalone example application for Glfw + Vulkan, using programmable pipeline
|
||||
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
|
||||
|
||||
#include <imgui.h> |
||||
|
||||
#include <stdio.h> // printf, fprintf |
||||
#include <stdlib.h> // abort |
||||
#define GLFW_INCLUDE_NONE |
||||
#define GLFW_INCLUDE_VULKAN |
||||
#include <GLFW/glfw3.h> |
||||
|
||||
#include "imgui_impl_glfw_vulkan.h" |
||||
|
||||
#define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16 |
||||
|
||||
static VkAllocationCallbacks* g_Allocator = NULL; |
||||
static VkInstance g_Instance = VK_NULL_HANDLE; |
||||
static VkSurfaceKHR g_Surface = VK_NULL_HANDLE; |
||||
static VkPhysicalDevice g_Gpu = VK_NULL_HANDLE; |
||||
static VkDevice g_Device = VK_NULL_HANDLE; |
||||
static VkSwapchainKHR g_Swapchain = VK_NULL_HANDLE; |
||||
static VkRenderPass g_RenderPass = VK_NULL_HANDLE; |
||||
static uint32_t g_QueueFamily = 0; |
||||
static VkQueue g_Queue = VK_NULL_HANDLE; |
||||
|
||||
static VkFormat g_Format = VK_FORMAT_B8G8R8A8_UNORM; |
||||
static VkColorSpaceKHR g_ColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; |
||||
static VkImageSubresourceRange g_ImageRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
||||
|
||||
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; |
||||
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; |
||||
|
||||
static int fb_width, fb_height; |
||||
static uint32_t g_BackBufferIndex = 0; |
||||
static uint32_t g_BackBufferCount = 0; |
||||
static VkImage g_BackBuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {}; |
||||
static VkImageView g_BackBufferView[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {}; |
||||
static VkFramebuffer g_Framebuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {}; |
||||
|
||||
static uint32_t g_FrameIndex = 0; |
||||
static VkCommandPool g_CommandPool[IMGUI_VK_QUEUED_FRAMES]; |
||||
static VkCommandBuffer g_CommandBuffer[IMGUI_VK_QUEUED_FRAMES]; |
||||
static VkFence g_Fence[IMGUI_VK_QUEUED_FRAMES]; |
||||
static VkSemaphore g_Semaphore[IMGUI_VK_QUEUED_FRAMES]; |
||||
|
||||
static VkClearValue g_ClearValue = {}; |
||||
|
||||
static void check_vk_result(VkResult err) |
||||
{ |
||||
if (err == 0) return; |
||||
printf("VkResult %d\n", err); |
||||
if (err < 0)
|
||||
abort(); |
||||
} |
||||
|
||||
static void resize_vulkan(GLFWwindow* /*window*/, int w, int h) |
||||
{ |
||||
VkResult err; |
||||
VkSwapchainKHR old_swapchain = g_Swapchain; |
||||
err = vkDeviceWaitIdle(g_Device); |
||||
check_vk_result(err); |
||||
|
||||
// Destroy old Framebuffer:
|
||||
for (uint32_t i=0; i<g_BackBufferCount; i++) |
||||
if (g_BackBufferView[i]) |
||||
vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator); |
||||
for(uint32_t i=0; i<g_BackBufferCount; i++) |
||||
if (g_Framebuffer[i]) |
||||
vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator); |
||||
if (g_RenderPass) |
||||
vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator); |
||||
|
||||
// Create Swapchain:
|
||||
{ |
||||
VkSwapchainCreateInfoKHR info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; |
||||
info.surface = g_Surface; |
||||
info.imageFormat = g_Format; |
||||
info.imageColorSpace = g_ColorSpace; |
||||
info.imageArrayLayers = 1; |
||||
info.imageUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
||||
info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; |
||||
info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; |
||||
info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; |
||||
info.presentMode = VK_PRESENT_MODE_FIFO_KHR; |
||||
info.clipped = VK_TRUE; |
||||
info.oldSwapchain = old_swapchain; |
||||
VkSurfaceCapabilitiesKHR cap; |
||||
err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_Gpu, g_Surface, &cap); |
||||
check_vk_result(err); |
||||
info.minImageCount = (cap.minImageCount + 2 < cap.maxImageCount) ? (cap.minImageCount + 2) : cap.maxImageCount; |
||||
if (cap.currentExtent.width == 0xffffffff) |
||||
{ |
||||
fb_width = w; |
||||
fb_height = h; |
||||
info.imageExtent.width = fb_width; |
||||
info.imageExtent.height = fb_height; |
||||
} |
||||
else |
||||
{ |
||||
fb_width = cap.currentExtent.width; |
||||
fb_height = cap.currentExtent.height; |
||||
info.imageExtent.width = fb_width; |
||||
info.imageExtent.height = fb_height; |
||||
} |
||||
err = vkCreateSwapchainKHR(g_Device, &info, g_Allocator, &g_Swapchain); |
||||
check_vk_result(err); |
||||
err = vkGetSwapchainImagesKHR(g_Device, g_Swapchain, &g_BackBufferCount, NULL); |
||||
check_vk_result(err); |
||||
err = vkGetSwapchainImagesKHR(g_Device, g_Swapchain, &g_BackBufferCount, g_BackBuffer); |
||||
check_vk_result(err); |
||||
} |
||||
if (old_swapchain) |
||||
vkDestroySwapchainKHR(g_Device, old_swapchain, g_Allocator); |
||||
|
||||
// Create the Render Pass:
|
||||
{ |
||||
VkAttachmentDescription attachment = {}; |
||||
attachment.format = g_Format; |
||||
attachment.samples = VK_SAMPLE_COUNT_1_BIT; |
||||
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
||||
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
||||
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
||||
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
||||
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
||||
attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
||||
VkAttachmentReference color_attachment = {}; |
||||
color_attachment.attachment = 0; |
||||
color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
||||
VkSubpassDescription subpass = {}; |
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
||||
subpass.colorAttachmentCount = 1; |
||||
subpass.pColorAttachments = &color_attachment; |
||||
VkRenderPassCreateInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; |
||||
info.attachmentCount = 1; |
||||
info.pAttachments = &attachment; |
||||
info.subpassCount = 1; |
||||
info.pSubpasses = &subpass; |
||||
err = vkCreateRenderPass(g_Device, &info, g_Allocator, &g_RenderPass); |
||||
check_vk_result(err); |
||||
} |
||||
|
||||
// Create The Image Views
|
||||
{ |
||||
VkImageViewCreateInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; |
||||
info.viewType = VK_IMAGE_VIEW_TYPE_2D; |
||||
info.format = g_Format; |
||||
info.components.r = VK_COMPONENT_SWIZZLE_R; |
||||
info.components.g = VK_COMPONENT_SWIZZLE_G; |
||||
info.components.b = VK_COMPONENT_SWIZZLE_B; |
||||
info.components.a = VK_COMPONENT_SWIZZLE_A; |
||||
info.subresourceRange = g_ImageRange; |
||||
for (uint32_t i = 0; i<g_BackBufferCount; i++) |
||||
{ |
||||
info.image = g_BackBuffer[i]; |
||||
err = vkCreateImageView(g_Device, &info, g_Allocator, &g_BackBufferView[i]); |
||||
check_vk_result(err); |
||||
} |
||||
} |
||||
|
||||
// Create Framebuffer:
|
||||
{ |
||||
VkImageView attachment[1]; |
||||
VkFramebufferCreateInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; |
||||
info.renderPass = g_RenderPass; |
||||
info.attachmentCount = 1; |
||||
info.pAttachments = attachment; |
||||
info.width = fb_width; |
||||
info.height = fb_height; |
||||
info.layers = 1; |
||||
for (uint32_t i = 0; i<g_BackBufferCount; i++) |
||||
{ |
||||
attachment[0] = g_BackBufferView[i]; |
||||
err = vkCreateFramebuffer(g_Device, &info, g_Allocator, &g_Framebuffer[i]); |
||||
check_vk_result(err); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void setup_vulkan(GLFWwindow* window) |
||||
{ |
||||
VkResult err; |
||||
|
||||
// Create Vulkan Instance
|
||||
{ |
||||
uint32_t glfw_extensions_count; |
||||
const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extensions_count); |
||||
VkInstanceCreateInfo create_info = {}; |
||||
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; |
||||
create_info.enabledExtensionCount = glfw_extensions_count; |
||||
create_info.ppEnabledExtensionNames = glfw_extensions; |
||||
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); |
||||
check_vk_result(err); |
||||
} |
||||
|
||||
// Create Window Surface
|
||||
{ |
||||
err = glfwCreateWindowSurface(g_Instance, window, g_Allocator, &g_Surface); |
||||
check_vk_result(err); |
||||
} |
||||
|
||||
// Get GPU
|
||||
{ |
||||
uint32_t count = 1; |
||||
err = vkEnumeratePhysicalDevices(g_Instance, &count, &g_Gpu); |
||||
check_vk_result(err); |
||||
} |
||||
|
||||
// Create Logical Device
|
||||
{ |
||||
int device_extension_count = 1; |
||||
const char* device_extensions[] = {"VK_KHR_swapchain"}; |
||||
const uint32_t queue_index = 0; |
||||
const uint32_t queue_count = 1; |
||||
const float queue_priority[] = {1.0f}; |
||||
VkDeviceQueueCreateInfo queue_info[1] = {}; |
||||
queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; |
||||
queue_info[0].queueFamilyIndex = g_QueueFamily; |
||||
queue_info[0].queueCount = queue_count; |
||||
queue_info[0].pQueuePriorities = queue_priority; |
||||
VkDeviceCreateInfo create_info = {}; |
||||
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; |
||||
create_info.queueCreateInfoCount = sizeof(queue_info)/sizeof(queue_info[0]); |
||||
create_info.pQueueCreateInfos = queue_info; |
||||
create_info.enabledExtensionCount = device_extension_count; |
||||
create_info.ppEnabledExtensionNames = device_extensions; |
||||
err = vkCreateDevice(g_Gpu, &create_info, g_Allocator, &g_Device); |
||||
check_vk_result(err); |
||||
vkGetDeviceQueue(g_Device, g_QueueFamily, queue_index, &g_Queue); |
||||
} |
||||
|
||||
// Create Framebuffers
|
||||
{ |
||||
int w, h; |
||||
glfwGetFramebufferSize(window, &w, &h); |
||||
resize_vulkan(window, w, h); |
||||
glfwSetFramebufferSizeCallback(window, resize_vulkan); |
||||
} |
||||
|
||||
// Create Command Buffers
|
||||
for (int i=0; i<IMGUI_VK_QUEUED_FRAMES; i++) |
||||
{ |
||||
{ |
||||
VkCommandPoolCreateInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; |
||||
info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; |
||||
info.queueFamilyIndex = g_QueueFamily; |
||||
err = vkCreateCommandPool(g_Device, &info, g_Allocator, &g_CommandPool[i]); |
||||
check_vk_result(err); |
||||
} |
||||
{ |
||||
VkCommandBufferAllocateInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; |
||||
info.commandPool = g_CommandPool[i]; |
||||
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; |
||||
info.commandBufferCount = 1; |
||||
err = vkAllocateCommandBuffers(g_Device, &info, &g_CommandBuffer[i]); |
||||
check_vk_result(err); |
||||
} |
||||
{ |
||||
VkFenceCreateInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; |
||||
info.flags = VK_FENCE_CREATE_SIGNALED_BIT; |
||||
err = vkCreateFence(g_Device, &info, g_Allocator, &g_Fence[i]); |
||||
check_vk_result(err); |
||||
} |
||||
{ |
||||
VkSemaphoreCreateInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; |
||||
err = vkCreateSemaphore(g_Device, &info, g_Allocator, &g_Semaphore[i]); |
||||
check_vk_result(err); |
||||
} |
||||
} |
||||
|
||||
// Create Descriptor Pool
|
||||
{ |
||||
VkDescriptorPoolSize pool_size[11] =
|
||||
{ |
||||
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 }, |
||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 }, |
||||
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 }, |
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 }, |
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 }, |
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 }, |
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 }, |
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 }, |
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 }, |
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 }, |
||||
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } |
||||
}; |
||||
VkDescriptorPoolCreateInfo pool_info = {}; |
||||
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; |
||||
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; |
||||
pool_info.maxSets = 1000 * 11; |
||||
pool_info.poolSizeCount = 11; |
||||
pool_info.pPoolSizes = pool_size; |
||||
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool); |
||||
check_vk_result(err); |
||||
} |
||||
} |
||||
|
||||
static void cleanup_vulkan() |
||||
{ |
||||
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); |
||||
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) |
||||
{ |
||||
vkDestroyFence(g_Device, g_Fence[i], g_Allocator); |
||||
vkFreeCommandBuffers(g_Device, g_CommandPool[i], 1, &g_CommandBuffer[i]); |
||||
vkDestroyCommandPool(g_Device, g_CommandPool[i], g_Allocator); |
||||
vkDestroySemaphore(g_Device, g_Semaphore[i], g_Allocator); |
||||
} |
||||
for (uint32_t i = 0; i < g_BackBufferCount; i++) |
||||
{ |
||||
vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator); |
||||
vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator); |
||||
} |
||||
vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator); |
||||
vkDestroySwapchainKHR(g_Device, g_Swapchain, g_Allocator); |
||||
vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator); |
||||
vkDestroyDevice(g_Device, g_Allocator); |
||||
vkDestroyInstance(g_Instance, g_Allocator); |
||||
} |
||||
|
||||
static void frame_begin() |
||||
{ |
||||
VkResult err; |
||||
while (true) |
||||
{ |
||||
err = vkWaitForFences(g_Device, 1, &g_Fence[g_FrameIndex], VK_TRUE, 100); |
||||
if (err == VK_SUCCESS) break; |
||||
if (err == VK_TIMEOUT) continue; |
||||
check_vk_result(err); |
||||
} |
||||
{ |
||||
err = vkAcquireNextImageKHR(g_Device, g_Swapchain, UINT64_MAX, g_Semaphore[g_FrameIndex], VK_NULL_HANDLE, &g_BackBufferIndex); |
||||
check_vk_result(err); |
||||
} |
||||
{ |
||||
err = vkResetCommandPool(g_Device, g_CommandPool[g_FrameIndex], 0); |
||||
check_vk_result(err); |
||||
VkCommandBufferBeginInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; |
||||
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; |
||||
err = vkBeginCommandBuffer(g_CommandBuffer[g_FrameIndex], &info); |
||||
check_vk_result(err); |
||||
} |
||||
{ |
||||
VkRenderPassBeginInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; |
||||
info.renderPass = g_RenderPass; |
||||
info.framebuffer = g_Framebuffer[g_BackBufferIndex]; |
||||
info.renderArea.extent.width = fb_width; |
||||
info.renderArea.extent.height = fb_height; |
||||
info.clearValueCount = 1; |
||||
info.pClearValues = &g_ClearValue; |
||||
vkCmdBeginRenderPass(g_CommandBuffer[g_FrameIndex], &info, VK_SUBPASS_CONTENTS_INLINE); |
||||
} |
||||
} |
||||
|
||||
static void frame_end() |
||||
{ |
||||
VkResult err; |
||||
vkCmdEndRenderPass(g_CommandBuffer[g_FrameIndex]); |
||||
{ |
||||
VkImageMemoryBarrier barrier = {}; |
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; |
||||
barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; |
||||
barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; |
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
||||
barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; |
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; |
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; |
||||
barrier.image = g_BackBuffer[g_BackBufferIndex]; |
||||
barrier.subresourceRange = g_ImageRange; |
||||
vkCmdPipelineBarrier(g_CommandBuffer[g_FrameIndex], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0, NULL, 1, &barrier); |
||||
} |
||||
{ |
||||
VkSubmitInfo info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; |
||||
info.waitSemaphoreCount = 1; |
||||
info.pWaitSemaphores = &g_Semaphore[g_FrameIndex]; |
||||
info.commandBufferCount = 1; |
||||
info.pCommandBuffers = &g_CommandBuffer[g_FrameIndex]; |
||||
|
||||
err = vkEndCommandBuffer(g_CommandBuffer[g_FrameIndex]); |
||||
check_vk_result(err); |
||||
err = vkResetFences(g_Device, 1, &g_Fence[g_FrameIndex]); |
||||
check_vk_result(err); |
||||
err = vkQueueSubmit(g_Queue, 1, &info, g_Fence[g_FrameIndex]); |
||||
check_vk_result(err); |
||||
} |
||||
{ |
||||
VkResult res; |
||||
VkSwapchainKHR swapchains[1] = {g_Swapchain}; |
||||
uint32_t indices[1] = {g_BackBufferIndex}; |
||||
VkPresentInfoKHR info = {}; |
||||
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; |
||||
info.swapchainCount = 1; |
||||
info.pSwapchains = swapchains; |
||||
info.pImageIndices = indices; |
||||
info.pResults = &res; |
||||
err = vkQueuePresentKHR(g_Queue, &info); |
||||
check_vk_result(err); |
||||
check_vk_result(res); |
||||
} |
||||
g_FrameIndex = (g_FrameIndex) % IMGUI_VK_QUEUED_FRAMES; |
||||
} |
||||
|
||||
static void error_callback(int error, const char* description) |
||||
{ |
||||
fprintf(stderr, "Error %d: %s\n", error, description); |
||||
} |
||||
|
||||
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
|
||||
// (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details)
|
||||
//ImGuiIO& io = ImGui::GetIO();
|
||||
//io.Fonts->AddFontDefault();
|
||||
//io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f);
|
||||
//io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f);
|
||||
//io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f);
|
||||
//io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f);
|
||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
|
||||
|
||||
// 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 = ImColor(114, 144, 154); |
||||
|
||||
// Main loop
|
||||
while (!glfwWindowShouldClose(window)) |
||||
{ |
||||
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, this time using an explicit Begin/End pair
|
||||
if (show_another_window) |
||||
{ |
||||
ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); |
||||
ImGui::Begin("Another Window", &show_another_window); |
||||
ImGui::Text("Hello"); |
||||
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), ImGuiSetCond_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(); |
||||
} |
||||
|
||||
// Cleanup
|
||||
VkResult err = vkDeviceWaitIdle(g_Device); |
||||
check_vk_result(err); |
||||
ImGui_ImplGlfwVulkan_Shutdown(); |
||||
cleanup_vulkan(); |
||||
glfwTerminate(); |
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in New Issue