1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-28 02:50:06 +00:00

merge v1.92.4

This commit is contained in:
maverikou 2025-11-10 20:19:58 +02:00
parent c425843be3
commit 44cff4493c
64 changed files with 1674 additions and 514 deletions

View file

@ -54,6 +54,7 @@ static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static ImGui_ImplVulkanH_Window g_MainWindowData;
static uint32_t g_MinImageCount = 2;
static bool g_SwapChainRebuild = false;
static VkImageUsageFlags g_SwapChainImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
static void glfw_error_callback(int error, const char* description)
{
@ -239,7 +240,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
// Create SwapChain, RenderPass, Framebuffer, etc.
IM_ASSERT(g_MinImageCount >= 2);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount, g_SwapChainImageUsage);
}
static void CleanupVulkan()
@ -410,12 +411,12 @@ int main(int, char**)
init_info.Queue = g_Queue;
init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool;
init_info.RenderPass = wd->RenderPass;
init_info.Subpass = 0;
init_info.MinImageCount = g_MinImageCount;
init_info.ImageCount = wd->ImageCount;
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.Allocator = g_Allocator;
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
init_info.PipelineInfoMain.Subpass = 0;
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info);
@ -456,7 +457,7 @@ int main(int, char**)
if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height))
{
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount, g_SwapChainImageUsage);
g_MainWindowData.FrameIndex = 0;
g_SwapChainRebuild = false;
}

View file

