1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
#include "platform.h"
#ifdef _WIN32
#define GLFW_EXPOSE_NATIVE_WIN32
#elif defined(__APPLE__)
#define GLFW_EXPOSE_NATIVE_COCOA
#else
#define GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_WAYLAND
#endif
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#ifdef __APPLE__
#import <QuartzCore/CAMetalLayer.h>
#import <AppKit/NSWindow.h>
#import <AppKit/NSView.h>
#endif
static GLFWwindow *window = nullptr;
static int windowed_x, windowed_y, windowed_w, windowed_h;
static bool g_is_fullscreen = false;
static void glfw_key_callback(GLFWwindow *cb_window, int key, int scancode,
int action, int mods) {
if (action == GLFW_PRESS) {
if (key == GLFW_KEY_ESCAPE) {
glfwSetWindowShouldClose(cb_window, GLFW_TRUE);
} else if (key == GLFW_KEY_F) {
platform_toggle_fullscreen();
}
}
}
void platform_init_window(bool fullscreen) {
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
window = glfwCreateWindow(1280, 720, "demo64k", nullptr, nullptr);
glfwSetKeyCallback(window, glfw_key_callback);
g_is_fullscreen = fullscreen;
if (fullscreen) {
// Save current windowed mode dimensions before going fullscreen
glfwGetWindowPos(window, &windowed_x, &windowed_y);
glfwGetWindowSize(window, &windowed_w, &windowed_h);
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height,
mode->refreshRate);
}
}
void platform_shutdown() {
glfwDestroyWindow(window);
glfwTerminate();
}
void platform_poll() { glfwPollEvents(); }
bool platform_should_close() { return glfwWindowShouldClose(window); }
void platform_toggle_fullscreen() {
g_is_fullscreen = !g_is_fullscreen;
if (g_is_fullscreen) {
glfwGetWindowPos(window, &windowed_x, &windowed_y);
glfwGetWindowSize(window, &windowed_w, &windowed_h);
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height,
mode->refreshRate);
} else {
glfwSetWindowMonitor(window, nullptr, windowed_x, windowed_y, windowed_w,
windowed_h, 0);
}
}
GLFWwindow *platform_get_window() { return window; }
double platform_get_time() { return glfwGetTime(); }
WGPUSurface platform_create_wgpu_surface(WGPUInstance instance) {
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
id metal_layer = NULL;
NSWindow *ns_window = glfwGetCocoaWindow(window);
[ns_window.contentView setWantsLayer:YES];
metal_layer = [CAMetalLayer layer];
[ns_window.contentView setLayer:metal_layer];
WGPUSurfaceSourceMetalLayer metal_src = {};
metal_src.chain.sType = WGPUSType_SurfaceSourceMetalLayer;
metal_src.layer = metal_layer;
WGPUSurfaceDescriptor surface_desc = {};
surface_desc.nextInChain = (const WGPUChainedStruct *)&metal_src;
return wgpuInstanceCreateSurface(instance, &surface_desc);
#elif defined(GLFW_EXPOSE_NATIVE_WIN32)
HWND hwnd = glfwGetWin32Window(window);
HINSTANCE hinstance = GetModuleHandle(NULL);
WGPUSurfaceSourceWindowsHWND win_src = {};
win_src.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
win_src.hinstance = hinstance;
win_src.hwnd = hwnd;
WGPUSurfaceDescriptor surface_desc = {};
surface_desc.nextInChain = (const WGPUChainedStruct *)&win_src;
return wgpuInstanceCreateSurface(instance, &surface_desc);
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_WAYLAND)
if (glfwGetPlatform() == GLFW_PLATFORM_X11) {
Display *x11_display = glfwGetX11Display();
Window x11_window = glfwGetX11Window(window);
WGPUSurfaceSourceXlibWindow x11_src = {};
x11_src.chain.sType = WGPUSType_SurfaceSourceXlibWindow;
x11_src.display = x11_display;
x11_src.window = x11_window;
WGPUSurfaceDescriptor surface_desc = {};
surface_desc.nextInChain = (const WGPUChainedStruct *)&x11_src;
return wgpuInstanceCreateSurface(instance, &surface_desc);
} else if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) {
struct wl_display *wayland_display = glfwGetWaylandDisplay();
struct wl_surface *wayland_surface = glfwGetWaylandWindow(window);
WGPUSurfaceSourceWaylandSurface wl_src = {};
wl_src.chain.sType = WGPUSType_SurfaceSourceWaylandSurface;
wl_src.display = wayland_display;
wl_src.surface = wayland_surface;
WGPUSurfaceDescriptor surface_desc = {};
surface_desc.nextInChain = (const WGPUChainedStruct *)&wl_src;
return wgpuInstanceCreateSurface(instance, &surface_desc);
}
#endif
return nullptr;
}
|