Skip to content

Commit ff672b2

Browse files
BrutPittocornut
authored andcommitted
Examples: SDL2+WebGPU, SDL3+WebGPU: add new examples. (#8381)
1 parent 778aed9 commit ff672b2

File tree

9 files changed

+2030
-0
lines changed

9 files changed

+2030
-0
lines changed

docs/CHANGELOG.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ Other Changes:
102102
latest Dawn-Native and WGPU-Native. (#8381, #8567, #8191, #7435) [@brutpitt]
103103
- GLFW+WebGPU: removed unnecessary ImGui_ImplWGPU_InvalidateDeviceObjects() call
104104
during surface resize. (#8381)
105+
- SDL2+WebGPU: added new example (Emscripten + native Dawn/WGPU). (#8381) [@brutpitt]
106+
- SDL3+WebGPU: added new example (Emscripten + native Dawn/WGPU). (#8381) [@brutpitt]
105107

106108

107109
-----------------------------------------------------------------------
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
# Building for desktop (WebGPU-native) with Dawn:
2+
# 1. git clone https://github.com/google/dawn dawn
3+
# 2. cmake -B build -DIMGUI_DAWN_DIR=dawn
4+
# 3. cmake --build build
5+
# The resulting binary will be found at one of the following locations:
6+
# * build/Debug/example_sdl2_wgpu[.exe]
7+
# * build/example_sdl2_wgpu[.exe]
8+
9+
# Building for desktop (WGPU-Native) with WGPU-Native:
10+
# 1. download WGPU-Native autogenerated binary modules for your platform/compiler from: https://github.com/gfx-rs/wgpu-native/releases
11+
# 2. unzip the downloaded file in your_preferred_folder
12+
# 3. cmake -B build -DIMGUI_WGPU_DIR=your_preferred_folder ("full path" or "relative" starting from current directory)
13+
# 4. cmake --build build
14+
# The resulting binary will be found at one of the following locations:
15+
# * build/Debug/example_sdl2_wgpu[.exe]
16+
# * build/example_sdl2_wgpu[.exe]
17+
18+
# Building for Emscripten:
19+
# 1. Install Emscripten SDK following the instructions: https://emscripten.org/docs/getting_started/downloads.html
20+
# 2. Install Ninja build system
21+
# 3. emcmake cmake -G Ninja -B build
22+
# (optional) -DIMGUI_EMSCRIPTEN_WEBGPU_FLAG="--use-port=path/to/emdawnwebgpu_package/emdawnwebgpu.port.py", see ReadMe.md
23+
# 3. cmake --build build
24+
# 4. emrun build/index.html
25+
26+
cmake_minimum_required(VERSION 3.22) # Dawn requires CMake >= 3.22
27+
project(imgui_example_sdl2_wgpu C CXX)
28+
29+
set(IMGUI_EXECUTABLE example_sdl2_wgpu)
30+
31+
if(NOT CMAKE_BUILD_TYPE)
32+
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
33+
endif()
34+
35+
set(CMAKE_CXX_STANDARD 17) # Dawn requires C++17
36+
37+
# Dear ImGui
38+
set(IMGUI_DIR ../../)
39+
40+
# ImGui example commons source files
41+
set(IMGUI_EXAMPLE_SOURCE_FILES
42+
main.cpp
43+
# backend files
44+
${IMGUI_DIR}/backends/imgui_impl_sdl2.cpp
45+
${IMGUI_DIR}/backends/imgui_impl_wgpu.cpp
46+
# Dear ImGui files
47+
${IMGUI_DIR}/imgui.cpp
48+
${IMGUI_DIR}/imgui_draw.cpp
49+
${IMGUI_DIR}/imgui_demo.cpp
50+
${IMGUI_DIR}/imgui_tables.cpp
51+
${IMGUI_DIR}/imgui_widgets.cpp
52+
)
53+
54+
if(EMSCRIPTEN)
55+
if(NOT IMGUI_EMSCRIPTEN_WEBGPU_FLAG) # if IMGUI_EMSCRIPTEN_WEBGPU_FLAG not used, set by current EMSCRIPTEN version
56+
if(EMSCRIPTEN_VERSION VERSION_GREATER_EQUAL "4.0.10")
57+
set(IMGUI_EMSCRIPTEN_WEBGPU_FLAG "--use-port=emdawnwebgpu" CACHE STRING "Choose between --use-port=emdawnwebgpu (Dawn implementation of EMSCRIPTEN) and -sUSE_WEBGPU=1 (WGPU implementation of EMSCRIPTEN, deprecated in 4.0.10): default to --use-port=emdawnwebgpu for EMSCRIPTEN >= 4.0.10")
58+
else()
59+
set(IMGUI_EMSCRIPTEN_WEBGPU_FLAG "-sUSE_WEBGPU=1" CACHE STRING "Use -sUSE_WEBGPU=1 for EMSCRIPTEN WGPU implementation")
60+
endif()
61+
else() # if IMGUI_EMSCRIPTEN_WEBGPU_FLAG used, check correct version
62+
if(EMSCRIPTEN_VERSION VERSION_LESS "4.0.10" AND "${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}" MATCHES "emdawnwebgpu")
63+
# it's necessary EMSCRIPTEN >= v4.0.10 (although "--use-port=path/to/emdawnwebgpu.port.py" is supported/tested from v4.0.8)
64+
message(FATAL_ERROR "emdawnwebgpu needs EMSCRIPTEN version >= 4.0.10")
65+
endif()
66+
endif()
67+
68+
add_compile_options(-sDISABLE_EXCEPTION_CATCHING=1 -DIMGUI_DISABLE_FILE_FUNCTIONS=1)
69+
else() # Native/Desktop build
70+
find_package(SDL2 REQUIRED) # SDL_MAIN_HANDLED
71+
72+
if(NOT IMGUI_DAWN_DIR AND NOT IMGUI_WGPU_DIR) # if it's Native/Desktop build, IMGUI_DAWN_DIR or IMGUI_WGPU_DIR must be specified
73+
message(FATAL_ERROR "Please specify the Dawn or WGPU base directory")
74+
endif()
75+
76+
if(IMGUI_DAWN_DIR AND IMGUI_WGPU_DIR) # both IMGUI_DAWN_DIR and IMGUI_WGPU_DIR cannot be set
77+
message(FATAL_ERROR "Please specify only one between Dawn / WGPU base directory")
78+
endif()
79+
80+
if(APPLE) # Add SDL2 module to get Surface, with libs and file property for MacOS build
81+
set_source_files_properties(${IMGUI_DIR}/backends/imgui_impl_wgpu.cpp PROPERTIES COMPILE_FLAGS "-x objective-c++")
82+
set(OS_LIBRARIES "-framework CoreFoundation -framework QuartzCore -framework Metal -framework MetalKit -framework Cocoa")
83+
endif()
84+
85+
if(IMGUI_DAWN_DIR) # DAWN-Native build options
86+
set(IMGUI_DAWN_DIR CACHE PATH "Path to Dawn repository")
87+
if(NOT IMGUI_DAWN_DIR)
88+
message(FATAL_ERROR "Please specify the Dawn repository by setting IMGUI_DAWN_DIR")
89+
endif()
90+
91+
option(DAWN_USE_GLFW OFF) # disable buildin GLFW in DAWN when we use SDL2 / SDL3
92+
93+
option(DAWN_FETCH_DEPENDENCIES "Use fetch_dawn_dependencies.py as an alternative to using depot_tools" ON)
94+
set(DAWN_BUILD_MONOLITHIC_LIBRARY "STATIC" CACHE STRING "Build monolithic library: SHARED, STATIC, or OFF.")
95+
96+
# Dawn builds many things by default - disable things we don't need
97+
option(DAWN_BUILD_SAMPLES "Enables building Dawn's samples" OFF)
98+
option(TINT_BUILD_CMD_TOOLS "Build the Tint command line tools" OFF)
99+
option(TINT_BUILD_DOCS "Build documentation" OFF)
100+
option(TINT_BUILD_TESTS "Build tests" OFF)
101+
if(NOT APPLE)
102+
option(TINT_BUILD_MSL_WRITER "Build the MSL output writer" OFF)
103+
endif()
104+
if(WIN32)
105+
option(DAWN_FORCE_SYSTEM_COMPONENT_LOAD "Allow system component fallback" ON)
106+
option(TINT_BUILD_SPV_READER "Build the SPIR-V input reader" OFF)
107+
option(TINT_BUILD_WGSL_READER "Build the WGSL input reader" ON)
108+
option(TINT_BUILD_GLSL_WRITER "Build the GLSL output writer" OFF)
109+
option(TINT_BUILD_GLSL_VALIDATOR "Build the GLSL output validator" OFF)
110+
option(TINT_BUILD_SPV_WRITER "Build the SPIR-V output writer" ON)
111+
option(TINT_BUILD_WGSL_WRITER "Build the WGSL output writer" ON)
112+
endif()
113+
# check if WAYLAND is the current Session Type and enable DAWN_USE_WAYLAND Wayland option @compile time
114+
# You can override this using: cmake -DDAWN_USE_WAYLAND=X (X = ON | OFF)
115+
if(LINUX)
116+
if($ENV{XDG_SESSION_TYPE} MATCHES wayland)
117+
option(DAWN_USE_WAYLAND "Enable support for Wayland surface" ON)
118+
endif()
119+
endif()
120+
121+
add_subdirectory("${IMGUI_DAWN_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/dawn" EXCLUDE_FROM_ALL)
122+
123+
set(LIBRARIES webgpu_dawn ${OS_LIBRARIES})
124+
else() # WGPU-Native build options
125+
126+
set(WGPU_NATIVE_LIB_DIR ${IMGUI_WGPU_DIR}/lib)
127+
find_library(WGPU_LIBRARY NAMES libwgpu_native.a wgpu_native.lib wgpu_native HINTS ${WGPU_NATIVE_LIB_DIR} REQUIRED)
128+
if(WIN32)
129+
set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32 Propsys RuntimeObject)
130+
elseif(UNIX AND NOT APPLE)
131+
set(OS_LIBRARIES "-lm -ldl")
132+
endif()
133+
134+
set(LIBRARIES ${WGPU_LIBRARY} ${OS_LIBRARIES})
135+
endif()
136+
endif()
137+
138+
add_executable(${IMGUI_EXECUTABLE} ${IMGUI_EXAMPLE_SOURCE_FILES})
139+
140+
target_include_directories(${IMGUI_EXECUTABLE} PUBLIC
141+
${IMGUI_DIR}
142+
${IMGUI_DIR}/backends
143+
${SDL2_INCLUDE_DIRS}
144+
)
145+
146+
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_EXAMPLE_SDL2_WGPU")
147+
148+
# compiler option only for IMGUI_EXAMPLE_SOURCE_FILES
149+
if (MSVC)
150+
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC /W4) # warning level 4
151+
else()
152+
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC -Wall) # -Wextra -Wpedantic
153+
endif()
154+
155+
# IMGUI_IMPL_WEBGPU_BACKEND_DAWN/WGPU internal define is set according to:
156+
# EMSCRIPTEN: by used FLAG
157+
# --use-port=emdawnwebgpu --> IMGUI_IMPL_WEBGPU_BACKEND_DAWN enabled (+EMSCRIPTEN)
158+
# -sUSE_WEBGPU=1 --> IMGUI_IMPL_WEBGPU_BACKEND_WGPU enabled (+EMSCRIPTEN)
159+
# NATIVE: by used SDK installation directory
160+
# if IMGUI_DAWN_DIR is valid --> IMGUI_IMPL_WEBGPU_BACKEND_DAWN enabled
161+
# if IMGUI_WGPU_DIR is valid --> IMGUI_IMPL_WEBGPU_BACKEND_WGPU enabled
162+
163+
if(NOT EMSCRIPTEN) # WegGPU-Native settings
164+
if(IMGUI_DAWN_DIR)
165+
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_DAWN")
166+
else()
167+
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_WGPU")
168+
target_include_directories(${IMGUI_EXECUTABLE} PUBLIC ${IMGUI_WGPU_DIR}/include)
169+
endif()
170+
171+
target_link_libraries(${IMGUI_EXECUTABLE} INTERFACE webgpu_cpp PUBLIC ${LIBRARIES} ${SDL2_LIBRARIES})
172+
else() # Emscripten settings
173+
set(CMAKE_EXECUTABLE_SUFFIX ".html")
174+
175+
if("${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}" MATCHES "emdawnwebgpu")
176+
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC "${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}")
177+
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_DAWN")
178+
else()
179+
target_compile_definitions(${IMGUI_EXECUTABLE} PUBLIC "IMGUI_IMPL_WEBGPU_BACKEND_WGPU")
180+
endif()
181+
message(STATUS "Using ${IMGUI_EMSCRIPTEN_WEBGPU_FLAG} WebGPU implementation")
182+
183+
target_compile_options(${IMGUI_EXECUTABLE} PUBLIC "-sUSE_SDL=2")
184+
target_link_options(${IMGUI_EXECUTABLE} PRIVATE
185+
"${IMGUI_EMSCRIPTEN_WEBGPU_FLAG}"
186+
"-sUSE_SDL=2"
187+
"-sWASM=1"
188+
"-sASYNCIFY=1"
189+
"-sALLOW_MEMORY_GROWTH=1"
190+
"-sNO_EXIT_RUNTIME=0"
191+
"-sASSERTIONS=1"
192+
"-sDISABLE_EXCEPTION_CATCHING=1"
193+
"-sNO_FILESYSTEM=1"
194+
"--shell-file=${CMAKE_CURRENT_LIST_DIR}/../libs/emscripten/shell_minimal.html"
195+
)
196+
set_target_properties(${IMGUI_EXECUTABLE} PROPERTIES OUTPUT_NAME "index")
197+
endif()
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#
2+
# Makefile to use with emscripten
3+
# See https://emscripten.org/docs/getting_started/downloads.html
4+
# for installation instructions.
5+
#
6+
# This Makefile assumes you have loaded emscripten's environment.
7+
# (On Windows, you may need to execute emsdk_env.bat or encmdprompt.bat ahead)
8+
#
9+
# Running `make -f Makefile.emscripten` will produce three files:
10+
# - web/index.html
11+
# - web/index.js
12+
# - web/index.wasm
13+
#
14+
# All three are needed to run the demo.
15+
16+
CC = emcc
17+
CXX = em++
18+
WEB_DIR = web
19+
EXE = $(WEB_DIR)/index.html
20+
IMGUI_DIR = ../..
21+
SOURCES = main.cpp
22+
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
23+
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl2.cpp $(IMGUI_DIR)/backends/imgui_impl_wgpu.cpp
24+
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
25+
UNAME_S := $(shell uname -s)
26+
CPPFLAGS =
27+
LDFLAGS =
28+
EMS =
29+
30+
##---------------------------------------------------------------------
31+
## EMSCRIPTEN OPTIONS
32+
##---------------------------------------------------------------------
33+
34+
# ("EMS" options gets added to both CPPFLAGS and LDFLAGS, whereas some options are for linker only)
35+
EMS += -s USE_SDL=2
36+
EMS += -s DISABLE_EXCEPTION_CATCHING=1
37+
LDFLAGS += -s WASM=1
38+
LDFLAGS += -s ALLOW_MEMORY_GROWTH=1
39+
LDFLAGS += -s ASYNCIFY=1
40+
LDFLAGS += -s NO_EXIT_RUNTIME=0
41+
LDFLAGS += -s ASSERTIONS=1
42+
43+
# (1) Using legacy WebGPU implementation (Emscripten < 4.0.10)
44+
#EMS += -DIMGUI_IMPL_WEBGPU_BACKEND_WGPU
45+
#LDFLAGS += -s USE_WEBGPU=1
46+
47+
# or (2) Using newer Dawn-based WebGPU port (Emscripten >= 4.0.10)
48+
EMS += --use-port=emdawnwebgpu
49+
LDFLAGS += --use-port=emdawnwebgpu
50+
51+
# Build as single file (binary text encoded in .html file)
52+
#LDFLAGS += -sSINGLE_FILE
53+
54+
# Emscripten allows preloading a file or folder to be accessible at runtime.
55+
# The Makefile for this example project suggests embedding the misc/fonts/ folder into our application, it will then be accessible as "/fonts"
56+
# See documentation for more details: https://emscripten.org/docs/porting/files/packaging_files.html
57+
# (Default value is 0. Set to 1 to enable file-system and include the misc/fonts/ folder as part of the build.)
58+
USE_FILE_SYSTEM ?= 0
59+
ifeq ($(USE_FILE_SYSTEM), 0)
60+
LDFLAGS += -s NO_FILESYSTEM=1
61+
CPPFLAGS += -DIMGUI_DISABLE_FILE_FUNCTIONS
62+
endif
63+
ifeq ($(USE_FILE_SYSTEM), 1)
64+
LDFLAGS += --no-heap-copy --preload-file ../../misc/fonts@/fonts
65+
endif
66+
67+
##---------------------------------------------------------------------
68+
## FINAL BUILD FLAGS
69+
##---------------------------------------------------------------------
70+
71+
CPPFLAGS += -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
72+
#CPPFLAGS += -g
73+
CPPFLAGS += -Wall -Wformat -Os $(EMS)
74+
LDFLAGS += --shell-file ../libs/emscripten/shell_minimal.html
75+
LDFLAGS += $(EMS)
76+
77+
##---------------------------------------------------------------------
78+
## BUILD RULES
79+
##---------------------------------------------------------------------
80+
81+
%.o:%.cpp
82+
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
83+
84+
%.o:$(IMGUI_DIR)/%.cpp
85+
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
86+
87+
%.o:$(IMGUI_DIR)/backends/%.cpp
88+
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
89+
90+
all: $(EXE)
91+
@echo Build complete for $(EXE)
92+
93+
$(WEB_DIR):
94+
mkdir $@
95+
96+
serve: all
97+
python3 -m http.server -d $(WEB_DIR)
98+
99+
$(EXE): $(OBJS) $(WEB_DIR)
100+
$(CXX) -o $@ $(OBJS) $(LDFLAGS)
101+
102+
clean:
103+
rm -f $(EXE) $(OBJS) $(WEB_DIR)/*.js $(WEB_DIR)/*.wasm $(WEB_DIR)/*.wasm.pre

0 commit comments

Comments
 (0)