@ -1,4 +1,4 @@
// Dear ImGui: standalone example application for using GLFW + WebGPU
// Dear ImGui: standalone example application for GLFW + WebGPU
// - Emscripten is supported for publishing on web. See https://emscripten.org.
// - Dawn is used as a WebGPU implementation on desktop.
@ -12,36 +12,32 @@
#include "imgui_impl_glfw.h"
#include "imgui_impl_wgpu.h"
#include <stdio.h>
#include <GLFW/glfw3.h>
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#include <emscripten/html5.h>
#include <emscripten/html5_webgpu.h>
#include "../libs/emscripten/emscripten_mainloop_stub.h"
#else
#include <webgpu/webgpu_glfw.h>
#endif
#include <GLFW/glfw3.h>
#include <webgpu/webgpu.h>
#include <webgpu/webgpu_cpp.h>
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
#ifdef __EMSCRIPTEN__
#include "../libs/emscripten/emscripten_mainloop_stub.h"
#endif
// Global WebGPU required states
// Data
static WGPUInstance wgpu_instance = nullptr;
static WGPUDevice wgpu_device = nullptr;
static WGPUSurface wgpu_surface = nullptr;
static WGPUTextureFormat wgpu_preferred_fmt = WGPUTextureFormat_RGBA8Unorm;
static WGPUSwapChain wgpu_swap_chain = nullptr;
static int wgpu_swap_chain_width = 1280;
static int wgpu_swap_chain_height = 800;
static int wgpu_surface_width = 1280;
static int wgpu_surface_height = 800;
// Forward declarations
static bool InitWGPU(GLFWwindow* window);
static void CreateSwapChain(int width, int height);
static void ResizeSurface(int width, int height);
static void glfw_error_callback(int error, const char* description)
{
@ -72,19 +68,23 @@ int main(int, char**)
// Make sure GLFW does not initialize any graphics context.
// This needs to be done explicitly later.
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow(wgpu_swap_chain_width, wgpu_swap_chain_height, "Dear ImGui GLFW+WebGPU example", nullptr, nullptr);
// Create window
float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only
wgpu_surface_width *= main_scale;
wgpu_surface_height *= main_scale;
GLFWwindow* window = glfwCreateWindow(wgpu_surface_width, wgpu_surface_height, "Dear ImGui GLFW+WebGPU example", nullptr, nullptr);
if (window == nullptr)
return 1;
// Initialize the WebGPU environment
if (!InitWGPU(window))
{
if (window)
glfwDestroyWindow(window);
glfwDestroyWindow(window);
glfwTerminate();
return 1;
}
CreateSwapChain(wgpu_swap_chain_width, wgpu_swap_chain_height);
ResizeSurface(wgpu_surface_width, wgpu_surface_height);
glfwShowWindow(window);
// Setup Dear ImGui context
@ -98,6 +98,11 @@ int main(int, char**)
ImGui::StyleColorsDark();
//ImGui::StyleColorsLight();
// Setup scaling
ImGuiStyle& style = ImGui::GetStyle();
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOther(window, true);
#ifdef __EMSCRIPTEN__
@ -117,15 +122,14 @@ int main(int, char**)
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
// - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details.
//io.Fonts->AddFontDefault();
// - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details.
//style.FontSizeBase = 20.0f;
//io.Fonts->AddFontDefault();
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
//io.Fonts->AddFontFromFileTTF("fonts/segoeui.ttf");
//io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf");
//io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf");
//io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf");
//io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf");
//ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf");
//IM_ASSERT(font != nullptr);
#endif
@ -160,10 +164,10 @@ int main(int, char**)
// React to changes in screen size
int width, height;
glfwGetFramebufferSize((GLFWwindow*)window, &width, &height);
if (width != wgpu_swap_chain_width || height != wgpu_swap_chain_height)
if (width != wgpu_surface_width || height != wgpu_surface_height)
{
ImGui_ImplWGPU_InvalidateDeviceObjects();
CreateSwapChain(width, height);
ResizeSurface(width, height);
ImGui_ImplWGPU_CreateDeviceObjects();
}
@ -238,8 +242,8 @@ int main(int, char**)
WGPUCommandBufferDescriptor cmd_buffer_desc = {};
WGPUCommandBuffer cmd_buffer = wgpuCommandEncoderFinish(encoder, &cmd_buffer_desc);
WGPUQueue queue = wgpuDeviceGetQueue(wgpu_device);
wgpuQueueSubmit(queue, 1, &cmd_buffer);
WGPUQueue wgpu_queue = wgpuDeviceGetQueue(wgpu_device);
wgpuQueueSubmit(wgpu_queue, 1, &cmd_buffer);
#ifndef __EMSCRIPTEN__
wgpuSwapChainPresent(wgpu_swap_chain);
@ -311,10 +315,10 @@ static bool InitWGPU(GLFWwindow* window)
#endif
#ifdef __EMSCRIPTEN__
wgpu::SurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {};
html_surface_desc.selector = "#canvas";
wgpu::SurfaceDescriptorFromCanvasHTMLSelector canvas_desc = {};
canvas_desc.selector = "#canvas";
wgpu::SurfaceDescriptor surface_desc = {};
surface_desc.nextInChain = &html_surface_desc;
surface_desc.nextInChain = &canvas_desc;
wgpu::Surface surface = instance.CreateSurface(&surface_desc);
wgpu::Adapter adapter = {};
@ -326,6 +330,7 @@ static bool InitWGPU(GLFWwindow* window)
wgpu_preferred_fmt = WGPUTextureFormat_BGRA8Unorm;
#endif
// Moving Dawn objects into WGPU handles
wgpu_instance = instance.MoveToCHandle();
wgpu_surface = surface.MoveToCHandle();
@ -334,12 +339,12 @@ static bool InitWGPU(GLFWwindow* window)
return true;
}
static void CreateSwapChain(int width, int height)
static void ResizeSurface(int width, int height)
{
if (wgpu_swap_chain)
wgpuSwapChainRelease(wgpu_swap_chain);
wgpu_swap_chain_width = width;
wgpu_swap_chain_height = height;
wgpu_surface_width = width;
wgpu_surface_height = height;
WGPUSwapChainDescriptor swap_chain_desc = {};
swap_chain_desc.usage = WGPUTextureUsage_RenderAttachment;
swap_chain_desc.format = wgpu_preferred_fmt;

View file

@ -39,7 +39,7 @@ int main(int, char**)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{
printf("Error: %s\n", SDL_GetError());
return -1;
return 1;
}
// From 2.0.18: Enable native IME.
@ -54,7 +54,7 @@ int main(int, char**)
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
return 1;
}
SDL_SysWMinfo wmInfo;
@ -230,7 +230,10 @@ bool CreateDeviceD3D(HWND hWnd)
//createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
D3D_FEATURE_LEVEL featureLevel;
const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, };
if (D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
HRESULT res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);
if (res == DXGI_ERROR_UNSUPPORTED) // Try high-performance WARP software driver if hardware is not available.
res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_WARP, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);
if (res != S_OK)
return false;
CreateRenderTarget();

