├── .github
├── FUNDING.yml
└── workflows
│ └── cmake.yml
├── .gitignore
├── CMakeLists.txt
├── LICENSE.txt
├── README.md
├── examples
├── .gitignore
├── CMakeLists.txt
├── hello-glfw3webgpu.c
└── utils.cmake
├── glfw3webgpu.c
└── glfw3webgpu.h
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: eliemichel
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12 | polar: # Replace with a single Polar username
13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14 | custom: ['https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=DNEEF8GDX2EV6¤cy_code=EUR&source=url']
15 |
--------------------------------------------------------------------------------
/.github/workflows/cmake.yml:
--------------------------------------------------------------------------------
1 | name: CMake
2 |
3 | on:
4 | push:
5 | branches: [ "main" ]
6 | pull_request:
7 | branches: [ "main" ]
8 |
9 | env:
10 | BUILD_TYPE: Release
11 |
12 | jobs:
13 | build:
14 | strategy:
15 | fail-fast: false
16 | matrix:
17 | system: [ Linux-x64, Windows-MSVC-x64, Windows-MSYS-x64, MacOS-x64, MacOS-ARM ]
18 | webgpu-backend: [ DAWN, WGPU ]
19 | link-type: [ SHARED, STATIC ]
20 | build-type: [ Debug, Release ]
21 |
22 | include:
23 | - system: Linux-x64
24 | runner: ubuntu-latest
25 | install-deps: |
26 | sudo apt-get update -y
27 | sudo apt-get install -y libwayland-dev libxkbcommon-dev xorg-dev
28 |
29 | - system: Windows-MSVC-x64
30 | runner: windows-latest
31 | exe-extension: .exe
32 | is-multiconfig: true
33 |
34 | - system: Windows-MSYS-x64
35 | runner: windows-latest
36 | msystem: ucrt64
37 | exe-extension: .exe
38 |
39 | - system: MacOS-ARM
40 | runner: macos-latest
41 |
42 | - system: MacOS-x64
43 | runner: macos-13
44 |
45 | - system: emscripten
46 | runner: ubuntu-latest
47 | webgpu-backend: EMSCRIPTEN
48 | link-type: STATIC
49 | build-type: Release
50 | cmake-wrapper: emcmake
51 | emsdk-version: 3.1.61
52 |
53 | # Latest version of Dawn to not support static linking
54 | exclude:
55 | - webgpu-backend: DAWN
56 | link-type: STATIC
57 |
58 | runs-on: ${{ matrix.runner }}
59 |
60 | steps:
61 | - uses: actions/checkout@v4
62 |
63 | - name: Install dependencies
64 | if: ${{ matrix.install-deps }}
65 | run: ${{ matrix.install-deps }}
66 |
67 | - name: Setup MSYS
68 | if: ${{ matrix.msystem }}
69 | uses: msys2/setup-msys2@v2
70 | with:
71 | msystem: ${{ matrix.msystem }}
72 | pacboy: >-
73 | toolchain:p
74 | cmake:p
75 | ninja:p
76 |
77 | - name: Setup emscripten
78 | if: ${{ matrix.emsdk-version }}
79 | uses: mymindstorm/setup-emsdk@v14
80 | with:
81 | version: ${{ matrix.emsdk-version }}
82 |
83 | - name: Configure CMake
84 | if: ${{ ! matrix.msystem }}
85 | run: >
86 | ${{ matrix.cmake-wrapper }} cmake
87 | -S examples
88 | -B build
89 | -DWEBGPU_BACKEND=${{ matrix.webgpu-backend }}
90 | -D${{ matrix.webgpu-backend }}_LINK_TYPE=${{ matrix.link-type }}
91 | -DCMAKE_BUILD_TYPE=${{ matrix.build-type }}
92 |
93 | - name: Build
94 | if: ${{ ! matrix.msystem }}
95 | run: >
96 | cmake
97 | --build build
98 | --config ${{ matrix.build-type }}
99 |
100 | # This is a hack to work around the lack of ${{ variables }} in 'shell' parameter
101 | # We use the SHELL env variable as the value of 'shell'
102 | - name: Configure CMake (MSYS)
103 | if: ${{ matrix.msystem }}
104 | shell: msys2 {0}
105 | run: >
106 | cmake
107 | -S examples
108 | -B build
109 | -DWEBGPU_BACKEND=${{ matrix.webgpu-backend }}
110 | -D${{ matrix.webgpu-backend }}_LINK_TYPE=${{ matrix.link-type }}
111 | -DCMAKE_BUILD_TYPE=${{ matrix.build-type }}
112 |
113 | - name: Build (MSYS)
114 | if: ${{ matrix.msystem }}
115 | shell: msys2 {0}
116 | run: >
117 | cmake
118 | --build build
119 | --config ${{ matrix.build-type }}
120 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | releases/
2 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # This is only meant to be included as a subdirectory in another project.
2 | # It assumes that targets 'glfw' and 'webgpu' exist.
3 | # Look at examples/CMakeLists.txt to see how to use it in a project.
4 |
5 | # The glfw3webgpu target
6 | add_library(glfw3webgpu STATIC glfw3webgpu.c)
7 | target_include_directories(glfw3webgpu PUBLIC .)
8 | target_link_libraries(glfw3webgpu PUBLIC glfw webgpu)
9 |
10 | # Copy compile definitions that are PRIVATE in glfw
11 | if (GLFW_BUILD_COCOA)
12 | target_compile_definitions(glfw3webgpu PRIVATE _GLFW_COCOA)
13 | target_compile_options(glfw3webgpu PRIVATE -x objective-c)
14 | target_link_libraries(glfw3webgpu PRIVATE "-framework Cocoa" "-framework CoreVideo" "-framework IOKit" "-framework QuartzCore")
15 | endif()
16 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 | Copyright (c) 2022-2024 Élie Michel and the wgpu-native authors
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
16 |
17 | GLFW WebGPU Extension
18 | =====================
19 |
20 | This is an extension for the great [GLFW](https://www.glfw.org/) library for using it with **WebGPU native**. It was written as part of the [Learn WebGPU for native C++](https://eliemichel.github.io/LearnWebGPU) tutorial series.
21 |
22 | Table of Contents
23 | -----------------
24 |
25 | - [Overview](#overview)
26 | - [Usage](#usage)
27 | - [Example](#example)
28 | - [License](#license)
29 |
30 | Overview
31 | --------
32 |
33 | This extension simply provides the following function:
34 |
35 | ```C
36 | WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* window);
37 | ```
38 |
39 | Given a GLFW window, `glfwCreateWindowWGPUSurface` returns a WebGPU *surface* that corresponds to the window's back-end. This is a process that is highly platform-specific, which is why I believe it belongs to GLFW.
40 |
41 | Usage
42 | -----
43 |
44 | **NB** The current version of this extension is written for GLFW 3.4. Up to version 1.2.0, it was written for GLFW 3.3.8.
45 |
46 | Your project must link to an implementation of WebGPU (providing `webgpu.h`) and of course to GLFW. Then:
47 |
48 | **Option A** If you use CMake, you can simply include this project as a subdirectory with `add_subdirectory(glfw3webgpu)` (see the content of [`CMakeLists.txt`](CMakeLists.txt)).
49 |
50 | **Option B** Just copy [`glfw3webgpu.h`](glfw3webgpu.h) and [`glfw3webgpu.c`](glfw3webgpu.c) to your project's source tree. On MacOS, you must add the compile option `-x objective-c` and the link libraries `-framework Cocoa`, `-framework CoreVideo`, `-framework IOKit`, and `-framework QuartzCore`.
51 |
52 | Example
53 | -------
54 |
55 | Thanks to this extension it is possible to simply write a fully cross-platform WebGPU hello world:
56 |
57 | ```C
58 | #include "glfw3webgpu.h"
59 |
60 | #define GLFW_INCLUDE_NONE
61 | #include
62 | #include
63 | #include
64 |
65 | int main(int argc, char* argv[]) {
66 | // Init WebGPU
67 | WGPUInstanceDescriptor desc;
68 | desc.nextInChain = NULL;
69 | WGPUInstance instance = wgpuCreateInstance(&desc);
70 |
71 | // Init GLFW
72 | glfwInit();
73 | glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
74 | GLFWwindow* window = glfwCreateWindow(640, 480, "Learn WebGPU", NULL, NULL);
75 |
76 | // Here we create our WebGPU surface from the window!
77 | WGPUSurface surface = glfwCreateWindowWGPUSurface(instance, window);
78 | printf("surface = %p", surface);
79 |
80 | // Terminate GLFW
81 | while (!glfwWindowShouldClose(window)) glfwPollEvents();
82 | glfwDestroyWindow(window);
83 | glfwTerminate();
84 |
85 | return 0;
86 | }
87 | ```
88 |
89 | **NB** The linking process depends on the implementation of WebGPU that you are using. You can find detailed instructions for the `wgpu-native` implementation in [this Hello WebGPU chapter](https://eliemichel.github.io/LearnWebGPU/getting-started/hello-webgpu.html). You may also check out [`examples/CMakeLists.txt`](examples/CMakeLists.txt).
90 |
91 | License
92 | -------
93 |
94 | See [LICENSE.txt](LICENSE.txt).
95 |
--------------------------------------------------------------------------------
/examples/.gitignore:
--------------------------------------------------------------------------------
1 | build*/
2 | webgpu/
3 | glfw/
4 |
--------------------------------------------------------------------------------
/examples/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # This example comes from https://eliemichel.github.io/LearnWebGPU
2 | cmake_minimum_required(VERSION 3.11.0...3.25.0)
3 | project(glfw3webgpu-examples VERSION 1.0.0 LANGUAGES C)
4 |
5 | include(FetchContent)
6 | include(utils.cmake)
7 |
8 | # Dependencies
9 | if (EMSCRIPTEN)
10 |
11 | add_library(glfw INTERFACE)
12 | target_link_options(glfw INTERFACE -sUSE_GLFW=3)
13 |
14 | add_library(webgpu INTERFACE)
15 | target_link_options(webgpu INTERFACE -sUSE_WEBGPU=1)
16 | function(target_copy_webgpu_binaries)
17 | endfunction()
18 |
19 | else (EMSCRIPTEN)
20 |
21 | FetchContent_Declare(
22 | glfw-light
23 | URL https://eliemichel.github.io/LearnWebGPU/_downloads/6873a344e35ea9f5e4fc7e5cc85d3ab8/glfw-3.4.0-light.zip
24 | URL_HASH MD5=e6684142080457e9227e4f78a6f84fc2
25 | )
26 | FetchContent_Declare(
27 | webgpu
28 | URL https://github.com/eliemichel/WebGPU-distribution/archive/refs/tags/main-v0.3.0-alpha.zip
29 | URL_HASH MD5=ea1195dc6c7661c36aa13ea5b734b86e
30 | )
31 | FetchContent_MakeAvailable(glfw-light webgpu)
32 |
33 | endif (EMSCRIPTEN)
34 |
35 | # The glfw3webgpu target
36 | # NB: We specify a second argument only because this is an out-of-tree
37 | # directory, no need to do this in your case.
38 | add_subdirectory(.. glfw3webgpu)
39 |
40 | # Example
41 | add_executable(hello-glfw3webgpu hello-glfw3webgpu.c)
42 | target_link_libraries(hello-glfw3webgpu PRIVATE glfw webgpu glfw3webgpu)
43 | set_target_properties(hello-glfw3webgpu PROPERTIES CXX_STANDARD 17)
44 | target_treat_all_warnings_as_errors(hello-glfw3webgpu)
45 | target_copy_webgpu_binaries(hello-glfw3webgpu)
46 |
--------------------------------------------------------------------------------
/examples/hello-glfw3webgpu.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This is an extension of GLFW for WebGPU, abstracting away the details of
3 | * OS-specific operations.
4 | *
5 | * This file is part of the "Learn WebGPU for C++" book.
6 | * https://eliemichel.github.io/LearnWebGPU
7 | *
8 | * MIT License
9 | * Copyright (c) 2022-2024 Elie Michel
10 | *
11 | * Permission is hereby granted, free of charge, to any person obtaining a copy
12 | * of this software and associated documentation files (the "Software"), to deal
13 | * in the Software without restriction, including without limitation the rights
14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | * copies of the Software, and to permit persons to whom the Software is
16 | * furnished to do so, subject to the following conditions:
17 | *
18 | * The above copyright notice and this permission notice shall be included in all
19 | * copies or substantial portions of the Software.
20 | *
21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 | * SOFTWARE.
28 | */
29 |
30 | #include "glfw3webgpu.h"
31 |
32 | #define GLFW_INCLUDE_NONE
33 | #include
34 | #include
35 | #include
36 |
37 | int main(int argc, char* argv[]) {
38 | (void)argc;
39 | (void)argv;
40 |
41 | // Init WebGPU
42 | WGPUInstance instance = wgpuCreateInstance(NULL);
43 |
44 | // Init GLFW
45 | glfwInit();
46 | glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
47 | GLFWwindow* window = glfwCreateWindow(640, 480, "Learn WebGPU", NULL, NULL);
48 |
49 | // Here we create our WebGPU surface from the window!
50 | WGPUSurface surface = glfwCreateWindowWGPUSurface(instance, window);
51 | printf("surface = %p", (void*)surface);
52 |
53 | // Terminate GLFW
54 | while (!glfwWindowShouldClose(window)) glfwPollEvents();
55 | glfwDestroyWindow(window);
56 | glfwTerminate();
57 |
58 | return 0;
59 | }
60 |
--------------------------------------------------------------------------------
/examples/utils.cmake:
--------------------------------------------------------------------------------
1 | function(target_treat_all_warnings_as_errors Target)
2 | # Treat warnings as errors
3 | set_target_properties(${Target} PROPERTIES COMPILE_WARNING_AS_ERROR ON)
4 |
5 | # Turn all warnings on
6 | if (MSVC)
7 | target_compile_options(${Target} PRIVATE /W4)
8 | else()
9 | target_compile_options(${Target} PRIVATE -Wall -Wextra -pedantic)
10 | endif()
11 | endfunction()
12 |
--------------------------------------------------------------------------------
/glfw3webgpu.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This is an extension of GLFW for WebGPU, abstracting away the details of
3 | * OS-specific operations.
4 | *
5 | * This file is part of the "Learn WebGPU for C++" book.
6 | * https://eliemichel.github.io/LearnWebGPU
7 | *
8 | * Most of this code comes from the wgpu-native triangle example:
9 | * https://github.com/gfx-rs/wgpu-native/blob/master/examples/triangle/main.c
10 | *
11 | * MIT License
12 | * Copyright (c) 2022-2025 Elie Michel and the wgpu-native authors
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining a copy
15 | * of this software and associated documentation files (the "Software"), to deal
16 | * in the Software without restriction, including without limitation the rights
17 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 | * copies of the Software, and to permit persons to whom the Software is
19 | * furnished to do so, subject to the following conditions:
20 | *
21 | * The above copyright notice and this permission notice shall be included in all
22 | * copies or substantial portions of the Software.
23 | *
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 | * SOFTWARE.
31 | */
32 |
33 | #include "glfw3webgpu.h"
34 |
35 | #include
36 |
37 | #include
38 |
39 | #ifdef __EMSCRIPTEN__
40 | # define GLFW_EXPOSE_NATIVE_EMSCRIPTEN
41 | # ifndef GLFW_PLATFORM_EMSCRIPTEN // not defined in older versions of emscripten
42 | # define GLFW_PLATFORM_EMSCRIPTEN 0
43 | # endif
44 | #else // __EMSCRIPTEN__
45 | # ifdef _GLFW_X11
46 | # define GLFW_EXPOSE_NATIVE_X11
47 | # endif
48 | # ifdef _GLFW_WAYLAND
49 | # define GLFW_EXPOSE_NATIVE_WAYLAND
50 | # endif
51 | # ifdef _GLFW_COCOA
52 | # define GLFW_EXPOSE_NATIVE_COCOA
53 | # endif
54 | # ifdef _GLFW_WIN32
55 | # define GLFW_EXPOSE_NATIVE_WIN32
56 | # endif
57 | #endif // __EMSCRIPTEN__
58 |
59 | #ifdef GLFW_EXPOSE_NATIVE_COCOA
60 | # include
61 | # include
62 | #endif
63 |
64 | #ifndef __EMSCRIPTEN__
65 | # include
66 | #endif
67 |
68 | WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* window) {
69 | #ifndef __EMSCRIPTEN__
70 | switch (glfwGetPlatform()) {
71 | #else
72 | // glfwGetPlatform is not available in older versions of emscripten
73 | switch (GLFW_PLATFORM_EMSCRIPTEN) {
74 | #endif
75 |
76 | #ifdef GLFW_EXPOSE_NATIVE_X11
77 | case GLFW_PLATFORM_X11: {
78 | Display* x11_display = glfwGetX11Display();
79 | Window x11_window = glfwGetX11Window(window);
80 |
81 | WGPUSurfaceSourceXlibWindow fromXlibWindow;
82 | fromXlibWindow.chain.sType = WGPUSType_SurfaceSourceXlibWindow;
83 | fromXlibWindow.chain.next = NULL;
84 | fromXlibWindow.display = x11_display;
85 | fromXlibWindow.window = x11_window;
86 |
87 | WGPUSurfaceDescriptor surfaceDescriptor;
88 | surfaceDescriptor.nextInChain = &fromXlibWindow.chain;
89 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
90 |
91 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
92 | }
93 | #endif // GLFW_EXPOSE_NATIVE_X11
94 |
95 | #ifdef GLFW_EXPOSE_NATIVE_WAYLAND
96 | case GLFW_PLATFORM_WAYLAND: {
97 | struct wl_display* wayland_display = glfwGetWaylandDisplay();
98 | struct wl_surface* wayland_surface = glfwGetWaylandWindow(window);
99 |
100 | WGPUSurfaceSourceWaylandSurface fromWaylandSurface;
101 | fromWaylandSurface.chain.sType = WGPUSType_SurfaceSourceWaylandSurface;
102 | fromWaylandSurface.chain.next = NULL;
103 | fromWaylandSurface.display = wayland_display;
104 | fromWaylandSurface.surface = wayland_surface;
105 |
106 | WGPUSurfaceDescriptor surfaceDescriptor;
107 | surfaceDescriptor.nextInChain = &fromWaylandSurface.chain;
108 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
109 |
110 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
111 | }
112 | #endif // GLFW_EXPOSE_NATIVE_WAYLAND
113 |
114 | #ifdef GLFW_EXPOSE_NATIVE_COCOA
115 | case GLFW_PLATFORM_COCOA: {
116 | id metal_layer = [CAMetalLayer layer];
117 | NSWindow* ns_window = glfwGetCocoaWindow(window);
118 | [ns_window.contentView setWantsLayer : YES] ;
119 | [ns_window.contentView setLayer : metal_layer] ;
120 |
121 | WGPUSurfaceSourceMetalLayer fromMetalLayer;
122 | fromMetalLayer.chain.sType = WGPUSType_SurfaceSourceMetalLayer;
123 | fromMetalLayer.chain.next = NULL;
124 | fromMetalLayer.layer = metal_layer;
125 |
126 | WGPUSurfaceDescriptor surfaceDescriptor;
127 | surfaceDescriptor.nextInChain = &fromMetalLayer.chain;
128 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
129 |
130 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
131 | }
132 | #endif // GLFW_EXPOSE_NATIVE_COCOA
133 |
134 | #ifdef GLFW_EXPOSE_NATIVE_WIN32
135 | case GLFW_PLATFORM_WIN32: {
136 | HWND hwnd = glfwGetWin32Window(window);
137 | HINSTANCE hinstance = GetModuleHandle(NULL);
138 |
139 | WGPUSurfaceSourceWindowsHWND fromWindowsHWND;
140 | fromWindowsHWND.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
141 | fromWindowsHWND.chain.next = NULL;
142 | fromWindowsHWND.hinstance = hinstance;
143 | fromWindowsHWND.hwnd = hwnd;
144 |
145 | WGPUSurfaceDescriptor surfaceDescriptor;
146 | surfaceDescriptor.nextInChain = &fromWindowsHWND.chain;
147 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
148 |
149 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
150 | }
151 | #endif // GLFW_EXPOSE_NATIVE_WIN32
152 |
153 | #ifdef GLFW_EXPOSE_NATIVE_EMSCRIPTEN
154 | case GLFW_PLATFORM_EMSCRIPTEN: {
155 | # ifdef WEBGPU_BACKEND_EMDAWNWEBGPU
156 | WGPUEmscriptenSurfaceSourceCanvasHTMLSelector fromCanvasHTMLSelector;
157 | fromCanvasHTMLSelector.chain.sType = WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector;
158 | fromCanvasHTMLSelector.selector = (WGPUStringView){ "canvas", WGPU_STRLEN };
159 | # else
160 | WGPUSurfaceDescriptorFromCanvasHTMLSelector fromCanvasHTMLSelector;
161 | fromCanvasHTMLSelector.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
162 | fromCanvasHTMLSelector.selector = "canvas";
163 | # endif
164 | fromCanvasHTMLSelector.chain.next = NULL;
165 |
166 | WGPUSurfaceDescriptor surfaceDescriptor;
167 | surfaceDescriptor.nextInChain = &fromCanvasHTMLSelector.chain;
168 | # ifdef WEBGPU_BACKEND_EMDAWNWEBGPU
169 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
170 | # else
171 | surfaceDescriptor.label = NULL;
172 | # endif
173 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
174 | }
175 | #endif // GLFW_EXPOSE_NATIVE_EMSCRIPTEN
176 |
177 | default:
178 | // Unsupported platform
179 | return NULL;
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/glfw3webgpu.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This is an extension of GLFW for WebGPU, abstracting away the details of
3 | * OS-specific operations.
4 | *
5 | * This file is part of the "Learn WebGPU for C++" book.
6 | * https://eliemichel.github.io/LearnWebGPU
7 | *
8 | * MIT License
9 | * Copyright (c) 2022-2024 Elie Michel and the wgpu-native authors
10 | *
11 | * Permission is hereby granted, free of charge, to any person obtaining a copy
12 | * of this software and associated documentation files (the "Software"), to deal
13 | * in the Software without restriction, including without limitation the rights
14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | * copies of the Software, and to permit persons to whom the Software is
16 | * furnished to do so, subject to the following conditions:
17 | *
18 | * The above copyright notice and this permission notice shall be included in all
19 | * copies or substantial portions of the Software.
20 | *
21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 | * SOFTWARE.
28 | */
29 |
30 | #ifndef _glfw3_webgpu_h_
31 | #define _glfw3_webgpu_h_
32 |
33 | #include
34 | #include
35 |
36 | #ifdef __cplusplus
37 | extern "C" {
38 | #endif
39 |
40 | /*! @brief Creates a WebGPU surface for the specified window.
41 | *
42 | * This function creates a WGPUSurface object for the specified window.
43 | *
44 | * If the surface cannot be created, this function returns `NULL`.
45 | *
46 | * It is the responsibility of the caller to destroy the window surface. The
47 | * window surface must be destroyed using `wgpuSurfaceRelease`.
48 | *
49 | * @param[in] instance The WebGPU instance to create the surface in.
50 | * @param[in] window The window to create the surface for.
51 | * @return The handle of the surface. This is set to `NULL` if an error
52 | * occurred.
53 | *
54 | * @ingroup webgpu
55 | */
56 | WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* window);
57 |
58 | #ifdef __cplusplus
59 | }
60 | #endif
61 |
62 | #endif // _glfw3_webgpu_h_
63 |
--------------------------------------------------------------------------------