Browse Source

Fix indentation and add full example

Emir 1 year ago
parent
commit
2a2bedc85c

+ 17 - 0
vendor/wgpu/examples/sdl2/Makefile

@@ -0,0 +1,17 @@
+FILES := $(wildcard *)
+
+# NOTE: changing this requires changing the same values in the `web/index.html`.
+INITIAL_MEMORY_PAGES := 2000
+MAX_MEMORY_PAGES     := 65536
+
+PAGE_SIZE := 65536
+INITIAL_MEMORY_BYTES := $(shell expr $(INITIAL_MEMORY_PAGES) \* $(PAGE_SIZE))
+MAX_MEMORY_BYTES     := $(shell expr $(MAX_MEMORY_PAGES) \* $(PAGE_SIZE))
+
+web/triangle.wasm: $(FILES) ../../wgpu.js ../../../wasm/js/runtime.js
+	odin build . \
+		-target:js_wasm32 -out:web/triangle.wasm -o:size \
+        -extra-linker-flags:"--export-table --import-memory --initial-memory=$(INITIAL_MEMORY_BYTES) --max-memory=$(MAX_MEMORY_BYTES)"
+
+	cp ../../wgpu.js web/wgpu.js
+	cp ../../../wasm/js/runtime.js web/runtime.js

+ 12 - 0
vendor/wgpu/examples/sdl2/build.bat

@@ -0,0 +1,12 @@
+REM NOTE: changing this requires changing the same values in the `web/index.html`.
+set INITIAL_MEMORY_PAGES=2000
+set MAX_MEMORY_PAGES=65536
+
+set PAGE_SIZE=65536
+set /a INITIAL_MEMORY_BYTES=%INITIAL_MEMORY_PAGES% * %PAGE_SIZE%
+set /a MAX_MEMORY_BYTES=%MAX_MEMORY_PAGES% * %PAGE_SIZE%
+
+call odin.exe build . -target:js_wasm32 -out:web/triangle.wasm -o:size -extra-linker-flags:"--export-table --import-memory --initial-memory=%INITIAL_MEMORY_BYTES% --max-memory=%MAX_MEMORY_BYTES%"
+
+copy "..\..\wgpu.js" "web\wgpu.js"
+copy "..\..\..\wasm\js\runtime.js" "web\runtime.js"

+ 11 - 52
vendor/wgpu/examples/sdl2/main.odin

@@ -4,13 +4,11 @@ import "base:runtime"
 
 
 import "core:fmt"
 import "core:fmt"
 
 
-import "vendor:sdl2"
 import "vendor:wgpu"
 import "vendor:wgpu"
-import "vendor:wgpu/sdl2glue"
 
 
 State :: struct {
 State :: struct {
 	ctx: runtime.Context,
 	ctx: runtime.Context,
-	window: ^sdl2.Window,
+	os:  OS,
 
 
 	instance:        wgpu.Instance,
 	instance:        wgpu.Instance,
 	surface:         wgpu.Surface,
 	surface:         wgpu.Surface,
@@ -29,32 +27,13 @@ state: State
 main :: proc() {
 main :: proc() {
 	state.ctx = context
 	state.ctx = context
 	
 	
-	sdl_flags := sdl2.InitFlags{.VIDEO, .JOYSTICK, .GAMECONTROLLER, .EVENTS}
-	if res := sdl2.Init(sdl_flags); res != 0 {
-		fmt.eprintf("ERROR: Failed to initialize SDL: [%s]\n", sdl2.GetError())
-		return
-	}
-	
-	window_flags: sdl2.WindowFlags = {.SHOWN, .ALLOW_HIGHDPI, .RESIZABLE}
-	state.window = sdl2.CreateWindow(
-		"wgpu triangle",
-		sdl2.WINDOWPOS_CENTERED,
-		sdl2.WINDOWPOS_CENTERED,
-		800,
-		600,
-		window_flags,
-	)
-	if state.window == nil {
-		fmt.eprintf("ERROR: Failed to create the SDL Window: [%s]\n", sdl2.GetError())
-		return
-	}
+	os_init(&state.os)
 
 
 	state.instance = wgpu.CreateInstance(nil)
 	state.instance = wgpu.CreateInstance(nil)
 	if state.instance == nil {
 	if state.instance == nil {
 		panic("WebGPU is not supported")
 		panic("WebGPU is not supported")
 	}
 	}
-	
-	state.surface = sdl2glue.GetSurface(state.instance, state.window)
+	state.surface = os_get_surface(&state.os, state.instance)
 
 
 	wgpu.InstanceRequestAdapter(state.instance, &{ compatibleSurface = state.surface }, on_adapter, nil)
 	wgpu.InstanceRequestAdapter(state.instance, &{ compatibleSurface = state.surface }, on_adapter, nil)
 
 
@@ -135,35 +114,15 @@ main :: proc() {
 			},
 			},
 		})
 		})
 
 