View file

@ -51,7 +51,7 @@ int main(int, char**)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{
printf("Error: %s\n", SDL_GetError());
return -1;
return 1;
}
// Inform SDL that we will be using metal for rendering. Without this hint initialization of metal renderer may fail.

View file

@ -31,7 +31,7 @@ int main(int, char**)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{
printf("Error: %s\n", SDL_GetError());
return -1;
return 1;
}
// From 2.0.18: Enable native IME.
@ -51,7 +51,7 @@ int main(int, char**)
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
return 1;
}
SDL_GLContext gl_context = SDL_GL_CreateContext(window);

View file

@ -36,7 +36,7 @@ int main(int, char**)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{
printf("Error: %s\n", SDL_GetError());
return -1;
return 1;
}
// Decide GL+GLSL versions
@ -85,14 +85,14 @@ int main(int, char**)
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
return 1;
}
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
if (gl_context == nullptr)
{
printf("Error: SDL_GL_CreateContext(): %s\n", SDL_GetError());
return -1;
return 1;
}
SDL_GL_MakeCurrent(window, gl_context);

View file

@ -33,7 +33,7 @@ int main(int, char**)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{
printf("Error: %s\n", SDL_GetError());
return -1;
return 1;
}
// From 2.0.18: Enable native IME.
@ -48,13 +48,13 @@ int main(int, char**)
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
return 1;
}
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
if (renderer == nullptr)
{
SDL_Log("Error creating SDL_Renderer!");
return -1;
return 1;
}
//SDL_RendererInfo info;
//SDL_GetRendererInfo(renderer, &info);

View file

@ -49,6 +49,7 @@ static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static ImGui_ImplVulkanH_Window g_MainWindowData;
static uint32_t g_MinImageCount = 2;
static bool g_SwapChainRebuild = false;
static VkImageUsageFlags g_SwapChainImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
static void check_vk_result(VkResult err)
{
@ -230,7 +231,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
// Create SwapChain, RenderPass, Framebuffer, etc.
IM_ASSERT(g_MinImageCount >= 2);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount, g_SwapChainImageUsage);
}
static void CleanupVulkan()
@ -349,7 +350,7 @@ int main(int, char**)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{
printf("Error: %s\n", SDL_GetError());
return -1;
return 1;
}
// From 2.0.18: Enable native IME.
@ -364,7 +365,7 @@ int main(int, char**)
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
return 1;
}
ImVector<const char*> extensions;
@ -416,12 +417,12 @@ int main(int, char**)
init_info.Queue = g_Queue;
init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool;
init_info.RenderPass = wd->RenderPass;
init_info.Subpass = 0;
init_info.MinImageCount = g_MinImageCount;
init_info.ImageCount = wd->ImageCount;
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.Allocator = g_Allocator;
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
init_info.PipelineInfoMain.Subpass = 0;
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info);
@ -476,7 +477,7 @@ int main(int, char**)
if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height))
{
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount, g_SwapChainImageUsage);
g_MainWindowData.FrameIndex = 0;
g_SwapChainRebuild = false;
}

View file

@ -0,0 +1,8 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
@set OUT_DIR=Debug
@set OUT_EXE=example_sdl3_directx11
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL3_DIR%\include /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include"
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl3.cpp ..\..\backends\imgui_impl_dx11.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:%SDL3_DIR%\lib\x86 SDL3.lib /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d11.lib d3dcompiler.lib shell32.lib
mkdir %OUT_DIR%
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View file

