-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add glfw wgpu desktop and multiviewport support #7132
Changes from 11 commits
6fda112
e7b5f87
e5cf10b
62cfa98
fff4391
ad666db
b271eff
82d92aa
e92aa28
c770f20
3de52f8
44c7dfc
0573513
c623669
04f4001
1ff90c5
fbf45ad
6b7358e
65dc67f
fd75685
fc570ac
286cd5b
3c435c0
da29b77
9d9ca37
adcc321
40df3db
0a1f5b9
868facf
085781f
8be48a4
38ddfb2
29ff159
f080228
cf4c10b
5c5ae80
37b37fc
976dc23
515b437
742e534
9638c28
25a492f
d3c3514
9a2b598
0bf134a
f959c41
e7712ff
4f9ba19
231cbee
1db579d
f790d51
76bc1b8
3caa79c
c1743ee
dad1689
fab96a6
daecfff
b475309
f9df6bf
80a5fdb
648278c
7b8107e
4cb0fe3
9ec299e
eba46cb
361432a
fa0120e
b555984
07e8ff9
b720c0f
da18fcb
baaaaea
b8a44b1
c895e98
913151c
a60387a
6ef4f67
50b2ff0
5717f0a
558c57a
9d6818d
49e70e6
ebb8d78
b30df88
4bb7567
fc4d818
6ebbecc
0c9c12c
0b30947
2f2d507
f5d1852
9a7f1b1
8d08e0b
ecdae77
6cd66dd
ec89c07
a3abb1f
80d21d0
69730ea
8ff415b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ | |
|
||
// CHANGELOG | ||
// (minor and older changes stripped away, please see git history for details) | ||
// 2023-12-12: Add support for multi viewports. | ||
// 2023-07-13: Use WGPUShaderModuleWGSLDescriptor's code instead of source. use WGPUMipmapFilterMode_Linear instead of WGPUFilterMode_Linear. (#6602) | ||
// 2023-04-11: Align buffer sizes. Use WGSL shaders instead of precompiled SPIR-V. | ||
// 2023-04-11: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). | ||
|
@@ -38,6 +39,7 @@ | |
#include "imgui_impl_wgpu.h" | ||
#include <limits.h> | ||
#include <webgpu/webgpu.h> | ||
#include <memory> | ||
|
||
// Dear ImGui prototypes from imgui_internal.h | ||
extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed = 0); | ||
|
@@ -72,8 +74,22 @@ struct Uniforms | |
float Gamma; | ||
}; | ||
|
||
// Forward declarations for multi-viewport support | ||
static void ImGui_ImplWGPU_InitPlatformInterface(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ocornut, maybe it's worth renaming everything from WGPU to WebGPU? "wgpu" is a name of the Rust implementation and I see "WebGPU" being used everywhere (except for C API, which I find unfortunate). Otherwise people might think that this backend can only be used with wgpu and not with Dawn. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had chosen to go with WGPU purely based on how the C API was naming things, so yeah WebGPU is fine to go with as well. |
||
static void ImGui_ImplWGPU_ShutdownPlatformInterface(); | ||
|
||
// For multi-viewport support: | ||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data. | ||
struct ImGui_ImplWGPU_ViewportData | ||
{ | ||
ImGui_ImplWGPUH_Window Window; | ||
ImGui_ImplWGPU_ViewportData() { } | ||
~ImGui_ImplWGPU_ViewportData() { } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These constructor and destructors are unnecessary and can be removed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That was a hang over of when I did have objects in there, yup should have been deleted |
||
}; | ||
|
||
struct ImGui_ImplWGPU_Data | ||
{ | ||
WGPUInstance wgpuInstance = nullptr; | ||
WGPUDevice wgpuDevice = nullptr; | ||
WGPUQueue defaultQueue = nullptr; | ||
WGPUTextureFormat renderTargetFormat = WGPUTextureFormat_Undefined; | ||
|
@@ -211,6 +227,25 @@ static void SafeRelease(WGPUTexture& res) | |
wgpuTextureRelease(res); | ||
res = nullptr; | ||
} | ||
static void SafeRelease(WGPURenderPassEncoder& res) | ||
{ | ||
if (res) | ||
wgpuRenderPassEncoderRelease(res); | ||
res = nullptr; | ||
} | ||
static void SafeRelease(WGPUCommandBuffer& res) | ||
{ | ||
if (res) | ||
wgpuCommandBufferRelease(res); | ||
res = nullptr; | ||
} | ||
static void SafeRelease(WGPUCommandEncoder& res) | ||
{ | ||
if (res) | ||
wgpuCommandEncoderRelease(res); | ||
res = nullptr; | ||
} | ||
|
||
|
||
static void SafeRelease(RenderResources& res) | ||
{ | ||
|
@@ -230,6 +265,18 @@ static void SafeRelease(FrameResources& res) | |
SafeRelease(res.IndexBufferHost); | ||
SafeRelease(res.VertexBufferHost); | ||
} | ||
static void SafeRelease(WGPUSwapChain& res) | ||
{ | ||
if (res) | ||
wgpuSwapChainRelease(res); | ||
res = nullptr; | ||
} | ||
static void SafeRelease(WGPUSurface& res) | ||
{ | ||
if (res) | ||
wgpuSurfaceRelease(res); | ||
res = nullptr; | ||
} | ||
|
||
static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const char* wgsl_source) | ||
{ | ||
|
@@ -699,7 +746,7 @@ void ImGui_ImplWGPU_InvalidateDeviceObjects() | |
SafeRelease(bd->pFrameResources[i]); | ||
} | ||
|
||
bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format) | ||
bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format, WGPUInstance instance) | ||
{ | ||
ImGuiIO& io = ImGui::GetIO(); | ||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); | ||
|
@@ -709,7 +756,11 @@ bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextur | |
io.BackendRendererUserData = (void*)bd; | ||
io.BackendRendererName = "imgui_impl_webgpu"; | ||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. | ||
#ifndef __EMSCRIPTEN__ | ||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // Enable multiviewport on desktop. | ||
#endif | ||
|
||
bd->wgpuInstance = instance; | ||
bd->wgpuDevice = device; | ||
bd->defaultQueue = wgpuDeviceGetQueue(bd->wgpuDevice); | ||
bd->renderTargetFormat = rt_format; | ||
|
@@ -739,6 +790,12 @@ bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextur | |
fr->VertexBufferSize = 5000; | ||
} | ||
|
||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) | ||
{ | ||
IM_ASSERT(instance != nullptr && "WGPUInstance required for multi viewport!"); | ||
ImGui_ImplWGPU_InitPlatformInterface(); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
|
@@ -756,6 +813,10 @@ void ImGui_ImplWGPU_Shutdown() | |
bd->numFramesInFlight = 0; | ||
bd->frameIndex = UINT_MAX; | ||
|
||
// Clean up windows | ||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) | ||
ImGui_ImplWGPU_ShutdownPlatformInterface(); | ||
|
||
io.BackendRendererName = nullptr; | ||
io.BackendRendererUserData = nullptr; | ||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset; | ||
|
@@ -769,6 +830,153 @@ void ImGui_ImplWGPU_NewFrame() | |
ImGui_ImplWGPU_CreateDeviceObjects(); | ||
} | ||
|
||
//-------------------------------------------------------------------------------------------------------- | ||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT | ||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. | ||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. | ||
//-------------------------------------------------------------------------------------------------------- | ||
|
||
|
||
static void ImGui_ImplWGPU_CreateWindow(ImGuiViewport* viewport) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably be moved out of the backend and user should provide this instead - there's no easy way to handle this for every platform/WebGPU impl. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 100% this is the main thing I was struggling with trying to fix, would it be just a callback that a user would need to assign to ? |
||
{ | ||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); | ||
ImGui_ImplWGPU_ViewportData* vd = IM_NEW(ImGui_ImplWGPU_ViewportData)(); | ||
viewport->RendererUserData = vd; | ||
|
||
WGPUChainedStruct chainedDescriptor = {}; | ||
// ------ ISSUE unknown for linux and apple ------------- | ||
#ifndef __EMSCRIPTEN__ | ||
#ifdef _WIN32 | ||
chainedDescriptor.sType = WGPUSType_SurfaceDescriptorFromWindowsHWND; | ||
std::unique_ptr<WGPUSurfaceDescriptorFromWindowsHWND> surfaceDescFromHandle = std::make_unique<WGPUSurfaceDescriptorFromWindowsHWND>(); | ||
surfaceDescFromHandle->hwnd = viewport->PlatformHandleRaw; | ||
#elif defined(__APPLE__) | ||
chainedDescriptor.sType = WGPUSType_SurfaceDescriptorFromMetalLayer; | ||
std::unique_ptr<WGPUSurfaceDescriptorFromMetalLayer> surfaceDescFromHandle = std::make_unique<WGPUSurfaceDescriptorFromMetalLayer>(); | ||
NSWindow* ns_window = viewport->PlatformHandleRaw; | ||
[ns_window.contentView setWantsLayer : YES]; | ||
metal_layer = [CAMetalLayer layer]; | ||
[ns_window.contentView setLayer : metal_layer] ; | ||
surfaceDescFromHandle->layer = metal_layer; | ||
// #elif defined(DAWN_USE_WAYLAND) | ||
// struct wl_display* wayland_display = glfwGetWaylandDisplay(); | ||
// struct wl_surface* wayland_surface = glfwGetWaylandWindow(window); | ||
// chainedDescriptor.sType = WGPUSType_SurfaceDescriptorFromWindowsHWND; | ||
// std::unique_ptr<WGPUSurfaceDescriptorFromWaylandSurface> surfaceDescFromHandle = std::make_unique<WGPUSurfaceDescriptorFromWaylandSurface>(); | ||
// surfaceDescFromHandle->display = wayland_display; | ||
// surfaceDescFromHandle->surface = wayland_surface; | ||
// #else | ||
// Display* x11_display = glfwGetX11Display(); | ||
// Window x11_window = glfwGetX11Window((GLFWwindow*) viewport->PlatformHandle); | ||
// chainedDescriptor.sType = WGPUSType_SurfaceDescriptorFromXlibWindow; | ||
// std::unique_ptr<WGPUSurfaceDescriptorFromXlibWindow> surfaceDescFromHandle = std::make_unique<WGPUSurfaceDescriptorFromXlibWindow>(); | ||
// surfaceDescFromHandle->display = x11_display; | ||
// surfaceDescFromHandle->window = x11_window; | ||
#endif | ||
// ------------------------------------------------------ | ||
|
||
surfaceDescFromHandle->chain = chainedDescriptor; | ||
WGPUSurfaceDescriptor surfaceDescriptor = {}; | ||
surfaceDescriptor.nextInChain = &surfaceDescFromHandle->chain; | ||
|
||
vd->Window.surface = wgpuInstanceCreateSurface(bd->wgpuInstance, &surfaceDescriptor); | ||
#endif | ||
WGPUSwapChainDescriptor swapDescriptor = {}; | ||
swapDescriptor.usage = WGPUTextureUsage_RenderAttachment; | ||
swapDescriptor.format = bd->renderTargetFormat; | ||
swapDescriptor.width = viewport->Size.x; | ||
swapDescriptor.height = viewport->Size.y; | ||
swapDescriptor.presentMode = WGPUPresentMode_Fifo; | ||
|
||
vd->Window.swapChain = wgpuDeviceCreateSwapChain(bd->wgpuDevice, vd->Window.surface, &swapDescriptor); | ||
} | ||
|
||
|
||
static void ImGui_ImplWGPU_DestroyWindow(ImGuiViewport* viewport) | ||
{ | ||
if (ImGui_ImplWGPU_ViewportData* vd = (ImGui_ImplWGPU_ViewportData*)viewport->RendererUserData) | ||
{ | ||
SafeRelease(vd->Window.swapChain); | ||
SafeRelease(vd->Window.surface); | ||
IM_DELETE(vd); | ||
} | ||
viewport->RendererUserData = nullptr; | ||
} | ||
|
||
|
||
static void ImGui_ImplWGPU_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) | ||
{ | ||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); | ||
ImGui_ImplWGPU_ViewportData* vd = (ImGui_ImplWGPU_ViewportData*)viewport->RendererUserData; | ||
|
||
SafeRelease(vd->Window.swapChain); | ||
|
||
WGPUSwapChainDescriptor swapDescriptor = {}; | ||
swapDescriptor.usage = WGPUTextureUsage_RenderAttachment; | ||
swapDescriptor.format = bd->renderTargetFormat; | ||
swapDescriptor.width = size.x; | ||
swapDescriptor.height = size.y; | ||
swapDescriptor.presentMode = WGPUPresentMode_Fifo; | ||
|
||
vd->Window.swapChain = wgpuDeviceCreateSwapChain(bd->wgpuDevice, vd->Window.surface, &swapDescriptor); | ||
} | ||
|
||
static void ImGui_ImplWGPU_RenderWindow(ImGuiViewport* viewport, void*) | ||
{ | ||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); | ||
ImGui_ImplWGPU_ViewportData* vd = (ImGui_ImplWGPU_ViewportData*)viewport->RendererUserData; | ||
|
||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); | ||
WGPURenderPassColorAttachment color_attachments = {}; | ||
color_attachments.view = wgpuSwapChainGetCurrentTextureView(vd->Window.swapChain); | ||
color_attachments.loadOp = WGPULoadOp_Clear; | ||
color_attachments.storeOp = WGPUStoreOp_Store; | ||
color_attachments.clearValue = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't work without this: color_attachments.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is a new requirement imposed in a version of dawn that I had yet to work with, If that is required then putting it in should be done. |
||
|
||
WGPURenderPassDescriptor render_pass_desc = {}; | ||
render_pass_desc.colorAttachmentCount = 1; | ||
render_pass_desc.colorAttachments = &color_attachments; | ||
render_pass_desc.depthStencilAttachment = nullptr; | ||
|
||
WGPUCommandEncoderDescriptor enc_desc = {}; | ||
WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(bd->wgpuDevice, &enc_desc); | ||
|
||
WGPURenderPassEncoder pass = wgpuCommandEncoderBeginRenderPass(encoder, &render_pass_desc); | ||
ImGui_ImplWGPU_RenderDrawData(viewport->DrawData, pass); | ||
wgpuRenderPassEncoderEnd(pass); | ||
|
||
WGPUCommandBufferDescriptor cmd_buffer_desc = {}; | ||
WGPUCommandBuffer cmd_buffer = wgpuCommandEncoderFinish(encoder, &cmd_buffer_desc); | ||
WGPUQueue queue = wgpuDeviceGetQueue(bd->wgpuDevice); | ||
wgpuQueueSubmit(queue, 1, &cmd_buffer); | ||
|
||
SafeRelease(color_attachments.view); | ||
SafeRelease(pass); | ||
SafeRelease(encoder); | ||
SafeRelease(cmd_buffer); | ||
} | ||
|
||
static void ImGui_ImplWGPU_SwapBuffers(ImGuiViewport* viewport, void*) | ||
{ | ||
ImGui_ImplWGPU_ViewportData* vd = (ImGui_ImplWGPU_ViewportData*)viewport->RendererUserData; | ||
wgpuSwapChainPresent(vd->Window.swapChain); | ||
} | ||
|
||
void ImGui_ImplWGPU_InitPlatformInterface() | ||
{ | ||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); | ||
platform_io.Renderer_CreateWindow = ImGui_ImplWGPU_CreateWindow; | ||
platform_io.Renderer_DestroyWindow = ImGui_ImplWGPU_DestroyWindow; | ||
platform_io.Renderer_SetWindowSize = ImGui_ImplWGPU_SetWindowSize; | ||
platform_io.Renderer_RenderWindow = ImGui_ImplWGPU_RenderWindow; | ||
platform_io.Renderer_SwapBuffers = ImGui_ImplWGPU_SwapBuffers; | ||
} | ||
|
||
void ImGui_ImplWGPU_ShutdownPlatformInterface() | ||
{ | ||
ImGui::DestroyPlatformWindows(); | ||
} | ||
|
||
//----------------------------------------------------------------------------- | ||
|
||
#endif // #ifndef IMGUI_DISABLE |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,7 @@ | |
|
||
#include <webgpu/webgpu.h> | ||
|
||
IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format = WGPUTextureFormat_Undefined); | ||
IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format = WGPUTextureFormat_Undefined, WGPUInstance instance = nullptr); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably needs a comment which will explain why "instance" is optional here (so that people don't need to read the implementation to know that). |
||
IMGUI_IMPL_API void ImGui_ImplWGPU_Shutdown(); | ||
IMGUI_IMPL_API void ImGui_ImplWGPU_NewFrame(); | ||
IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder); | ||
|
@@ -31,4 +31,17 @@ IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURen | |
IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects(); | ||
IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects(); | ||
|
||
// Helper structure to hold the data needed by one rendering context into one OS window | ||
// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it's not meant to be used by other people, then maybe let's move it into the example's main.cpp? Actually, it would be pretty handy since you'll be able to use Dawn's |
||
struct ImGui_ImplWGPUH_Window | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does "H" stand for in this name? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Helper would be my assumption similar to some of the other questions, the vulkan one had a similar naming convention. I feel using the vulkan backend to base my PR was a bad idea xD |
||
{ | ||
WGPUSwapChain swapChain; | ||
WGPUSurface surface; | ||
|
||
ImGui_ImplWGPUH_Window() | ||
{ | ||
memset((void*)this, 0, sizeof(*this)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should probably do WGPUSwapChain swapChain = nullptr;
WGPUSurface surface = nullptr; or ImGui_ImplWGPUH_Window() : swapChain(nullptr), surface(nullptr) {} If doing the former, the default constructor can be removed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another hang over from copying the vulkan code as it did a similar thing. |
||
} | ||
}; | ||
|
||
#endif // #ifndef IMGUI_DISABLE |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# Example usage: | ||
# cmake -B build -g "Ninja" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably better to list all steps and explain that you need to have Dawn cloned at "external/libraries/dawn": mkdir build && cd build
cmake ..
cmake --build . The second step would look like this, if you add an option to specify Dawn's dir: cmake .. -DIMGUI_DAWN_DIR=<dir of cloned Dawn repo> |
||
|
||
cmake_minimum_required(VERSION 3.10.2) | ||
project(imgui_example_emscripten_wgpu C CXX) | ||
|
||
if(NOT CMAKE_BUILD_TYPE) | ||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE) | ||
endif() | ||
|
||
set(CMAKE_CXX_STANDARD 17) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't Dear ImGui still C++11? (I see that other examples are) - what are some C++17 features that you need here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another hangup on copying from the vulkan cmake (might want to check the vulkan backend and examples to maybe nip those unless they are needed I assume) |
||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES") | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_PROTOTYPES") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it really needed? Compiled fine without this for me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah these are not needed, was me being sloppy checking the cmake. (again copied from vulkan but this time I think vulkan needs those) |
||
|
||
set(BUILD_TESTING OFF) | ||
set(BUILD_TESTING_STATIC OFF) | ||
set(BUILD_TESTING_SHARED OFF) | ||
|
||
# Dear ImGui | ||
set(IMGUI_DIR ../../) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better do this: set(IMGUI_DIR "${CMAKE_CURRENT_LIST_DIR}/../..")
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks good, might want to do the same change in the vulkan example too. |
||
include_directories(${IMGUI_DIR} ${IMGUI_DIR}/backends ..) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better to use this: target_include_directories(example_emscripten_wgpu PRIVATE ${IMGUI_DIR} ${IMGUI_DIR}/backends) |
||
|
||
# Libraries | ||
if(EMSCRIPTEN) | ||
set(LIBRARIES glfw) | ||
add_compile_options(-sDISABLE_EXCEPTION_CATCHING=1 -DIMGUI_DISABLE_FILE_FUNCTIONS=1) | ||
else() | ||
# Dawn wgpu desktop | ||
set(DAWN_FETCH_DEPENDENCIES ON) | ||
add_subdirectory("external/libraries/dawn" dawn EXCLUDE_FROM_ALL) # point this to up to date dawn repo | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would probably be better to allow users to set DAWN_DIR variable and use that instead so that
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was unsure the best approach to handle this, might need to account for wgpu-native as well (which I had not) |
||
set(LIBRARIES webgpu_dawn webgpu_cpp webgpu_glfw glfw) | ||
endif() | ||
|
||
add_executable(example_emscripten_wgpu | ||
main.cpp | ||
${IMGUI_DIR}/backends/imgui_impl_glfw.cpp | ||
${IMGUI_DIR}/backends/imgui_impl_wgpu.cpp | ||
${IMGUI_DIR}/imgui.cpp | ||
${IMGUI_DIR}/imgui_draw.cpp | ||
${IMGUI_DIR}/imgui_demo.cpp | ||
${IMGUI_DIR}/imgui_tables.cpp | ||
${IMGUI_DIR}/imgui_widgets.cpp | ||
) | ||
|
||
# Libraries | ||
if(EMSCRIPTEN) | ||
set_target_properties(example_emscripten_wgpu PROPERTIES OUTPUT_NAME "index") | ||
set_target_properties(example_emscripten_wgpu PROPERTIES SUFFIX ".html") | ||
set_target_properties(example_emscripten_wgpu PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/web) | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --shell-file ${CMAKE_SOURCE_DIR}/../libs/emscripten/shell_minimal.html") | ||
|
||
target_link_options(example_emscripten_wgpu PRIVATE | ||
"-sUSE_WEBGPU=1" | ||
"-sUSE_GLFW=3" | ||
"-sWASM=1" | ||
"-sALLOW_MEMORY_GROWTH=1" | ||
"-sNO_EXIT_RUNTIME=0" | ||
"-sASSERTIONS=1" | ||
"-sDISABLE_EXCEPTION_CATCHING=1" | ||
"-sNO_FILESYSTEM=1" | ||
) | ||
endif() | ||
|
||
target_link_libraries(example_emscripten_wgpu ${LIBRARIES}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be removed if
ImGui_ImplWGPU_CreateWindow
is not included in the backend.