-		now := sdl2.GetPerformanceCounter()
-		last : u64 = 0
-		dt: f32 = 0
- 		main_loop: for {
-			last = now
-			now := sdl2.GetPerformanceCounter()
-			dt = auto_cast((now - last)*1000 / sdl2.GetPerformanceFrequency())
+		os_run(&state.os)
+	}
+}
 
 
-			e: sdl2.Event
-	
-			for sdl2.PollEvent(&e) {
-				#partial switch (e.type) {
-				case .QUIT:
-					break main_loop
+resize :: proc "c" () {
+	context = state.ctx
 	
 	
-				case .WINDOWEVENT:
-					#partial switch (e.window.event) {
-					case .SIZE_CHANGED:
-					case .RESIZED:
-						state.config.width = cast(u32)e.window.data1
-						state.config.height = cast(u32)e.window.data2
-						wgpu.SurfaceConfigure(state.surface, &state.config)
-					}
-				}
-			}
-
-			frame(dt)
-		}
-	}
+	state.config.width, state.config.height = os_get_render_bounds(&state.os)
+	wgpu.SurfaceConfigure(state.surface, &state.config)
 }
 }
 
 
 frame :: proc "c" (dt: f32) {
 frame :: proc "c" (dt: f32) {
@@ -178,7 +137,7 @@ frame :: proc "c" (dt: f32) {
 		if surface_texture.texture != nil {
 		if surface_texture.texture != nil {
 			wgpu.TextureRelease(surface_texture.texture)
 			wgpu.TextureRelease(surface_texture.texture)
 		}
 		}
-		// todo - resize()
+		resize()
 		return
 		return
 	case .OutOfMemory, .DeviceLost:
 	case .OutOfMemory, .DeviceLost:
 		// Fatal error
 		// Fatal error

+ 60 - 0
vendor/wgpu/examples/sdl2/os_js.odin

@@ -0,0 +1,60 @@
+package vendor_wgpu_example_triangle
+
+import "vendor:wgpu"
+import "vendor:wasm/js"
+
+OS :: struct {
+	initialized: bool,
+}
+
+@(private="file")
+g_os: ^OS
+
+os_init :: proc(os: ^OS) {
+	g_os = os
+	assert(js.add_window_event_listener(.Resize, nil, size_callback))
+}
+
+// NOTE: frame loop is done by the runtime.js repeatedly calling `step`.
+os_run :: proc(os: ^OS) {
+	os.initialized = true
+}
+
+os_get_render_bounds :: proc(os: ^OS) -> (width, height: u32) {
+	rect := js.get_bounding_client_rect("body")
+	return u32(rect.width), u32(rect.height)
+}
+
+os_get_surface :: proc(os: ^OS, instance: wgpu.Instance) -> wgpu.Surface {
+	return wgpu.InstanceCreateSurface(
+		instance,
+		&wgpu.SurfaceDescriptor{
+			nextInChain = &wgpu.SurfaceDescriptorFromCanvasHTMLSelector{
+				sType = .SurfaceDescriptorFromCanvasHTMLSelector,
+				selector = "#wgpu-canvas",
+			},
+		},
+	)
+}
+
+@(private="file", export)
+step :: proc(dt: f32) -> bool {
+	if !g_os.initialized {
+		return true
+	}
+
+	frame(dt)
+	return true
+}
+
+@(private="file", fini)
+os_fini :: proc() {
+	js.remove_window_event_listener(.Resize, nil, size_callback)
+
+	finish()
+}
+
+@(private="file")
+size_callback :: proc(e: js.Event) {
+	resize()
+}

+ 87 - 0
vendor/wgpu/examples/sdl2/os_sdl2.odin

@@ -0,0 +1,87 @@
+//+build !js
+package vendor_wgpu_example_triangle
+
+import "core:c"
+import "core:fmt"
+
+import "vendor:sdl2"
+import "vendor:wgpu"
+import "vendor:wgpu/sdl2glue"
+
+OS :: struct {
+	window: ^sdl2.Window,
+}
+
+os_init :: proc(os: ^OS) {
+	sdl_flags := sdl2.InitFlags{.VIDEO, .JOYSTICK, .GAMECONTROLLER, .EVENTS}
+	if res := sdl2.Init(sdl_flags); res != 0 {
+		fmt.eprintfln("ERROR: Failed to initialize SDL: [%s]", sdl2.GetError())
+		return
+	}
+	
+	window_flags: sdl2.WindowFlags = {.SHOWN, .ALLOW_HIGHDPI, .RESIZABLE}
+	os.window = sdl2.CreateWindow(
+		"wgpu triangle",
+		sdl2.WINDOWPOS_CENTERED,
+		sdl2.WINDOWPOS_CENTERED,
+		800,
+		600,
+		window_flags,
+	)
+	if os.window == nil {
+		fmt.eprintfln("ERROR: Failed to create the SDL Window: [%s]", sdl2.GetError())
+		return
+	}
+
+	sdl2.AddEventWatch(size_callback, nil)
+}
+
+os_run :: proc(os: ^OS) {
+	now := sdl2.GetPerformanceCounter()
+	last : u64
+	dt: f32
+	main_loop: for {
+		last = now
+		now = sdl2.GetPerformanceCounter()
+		dt = f32((now - last) * 1000) / f32(sdl2.GetPerformanceFrequency())
+
+		e: sdl2.Event
+
+		for sdl2.PollEvent(&e) {
+			#partial switch (e.type) {
+			case .QUIT:
+				break main_loop
+			}
+		}
+
+		frame(dt)
+	}
+
+	sdl2.DestroyWindow(os.window)
+	sdl2.Quit()
+
+	finish()
+}
+
+
+os_get_render_bounds :: proc(os: ^OS) -> (width, height: u32) {
+	iw, ih: c.int
+	sdl2.GetWindowSize(os.window, &iw, &ih)
+	return u32(iw), u32(ih)
+}
+
+os_get_surface :: proc(os: ^OS, instance: wgpu.Instance) -> wgpu.Surface {
+	return sdl2glue.GetSurface(instance, os.window)
+}
+
+@(private="file")
+size_callback :: proc "c" (userdata: rawptr, event: ^sdl2.Event) -> c.int {
+	
+	if event.type == .WINDOWEVENT {
+		if event.window.event == .SIZE_CHANGED || event.window.event == .RESIZED {
+			resize()
+		}
+	}
+
+	return 0
+}

+ 23 - 0
vendor/wgpu/examples/sdl2/web/index.html

@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html lang="en" style="height: 100%;">
+	<head>
+		<meta charset="UTF-8">
+		<meta name="viewport" content="width=device-width, initial-scale=1">
+		<title>WGPU WASM Triangle</title>
+	</head>
+	<body id="body" style="height: 100%; padding: 0; margin: 0; overflow: hidden;">
+		<canvas id="wgpu-canvas"></canvas>
+	
+		<script type="text/javascript" src="runtime.js"></script>
+		<script type="text/javascript" src="wgpu.js"></script>
+		<script type="text/javascript">
+			const mem = new WebAssembly.Memory({ initial: 2000, maximum: 65536, shared: false });
+			const memInterface = new odin.WasmMemoryInterface();
+			memInterface.setMemory(mem);
+
+			const wgpuInterface = new odin.WebGPUInterface(memInterface);
+
+			odin.runWasm("triangle.wasm", null, { wgpu: wgpuInterface.getInterface() }, memInterface, /*intSize=8*/);
+		</script>
+	</body>
+</html>

+ 9 - 9
vendor/wgpu/sdl2glue/glue_darwin.odin

@@ -6,14 +6,14 @@ import CA "vendor:darwin/QuartzCore"
 import NS "core:sys/darwin/Foundation"
 import NS "core:sys/darwin/Foundation"
 
 
 GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surface {
 GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surface {
-    window_info: sdl2.SysWMinfo 
-    sdl2.GetWindowWMInfo(window, &window_info)
-    ns_window := cast(^NS.Window)window_info.info.cocoa.window
-    metal_layer := CA.MetalLayer_layer()
-    ns_window->contentView()->setLayer(metal_layer)
-    return wgpu.InstanceCreateSurface(
-        instance,
-        &wgpu.SurfaceDescriptor{
+	window_info: sdl2.SysWMinfo 
+	sdl2.GetWindowWMInfo(window, &window_info)
+	ns_window := cast(^NS.Window)window_info.info.cocoa.window
+	metal_layer := CA.MetalLayer_layer()
+	ns_window->contentView()->setLayer(metal_layer)
+	return wgpu.InstanceCreateSurface(
+		instance,
+		&wgpu.SurfaceDescriptor{
 			nextInChain = &wgpu.SurfaceDescriptorFromMetalLayer{
 			nextInChain = &wgpu.SurfaceDescriptorFromMetalLayer{
 				chain = wgpu.ChainedStruct{
 				chain = wgpu.ChainedStruct{
 					sType = .SurfaceDescriptorFromMetalLayer,
 					sType = .SurfaceDescriptorFromMetalLayer,
@@ -21,5 +21,5 @@ GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surfac
 				layer = rawptr(metal_layer),
 				layer = rawptr(metal_layer),
 			},
 			},
 		},
 		},
-    )
+	)
 }
 }

+ 33 - 33
vendor/wgpu/sdl2glue/glue_linux.odin

@@ -4,39 +4,39 @@ import "vendor:sdl2"
 import "vendor:wgpu"
 import "vendor:wgpu"
 
 
 GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surface {
 GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surface {
-    window_info: sdl2.SysWMinfo 
-    sdl2.GetWindowWMInfo(window, &window_info)
+	window_info: sdl2.SysWMinfo 
+	sdl2.GetWindowWMInfo(window, &window_info)
 	if window_info.subsystem == .WAYLAND {
 	if window_info.subsystem == .WAYLAND {
-        display := window_info.info.wl.display
-        surface := window_info.info.wl.surface
-        return wgpu.InstanceCreateSurface(
-            instance,
-            &wgpu.SurfaceDescriptor{
-                nextInChain = &wgpu.SurfaceDescriptorFromWaylandSurface{
-                    chain = {
-                        sType = .SurfaceDescriptorFromWaylandSurface,
-                    },
-                    display = display,
-                    surface = surface,
-                },
-            },
-        )
+		display := window_info.info.wl.display
+		surface := window_info.info.wl.surface
+		return wgpu.InstanceCreateSurface(
+			instance,
+			&wgpu.SurfaceDescriptor{
+				nextInChain = &wgpu.SurfaceDescriptorFromWaylandSurface{
+					chain = {
+						sType = .SurfaceDescriptorFromWaylandSurface,
+					},
+					display = display,
+					surface = surface,
+				},
+			},
+		)
 	} else if window_info.subsystem == .X11 {
 	} else if window_info.subsystem == .X11 {
-        display := window_info.info.x11.display
-        window  := window_info.info.x11.window
-        return wgpu.InstanceCreateSurface(
-            instance,
-            &wgpu.SurfaceDescriptor{
-                nextInChain = &wgpu.SurfaceDescriptorFromXlibWindow{
-                    chain = {
-                        sType = .SurfaceDescriptorFromXlibWindow,
-                    },
-                    display = display,
-                    window  = u64(window),
-                },
-            },
-        )
-    } else {
-        panic("wgpu sdl2 glue: unsupported platform, expected Wayland or X11")
-    }
+		display := window_info.info.x11.display
+		window  := window_info.info.x11.window
+		return wgpu.InstanceCreateSurface(
+			instance,
+			&wgpu.SurfaceDescriptor{
+				nextInChain = &wgpu.SurfaceDescriptorFromXlibWindow{
+					chain = {
+						sType = .SurfaceDescriptorFromXlibWindow,
+					},
+					display = display,
+					window  = u64(window),
+				},
+			},
+		)
+	} else {
+		panic("wgpu sdl2 glue: unsupported platform, expected Wayland or X11")
+	}
 }
 }

+ 13 - 13
vendor/wgpu/sdl2glue/glue_windows.odin

@@ -2,24 +2,24 @@ package wgpu_sdl2_glue
 
 
 import win "core:sys/windows"
 import win "core:sys/windows"
 
 
-import     "vendor:sdl2"
-import     "vendor:wgpu"
+import  "vendor:sdl2"
+import  "vendor:wgpu"
 
 
 GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surface {
 GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surface {
-    window_info: sdl2.SysWMinfo 
-    sdl2.GetWindowWMInfo(window, &window_info)
-    hwnd := cast(win.HWND)window_info.info.win.window
-    hinstance := win.GetModuleHandleW(nil)
-    return wgpu.InstanceCreateSurface(
-        instance,
-        &wgpu.SurfaceDescriptor{
-			nextInChain = &wgpu.SurfaceDescriptorFromMetalLayer{
+	window_info: sdl2.SysWMinfo 
+	sdl2.GetWindowWMInfo(window, &window_info)
+	hwnd := window_info.info.win.window
+	hinstance := win.GetModuleHandleW(nil)
+	return wgpu.InstanceCreateSurface(
+		instance,
+		&wgpu.SurfaceDescriptor{
+			nextInChain = &wgpu.SurfaceDescriptorFromWindowsHWND{
 				chain = wgpu.ChainedStruct{
 				chain = wgpu.ChainedStruct{
-					sType = .SurfaceDescriptorFromMetalLayer,
+					sType = .SurfaceDescriptorFromWindowsHWND,
 				},
 				},
 				hinstance = rawptr(hinstance),
 				hinstance = rawptr(hinstance),
 				hwnd = rawptr(hwnd),
 				hwnd = rawptr(hwnd),
 			},
 			},
 		},
 		},
-    )
-}
+	)
+}