@ -0,0 +1,187 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{009DAC16-1A9C-47BE-9770-A30A046E8090}</ProjectGuid>
<RootNamespace>example_sdl3_directx11</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<ProjectName>example_sdl3_directx11</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>%SDL3_DIR%\lib\x86;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>SDL3.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>%SDL3_DIR%\lib\x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>SDL3.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>%SDL3_DIR%\lib\x86;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>SDL3.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>
</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>%SDL3_DIR%\lib\x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>SDL3.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>
</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\imgui.cpp" />
<ClCompile Include="..\..\imgui_demo.cpp" />
<ClCompile Include="..\..\imgui_draw.cpp" />
<ClCompile Include="..\..\imgui_tables.cpp" />
<ClCompile Include="..\..\imgui_widgets.cpp" />
<ClCompile Include="..\..\backends\imgui_impl_sdl3.cpp" />
<ClCompile Include="..\..\backends\imgui_impl_dx11.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\imconfig.h" />
<ClInclude Include="..\..\imgui.h" />
<ClInclude Include="..\..\imgui_internal.h" />
<ClInclude Include="..\..\backends\imgui_impl_sdl3.h" />
<ClInclude Include="..\..\backends\imgui_impl_dx11.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\misc\debuggers\imgui.natstepfilter" />
<None Include="..\..\misc\debuggers\imgui.natvis" />
<None Include="..\README.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="imgui">
<UniqueIdentifier>{0587d7a3-f2ce-4d56-b84f-a0005d3bfce6}</UniqueIdentifier>
</Filter>
<Filter Include="sources">
<UniqueIdentifier>{08e36723-ce4f-4cff-9662-c40801cf1acf}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\imconfig.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\..\imgui.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\..\imgui_internal.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\..\backends\imgui_impl_sdl3.h">
<Filter>sources</Filter>
</ClInclude>
<ClInclude Include="..\..\backends\imgui_impl_dx11.h">
<Filter>sources</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\imgui.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>sources</Filter>
</ClCompile>
<ClCompile Include="..\..\imgui_demo.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="..\..\imgui_draw.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="..\..\imgui_tables.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="..\..\imgui_widgets.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="..\..\backends\imgui_impl_sdl3.cpp">
<Filter>sources</Filter>
</ClCompile>
<ClCompile Include="..\..\backends\imgui_impl_dx11.cpp">
<Filter>sources</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\README.txt" />
<None Include="..\..\misc\debuggers\imgui.natvis">
<Filter>imgui</Filter>
</None>
<None Include="..\..\misc\debuggers\imgui.natstepfilter">
<Filter>imgui</Filter>
</None>
</ItemGroup>
</Project>

View file

@ -0,0 +1,257 @@
// Dear ImGui: standalone example application for SDL3 + DirectX 11
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
#include "imgui.h"
#include "imgui_impl_sdl3.h"
#include "imgui_impl_dx11.h"
#include <d3d11.h>
#include <stdio.h> // printf
#include <SDL3/SDL.h>
// Data
static ID3D11Device* g_pd3dDevice = nullptr;
static ID3D11DeviceContext* g_pd3dDeviceContext = nullptr;
static IDXGISwapChain* g_pSwapChain = nullptr;
static ID3D11RenderTargetView* g_mainRenderTargetView = nullptr;
// Forward declarations of helper functions
bool CreateDeviceD3D(HWND hWnd);
void CleanupDeviceD3D();
void CreateRenderTarget();
void CleanupRenderTarget();
// Main code
int main(int, char**)
{
// Setup SDL
// [If using SDL_MAIN_USE_CALLBACKS: all code below until the main loop starts would likely be your SDL_AppInit() function]
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
{
printf("Error: SDL_Init(): %s\n", SDL_GetError());
return 1;
}
// Setup window
float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
SDL_WindowFlags window_flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+DirectX11 example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return 1;
}
SDL_PropertiesID props = SDL_GetWindowProperties(window);
HWND hwnd = (HWND)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
// Initialize Direct3D
if (!CreateDeviceD3D(hwnd))
{
CleanupDeviceD3D();
return 1;
}
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
SDL_ShowWindow(window);
// 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::StyleColorsLight();
// Setup scaling
ImGuiStyle& style = ImGui::GetStyle();
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
// Setup Platform/Renderer backends
ImGui_ImplSDL3_InitForD3D(window);
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
// 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
//style.FontSizeBase = 20.0f;
//io.Fonts->AddFontDefault();
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
//IM_ASSERT(font != nullptr);
// Our state
bool show_demo_window = true;
bool show_another_window = false;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Main loop
bool done = false;
while (!done)
{
// 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, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
// [If using SDL_MAIN_USE_CALLBACKS: call ImGui_ImplSDL3_ProcessEvent() from your SDL_AppEvent() function]
SDL_Event event;
while (SDL_PollEvent(&event))
{
ImGui_ImplSDL3_ProcessEvent(&event);
if (event.type == SDL_EVENT_QUIT)
done = true;
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
done = true;
if (event.type == SDL_EVENT_WINDOW_RESIZED && event.window.windowID == SDL_GetWindowID(window))
{
// Release all outstanding references to the swap chain's buffers before resizing.
CleanupRenderTarget();
g_pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
CreateRenderTarget();
}
}
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppIterate() function]
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
{
SDL_Delay(10);
continue;
}
// Start the Dear ImGui frame
ImGui_ImplDX11_NewFrame();
ImGui_ImplSDL3_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 create 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 / io.Framerate, io.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();
const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr);
g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
g_pSwapChain->Present(1, 0); // Present with vsync
//g_pSwapChain->Present(0, 0); // Present without vsync
}
// Cleanup
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppQuit() function]
ImGui_ImplDX11_Shutdown();
ImGui_ImplSDL3_Shutdown();
ImGui::DestroyContext();
CleanupDeviceD3D();
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
// Helper functions to use DirectX11
bool CreateDeviceD3D(HWND hWnd)
{
// Setup swap chain
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 2;
sd.BufferDesc.Width = 0;
sd.BufferDesc.Height = 0;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
UINT createDeviceFlags = 0;
//createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
D3D_FEATURE_LEVEL featureLevel;
const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, };
HRESULT res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);
if (res == DXGI_ERROR_UNSUPPORTED) // Try high-performance WARP software driver if hardware is not available.
res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_WARP, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);
if (res != S_OK)
return false;
CreateRenderTarget();
return true;
}
void CleanupDeviceD3D()
{
CleanupRenderTarget();
if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = nullptr; }
if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = nullptr; }
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = nullptr; }
}
void CreateRenderTarget()
{
ID3D11Texture2D* pBackBuffer;
g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_mainRenderTargetView);
pBackBuffer->Release();
}
void CleanupRenderTarget()
{
if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = nullptr; }
}

