Initial commit.
This commit is contained in:
commit
cb0391ce80
56 changed files with 3485 additions and 0 deletions
1
Client/glfw3webgpu/.gitignore
vendored
Normal file
1
Client/glfw3webgpu/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
releases/
|
||||
15
Client/glfw3webgpu/CMakeLists.txt
Normal file
15
Client/glfw3webgpu/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# This is only meant to be included as a subdirectory in another project.
|
||||
# It assumes that targets 'glfw' and 'webgpu' exist.
|
||||
# Look at examples/CMakeLists.txt to see how to use it in a project.
|
||||
|
||||
# The glfw3webgpu target
|
||||
add_library(glfw3webgpu STATIC glfw3webgpu.c)
|
||||
target_include_directories(glfw3webgpu PUBLIC .)
|
||||
target_link_libraries(glfw3webgpu PUBLIC glfw webgpu)
|
||||
|
||||
# Copy compile definitions that are PRIVATE in glfw
|
||||
if (GLFW_BUILD_COCOA)
|
||||
target_compile_definitions(glfw3webgpu PRIVATE _GLFW_COCOA)
|
||||
target_compile_options(glfw3webgpu PRIVATE -x objective-c)
|
||||
target_link_libraries(glfw3webgpu PRIVATE "-framework Cocoa" "-framework CoreVideo" "-framework IOKit" "-framework QuartzCore")
|
||||
endif()
|
||||
20
Client/glfw3webgpu/LICENSE.txt
Normal file
20
Client/glfw3webgpu/LICENSE.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
MIT License
|
||||
Copyright (c) 2022-2024 Élie Michel and the wgpu-native authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
94
Client/glfw3webgpu/README.md
Normal file
94
Client/glfw3webgpu/README.md
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
<img src="https://github.com/eliemichel/glfw3webgpu/actions/workflows/cmake.yml/badge.svg" alt="CMake Badge" />
|
||||
|
||||
<div align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/eliemichel/LearnWebGPU/main/images/webgpu-dark.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/eliemichel/LearnWebGPU/main/images/webgpu-light.svg">
|
||||
<img alt="Learn WebGPU Logo" src="images/webgpu-dark.svg" width="200">
|
||||
</picture>
|
||||
|
||||
<a href="https://github.com/eliemichel/LearnWebGPU">LearnWebGPU</a> | <a href="https://github.com/eliemichel/WebGPU-Cpp">WebGPU-C++</a> | <a href="https://github.com/eliemichel/WebGPU-distribution">WebGPU-distribution</a><br/>
|
||||
<a href="https://github.com/eliemichel/glfw3webgpu">glfw3webgpu</a> | <a href="https://github.com/eliemichel/sdl2webgpu">sdl2webgpu</a> | <a href="https://github.com/eliemichel/sdl3webgpu">sdl3webgpu</a>
|
||||
|
||||
<a href="https://discord.gg/2Tar4Kt564"><img src="https://img.shields.io/static/v1?label=Discord&message=Join%20us!&color=blue&logo=discord&logoColor=white" alt="Discord | Join us!"/></a>
|
||||
</div>
|
||||
|
||||
|
||||
GLFW WebGPU Extension
|
||||
=====================
|
||||
|
||||
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.
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Usage](#usage)
|
||||
- [Example](#example)
|
||||
- [License](#license)
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
This extension simply provides the following function:
|
||||
|
||||
```C
|
||||
WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* window);
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
**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.
|
||||
|
||||
Your project must link to an implementation of WebGPU (providing `webgpu.h`) and of course to GLFW. Then:
|
||||
|
||||
**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)).
|
||||
|
||||
**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`.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
Thanks to this extension it is possible to simply write a fully cross-platform WebGPU hello world:
|
||||
|
||||
```C
|
||||
#include "glfw3webgpu.h"
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <webgpu/webgpu.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// Init WebGPU
|
||||
WGPUInstanceDescriptor desc;
|
||||
desc.nextInChain = NULL;
|
||||
WGPUInstance instance = wgpuCreateInstance(&desc);
|
||||
|
||||
// Init GLFW
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* window = glfwCreateWindow(640, 480, "Learn WebGPU", NULL, NULL);
|
||||
|
||||
// Here we create our WebGPU surface from the window!
|
||||
WGPUSurface surface = glfwCreateWindowWGPUSurface(instance, window);
|
||||
printf("surface = %p", surface);
|
||||
|
||||
// Terminate GLFW
|
||||
while (!glfwWindowShouldClose(window)) glfwPollEvents();
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**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).
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
See [LICENSE.txt](LICENSE.txt).
|
||||
191
Client/glfw3webgpu/glfw3webgpu.c
Normal file
191
Client/glfw3webgpu/glfw3webgpu.c
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/**
|
||||
* This is an extension of GLFW for WebGPU, abstracting away the details of
|
||||
* OS-specific operations.
|
||||
*
|
||||
* This file is part of the "Learn WebGPU for C++" book.
|
||||
* https://eliemichel.github.io/LearnWebGPU
|
||||
*
|
||||
* Most of this code comes from the wgpu-native triangle example:
|
||||
* https://github.com/gfx-rs/wgpu-native/blob/master/examples/triangle/main.c
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) 2022-2025 Elie Michel and the wgpu-native authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "glfw3webgpu.h"
|
||||
|
||||
#include <webgpu/webgpu.h>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
// Begin hack
|
||||
#if defined(__APPLE__)
|
||||
#define _GLFW_COCOA
|
||||
#elif defined(_WIN32)
|
||||
#define _GLFW_WIN32
|
||||
#elif defined(__linux__)
|
||||
#define _GLFW_X11 // or _GLFW_WAYLAND if you built GLFW with Wayland
|
||||
#endif
|
||||
// End hack
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
# define GLFW_EXPOSE_NATIVE_EMSCRIPTEN
|
||||
# ifndef GLFW_PLATFORM_EMSCRIPTEN // not defined in older versions of emscripten
|
||||
# define GLFW_PLATFORM_EMSCRIPTEN 0
|
||||
# endif
|
||||
#else // __EMSCRIPTEN__
|
||||
# ifdef _GLFW_X11
|
||||
# define GLFW_EXPOSE_NATIVE_X11
|
||||
# endif
|
||||
# ifdef _GLFW_WAYLAND
|
||||
# define GLFW_EXPOSE_NATIVE_WAYLAND
|
||||
# endif
|
||||
# ifdef _GLFW_COCOA
|
||||
# define GLFW_EXPOSE_NATIVE_COCOA
|
||||
# endif
|
||||
# ifdef _GLFW_WIN32
|
||||
# define GLFW_EXPOSE_NATIVE_WIN32
|
||||
# endif
|
||||
#endif // __EMSCRIPTEN__
|
||||
|
||||
#ifdef GLFW_EXPOSE_NATIVE_COCOA
|
||||
# include <Foundation/Foundation.h>
|
||||
# include <QuartzCore/CAMetalLayer.h>
|
||||
#endif
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
# include <GLFW/glfw3native.h>
|
||||
#endif
|
||||
|
||||
WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* window) {
|
||||
#ifndef __EMSCRIPTEN__
|
||||
switch (glfwGetPlatform()) {
|
||||
#else
|
||||
// glfwGetPlatform is not available in older versions of emscripten
|
||||
switch (GLFW_PLATFORM_EMSCRIPTEN) {
|
||||
#endif
|
||||
|
||||
#ifdef GLFW_EXPOSE_NATIVE_X11
|
||||
case GLFW_PLATFORM_X11: {
|
||||
Display* x11_display = glfwGetX11Display();
|
||||
Window x11_window = glfwGetX11Window(window);
|
||||
|
||||
WGPUSurfaceSourceXlibWindow fromXlibWindow;
|
||||
fromXlibWindow.chain.sType = WGPUSType_SurfaceSourceXlibWindow;
|
||||
fromXlibWindow.chain.next = NULL;
|
||||
fromXlibWindow.display = x11_display;
|
||||
fromXlibWindow.window = x11_window;
|
||||
|
||||
WGPUSurfaceDescriptor surfaceDescriptor;
|
||||
surfaceDescriptor.nextInChain = &fromXlibWindow.chain;
|
||||
surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
|
||||
|
||||
return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||
}
|
||||
#endif // GLFW_EXPOSE_NATIVE_X11
|
||||
|
||||
#ifdef GLFW_EXPOSE_NATIVE_WAYLAND
|
||||
case GLFW_PLATFORM_WAYLAND: {
|
||||
struct wl_display* wayland_display = glfwGetWaylandDisplay();
|
||||
struct wl_surface* wayland_surface = glfwGetWaylandWindow(window);
|
||||
|
||||
WGPUSurfaceSourceWaylandSurface fromWaylandSurface;
|
||||
fromWaylandSurface.chain.sType = WGPUSType_SurfaceSourceWaylandSurface;
|
||||
fromWaylandSurface.chain.next = NULL;
|
||||
fromWaylandSurface.display = wayland_display;
|
||||
fromWaylandSurface.surface = wayland_surface;
|
||||
|
||||
WGPUSurfaceDescriptor surfaceDescriptor;
|
||||
surfaceDescriptor.nextInChain = &fromWaylandSurface.chain;
|
||||
surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
|
||||
|
||||
return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||
}
|
||||
#endif // GLFW_EXPOSE_NATIVE_WAYLAND
|
||||
|
||||
#ifdef GLFW_EXPOSE_NATIVE_COCOA
|
||||
case GLFW_PLATFORM_COCOA: {
|
||||
id metal_layer = [CAMetalLayer layer];
|
||||
NSWindow* ns_window = glfwGetCocoaWindow(window);
|
||||
[ns_window.contentView setWantsLayer : YES] ;
|
||||
[ns_window.contentView setLayer : metal_layer] ;
|
||||
|
||||
WGPUSurfaceSourceMetalLayer fromMetalLayer;
|
||||
fromMetalLayer.chain.sType = WGPUSType_SurfaceSourceMetalLayer;
|
||||
fromMetalLayer.chain.next = NULL;
|
||||
fromMetalLayer.layer = (__bridge void *)(metal_layer);
|
||||
|
||||
WGPUSurfaceDescriptor surfaceDescriptor;
|
||||
surfaceDescriptor.nextInChain = &fromMetalLayer.chain;
|
||||
surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
|
||||
|
||||
return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||
}
|
||||
#endif // GLFW_EXPOSE_NATIVE_COCOA
|
||||
|
||||
#ifdef GLFW_EXPOSE_NATIVE_WIN32
|
||||
case GLFW_PLATFORM_WIN32: {
|
||||
HWND hwnd = glfwGetWin32Window(window);
|
||||
HINSTANCE hinstance = GetModuleHandle(NULL);
|
||||
|
||||
WGPUSurfaceSourceWindowsHWND fromWindowsHWND;
|
||||
fromWindowsHWND.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
|
||||
fromWindowsHWND.chain.next = NULL;
|
||||
fromWindowsHWND.hinstance = hinstance;
|
||||
fromWindowsHWND.hwnd = hwnd;
|
||||
|
||||
WGPUSurfaceDescriptor surfaceDescriptor;
|
||||
surfaceDescriptor.nextInChain = &fromWindowsHWND.chain;
|
||||
surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
|
||||
|
||||
return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||
}
|
||||
#endif // GLFW_EXPOSE_NATIVE_WIN32
|
||||
|
||||
#ifdef GLFW_EXPOSE_NATIVE_EMSCRIPTEN
|
||||
case GLFW_PLATFORM_EMSCRIPTEN: {
|
||||
# ifdef WEBGPU_BACKEND_EMDAWNWEBGPU
|
||||
WGPUEmscriptenSurfaceSourceCanvasHTMLSelector fromCanvasHTMLSelector;
|
||||
fromCanvasHTMLSelector.chain.sType = WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector;
|
||||
fromCanvasHTMLSelector.selector = (WGPUStringView){ "canvas", WGPU_STRLEN };
|
||||
# else
|
||||
WGPUSurfaceDescriptorFromCanvasHTMLSelector fromCanvasHTMLSelector;
|
||||
fromCanvasHTMLSelector.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
|
||||
fromCanvasHTMLSelector.selector = "canvas";
|
||||
# endif
|
||||
fromCanvasHTMLSelector.chain.next = NULL;
|
||||
|
||||
WGPUSurfaceDescriptor surfaceDescriptor;
|
||||
surfaceDescriptor.nextInChain = &fromCanvasHTMLSelector.chain;
|
||||
# ifdef WEBGPU_BACKEND_EMDAWNWEBGPU
|
||||
surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN };
|
||||
# else
|
||||
surfaceDescriptor.label = NULL;
|
||||
# endif
|
||||
return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
|
||||
}
|
||||
#endif // GLFW_EXPOSE_NATIVE_EMSCRIPTEN
|
||||
|
||||
default:
|
||||
// Unsupported platform
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
62
Client/glfw3webgpu/glfw3webgpu.h
Normal file
62
Client/glfw3webgpu/glfw3webgpu.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* This is an extension of GLFW for WebGPU, abstracting away the details of
|
||||
* OS-specific operations.
|
||||
*
|
||||
* This file is part of the "Learn WebGPU for C++" book.
|
||||
* https://eliemichel.github.io/LearnWebGPU
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) 2022-2024 Elie Michel and the wgpu-native authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _glfw3_webgpu_h_
|
||||
#define _glfw3_webgpu_h_
|
||||
|
||||
#include <webgpu/webgpu.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! @brief Creates a WebGPU surface for the specified window.
|
||||
*
|
||||
* This function creates a WGPUSurface object for the specified window.
|
||||
*
|
||||
* If the surface cannot be created, this function returns `NULL`.
|
||||
*
|
||||
* It is the responsibility of the caller to destroy the window surface. The
|
||||
* window surface must be destroyed using `wgpuSurfaceRelease`.
|
||||
*
|
||||
* @param[in] instance The WebGPU instance to create the surface in.
|
||||
* @param[in] window The window to create the surface for.
|
||||
* @return The handle of the surface. This is set to `NULL` if an error
|
||||
* occurred.
|
||||
*
|
||||
* @ingroup webgpu
|
||||
*/
|
||||
WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* window);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _glfw3_webgpu_h_
|
||||
Loading…
Add table
Add a link
Reference in a new issue