View file

@ -24,7 +24,7 @@ int main(int, char**)
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
{
printf("Error: SDL_Init(): %s\n", SDL_GetError());
return -1;
return 1;
}
// Create SDL window graphics context
@ -34,19 +34,19 @@ int main(int, char**)
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
return 1;
}
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
SDL_ShowWindow(window);
// Create Metal device _before_ creating the view/layer
id<MTLDevice> metalDevice = MTLCreateSystemDefaultDevice();
id<MTLDevice> metalDevice = MTLCreateSystemDefaultDevice();
if (!metalDevice)
{
printf("Error: failed to create Metal device.\n");
SDL_DestroyWindow(window);
SDL_Quit();
return -1;
return 1;
}
SDL_MetalView view = SDL_Metal_CreateView(window);
CAMetalLayer* layer = (__bridge CAMetalLayer*)SDL_Metal_GetLayer(view);
@ -128,7 +128,7 @@ int main(int, char**)
int width, height;
SDL_GetWindowSizeInPixels(window, &width, &height);
layer.drawableSize = CGSizeMake(width, height);
id<CAMetalDrawable> drawable = [layer nextDrawable];

View file

@ -30,7 +30,7 @@ int main(int, char**)
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
{
printf("Error: SDL_Init(): %s\n", SDL_GetError());
return -1;
return 1;
}
// Decide GL+GLSL versions
@ -74,13 +74,13 @@ int main(int, char**)
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
return 1;
}
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
if (gl_context == nullptr)
{
printf("Error: SDL_GL_CreateContext(): %s\n", SDL_GetError());
return -1;
return 1;
}
SDL_GL_MakeCurrent(window, gl_context);

View file

@ -31,7 +31,7 @@ int main(int, char**)
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
{
printf("Error: SDL_Init(): %s\n", SDL_GetError());
return -1;
return 1;
}
// Create SDL window graphics context
@ -41,7 +41,7 @@ int main(int, char**)
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
return 1;
}
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
SDL_ShowWindow(window);
@ -51,14 +51,14 @@ int main(int, char**)
if (gpu_device == nullptr)
{
printf("Error: SDL_CreateGPUDevice(): %s\n", SDL_GetError());
return -1;
return 1;
}
// Claim window for GPU Device
if (!SDL_ClaimWindowForGPUDevice(gpu_device, window))
{
printf("Error: SDL_ClaimWindowForGPUDevice(): %s\n", SDL_GetError());
return -1;
return 1;
}
SDL_SetGPUSwapchainParameters(gpu_device, window, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_VSYNC);

View file

@ -28,7 +28,7 @@ int main(int, char**)
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
{
printf("Error: SDL_Init(): %s\n", SDL_GetError());
return -1;
return 1;
}
// Create window with SDL_Renderer graphics context
@ -38,14 +38,14 @@ int main(int, char**)
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
return 1;
}
SDL_Renderer* renderer = SDL_CreateRenderer(window, nullptr);
SDL_SetRenderVSync(renderer, 1);
if (renderer == nullptr)
{
SDL_Log("Error: SDL_CreateRenderer(): %s\n", SDL_GetError());
return -1;
return 1;
}
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
SDL_ShowWindow(window);

View file

@ -51,6 +51,7 @@ static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static ImGui_ImplVulkanH_Window g_MainWindowData;
static uint32_t g_MinImageCount = 2;
static bool g_SwapChainRebuild = false;
static VkImageUsageFlags g_SwapChainImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
static void check_vk_result(VkResult err)
{
@ -232,7 +233,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
// Create SwapChain, RenderPass, Framebuffer, etc.
IM_ASSERT(g_MinImageCount >= 2);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount, g_SwapChainImageUsage);
}
static void CleanupVulkan()
@ -349,7 +350,7 @@ int main(int, char**)
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
{
printf("Error: SDL_Init(): %s\n", SDL_GetError());
return -1;
return 1;
}
// Create window with Vulkan graphics context
@ -359,7 +360,7 @@ int main(int, char**)
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
return 1;
}
ImVector<const char*> extensions;
@ -415,12 +416,12 @@ int main(int, char**)
init_info.Queue = g_Queue;
init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool;
init_info.RenderPass = wd->RenderPass;
init_info.Subpass = 0;
init_info.MinImageCount = g_MinImageCount;
init_info.ImageCount = wd->ImageCount;
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.Allocator = g_Allocator;
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
init_info.PipelineInfoMain.Subpass = 0;
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info);
@ -478,7 +479,7 @@ int main(int, char**)
if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height))
{
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, fb_height, fb_height, g_MinImageCount, g_SwapChainImageUsage);
g_MainWindowData.FrameIndex = 0;
g_SwapChainRebuild = false;
}

View file

@ -1,4 +1,4 @@
// Dear ImGui: standalone example application for DirectX 10
// Dear ImGui: standalone example application for Windows API + DirectX 10
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq

View file

@ -1,4 +1,4 @@
// Dear ImGui: standalone example application for DirectX 11
// Dear ImGui: standalone example application for Windows API + DirectX 11
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq

View file

@ -1,4 +1,4 @@
// Dear ImGui: standalone example application for DirectX 12
// Dear ImGui: standalone example application for Windows API + DirectX 12
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
@ -10,7 +10,7 @@
#include "imgui_impl_win32.h"
#include "imgui_impl_dx12.h"
#include <d3d12.h>
#include <dxgi1_4.h>
#include <dxgi1_5.h>
#include <tchar.h>
#ifdef _DEBUG
@ -92,6 +92,7 @@ static ID3D12Fence* g_fence = nullptr;
static HANDLE g_fenceEvent = nullptr;
static UINT64 g_fenceLastSignaledValue = 0;
static IDXGISwapChain3* g_pSwapChain = nullptr;
static bool g_SwapChainTearingSupport = false;
static bool g_SwapChainOccluded = false;
static HANDLE g_hSwapChainWaitableObject = nullptr;
static ID3D12Resource* g_mainRenderTargetResource[APP_NUM_BACK_BUFFERS] = {};
@ -102,8 +103,8 @@ bool CreateDeviceD3D(HWND hWnd);
void CleanupDeviceD3D();
void CreateRenderTarget();
void CleanupRenderTarget();
void WaitForLastSubmittedFrame();
FrameContext* WaitForNextFrameResources();
void WaitForPendingOperations();
FrameContext* WaitForNextFrameContext();
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
// Main code
@ -256,7 +257,7 @@ int main(int, char**)
// Rendering
ImGui::Render();
FrameContext* frameCtx = WaitForNextFrameResources();
FrameContext* frameCtx = WaitForNextFrameContext();
UINT backBufferIdx = g_pSwapChain->GetCurrentBackBufferIndex();
frameCtx->CommandAllocator->Reset();
@ -282,19 +283,17 @@ int main(int, char**)
g_pd3dCommandList->Close();
g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList);
g_pd3dCommandQueue->Signal(g_fence, ++g_fenceLastSignaledValue);
frameCtx->FenceValue = g_fenceLastSignaledValue;
// Present
HRESULT hr = g_pSwapChain->Present(1, 0); // Present with vsync
//HRESULT hr = g_pSwapChain->Present(0, 0); // Present without vsync
//HRESULT hr = g_pSwapChain->Present(0, g_SwapChainTearingSupport ? DXGI_PRESENT_ALLOW_TEARING : 0); // Present without vsync
g_SwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED);
UINT64 fenceValue = g_fenceLastSignaledValue + 1;
g_pd3dCommandQueue->Signal(g_fence, fenceValue);
g_fenceLastSignaledValue = fenceValue;
frameCtx->FenceValue = fenceValue;
g_frameIndex++;
}
WaitForLastSubmittedFrame();
WaitForPendingOperations();
// Cleanup
ImGui_ImplDX12_Shutdown();
@ -409,14 +408,24 @@ bool CreateDeviceD3D(HWND hWnd)
return false;
{
IDXGIFactory4* dxgiFactory = nullptr;
IDXGIFactory5* dxgiFactory = nullptr;
IDXGISwapChain1* swapChain1 = nullptr;
if (CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)) != S_OK)
return false;
BOOL allow_tearing = FALSE;
dxgiFactory->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allow_tearing, sizeof(allow_tearing));
g_SwapChainTearingSupport = (allow_tearing == TRUE);
if (g_SwapChainTearingSupport)
sd.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
if (dxgiFactory->CreateSwapChainForHwnd(g_pd3dCommandQueue, hWnd, &sd, nullptr, nullptr, &swapChain1) != S_OK)
return false;
if (swapChain1->QueryInterface(IID_PPV_ARGS(&g_pSwapChain)) != S_OK)
return false;
if (g_SwapChainTearingSupport)
dxgiFactory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER);
swapChain1->Release();
dxgiFactory->Release();
g_pSwapChain->SetMaximumFrameLatency(APP_NUM_BACK_BUFFERS);
@ -465,49 +474,33 @@ void CreateRenderTarget()
void CleanupRenderTarget()
{
WaitForLastSubmittedFrame();
WaitForPendingOperations();
for (UINT i = 0; i < APP_NUM_BACK_BUFFERS; i++)
if (g_mainRenderTargetResource[i]) { g_mainRenderTargetResource[i]->Release(); g_mainRenderTargetResource[i] = nullptr; }
}
void WaitForLastSubmittedFrame()
void WaitForPendingOperations()
{
FrameContext* frameCtx = &g_frameContext[g_frameIndex % APP_NUM_FRAMES_IN_FLIGHT];
g_pd3dCommandQueue->Signal(g_fence, ++g_fenceLastSignaledValue);
UINT64 fenceValue = frameCtx->FenceValue;
if (fenceValue == 0)
return; // No fence was signaled
frameCtx->FenceValue = 0;
if (g_fence->GetCompletedValue() >= fenceValue)
return;
g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent);
WaitForSingleObject(g_fenceEvent, INFINITE);
g_fence->SetEventOnCompletion(g_fenceLastSignaledValue, g_fenceEvent);
::WaitForSingleObject(g_fenceEvent, INFINITE);
}
FrameContext* WaitForNextFrameResources()
FrameContext* WaitForNextFrameContext()
{
UINT nextFrameIndex = g_frameIndex + 1;
g_frameIndex = nextFrameIndex;
HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, nullptr };
DWORD numWaitableObjects = 1;
FrameContext* frameCtx = &g_frameContext[nextFrameIndex % APP_NUM_FRAMES_IN_FLIGHT];
UINT64 fenceValue = frameCtx->FenceValue;
if (fenceValue != 0) // means no fence was signaled
FrameContext* frame_context = &g_frameContext[g_frameIndex % APP_NUM_FRAMES_IN_FLIGHT];
if (g_fence->GetCompletedValue() < frame_context->FenceValue)
{
frameCtx->FenceValue = 0;
g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent);
waitableObjects[1] = g_fenceEvent;
numWaitableObjects = 2;
g_fence->SetEventOnCompletion(frame_context->FenceValue, g_fenceEvent);
HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, g_fenceEvent };
::WaitForMultipleObjects(2, waitableObjects, TRUE, INFINITE);
}
else
::WaitForSingleObject(g_hSwapChainWaitableObject, INFINITE);
WaitForMultipleObjects(numWaitableObjects, waitableObjects, TRUE, INFINITE);
return frameCtx;
return frame_context;
}
// Forward declare message handler from imgui_impl_win32.cpp
@ -528,9 +521,10 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_SIZE:
if (g_pd3dDevice != nullptr && wParam != SIZE_MINIMIZED)
{
WaitForLastSubmittedFrame();
CleanupRenderTarget();
HRESULT result = g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT);
DXGI_SWAP_CHAIN_DESC1 desc = {};
g_pSwapChain->GetDesc1(&desc);
HRESULT result = g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), desc.Format, desc.Flags);
assert(SUCCEEDED(result) && "Failed to resize swapchain.");
CreateRenderTarget();
}

View file

@ -1,4 +1,4 @@
// Dear ImGui: standalone example application for DirectX 9
// Dear ImGui: standalone example application for Windows API + DirectX 9
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq

View file

@ -1,4 +1,4 @@
// Dear ImGui: standalone example application for Win32 + OpenGL 3
// Dear ImGui: standalone example application for Windows API + OpenGL
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq

View file

@ -1,4 +1,4 @@
// Dear ImGui: standalone example application for Win32 + Vulkan
// Dear ImGui: standalone example application for Windows API + Vulkan
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
@ -47,6 +47,7 @@ static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static ImGui_ImplVulkanH_Window g_MainWindowData;
static uint32_t g_MinImageCount = 2;
static bool g_SwapChainRebuild = false;
static VkImageUsageFlags g_SwapChainImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
static void check_vk_result(VkResult err)
{
@ -228,7 +229,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
// Create SwapChain, RenderPass, Framebuffer, etc.
IM_ASSERT(g_MinImageCount >= 2);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount, g_SwapChainImageUsage);
}
static void CleanupVulkan()
@ -403,12 +404,12 @@ int main(int, char**)
init_info.Queue = g_Queue;
init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool;
init_info.RenderPass = wd->RenderPass;
init_info.Subpass = 0;
init_info.MinImageCount = g_MinImageCount;
init_info.ImageCount = wd->ImageCount;
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.Allocator = g_Allocator;
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
init_info.PipelineInfoMain.Subpass = 0;
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info);
@ -549,7 +550,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height))
{
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount, g_SwapChainImageUsage);
g_MainWindowData.FrameIndex = 0;
g_SwapChainRebuild = false;
}

View file

@ -39,6 +39,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_vulkan", "exa
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_sdlgpu3", "example_sdl3_sdlgpu3\example_sdl3_sdlgpu3.vcxproj", "{C22CB6F8-39A5-4DDA-90ED-4ACA4E81E1E5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_directx11", "example_sdl3_directx11\example_sdl3_directx11.vcxproj", "{009DAC16-1A9C-47BE-9770-A30A046E8090}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -191,6 +193,14 @@ Global
{C22CB6F8-39A5-4DDA-90ED-4ACA4E81E1E5}.Release|Win32.Build.0 = Release|Win32
{C22CB6F8-39A5-4DDA-90ED-4ACA4E81E1E5}.Release|x64.ActiveCfg = Release|x64
{C22CB6F8-39A5-4DDA-90ED-4ACA4E81E1E5}.Release|x64.Build.0 = Release|x64
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Debug|Win32.ActiveCfg = Debug|Win32
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Debug|Win32.Build.0 = Debug|Win32
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Debug|x64.ActiveCfg = Debug|x64
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Debug|x64.Build.0 = Debug|x64
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Release|Win32.ActiveCfg = Release|Win32
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Release|Win32.Build.0 = Release|Win32
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Release|x64.ActiveCfg = Release|x64
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE