-
-
Notifications
You must be signed in to change notification settings - Fork 50
Canvas/context inversion of control #764
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
0c37057
dd9ea18
e9db27c
8bd6c82
ee03c1f
95e88b0
301249e
19e3474
10dfd32
00caada
63b4ef7
6d6e0d8
a2746b6
f1447e2
d495ab3
8276a6d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,7 +13,7 @@ | |
| import atexit | ||
|
|
||
| import glfw | ||
| from wgpu.backends.wgpu_native import GPUCanvasContext | ||
| import wgpu | ||
|
|
||
| # from triangle import setup_drawing_sync | ||
| from cube import setup_drawing_sync | ||
|
|
@@ -26,37 +26,33 @@ | |
| api_is_wayland = True | ||
|
|
||
|
|
||
| def get_glfw_present_methods(window): | ||
| def get_glfw_present_info(window): | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This specific function feels like we could have a module with a bunch of helpers like this for different backends. Let's leave it for now though.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That module is called
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. I think it's important for people to see how to get a winId in the examples locally here, without having to venture out to rendercanvas. It will put off low level coders, keen on building their own pygfx/rendercanvas libraries. |
||
| if sys.platform.startswith("win"): | ||
| return { | ||
| "screen": { | ||
| "platform": "windows", | ||
| "window": int(glfw.get_win32_window(window)), | ||
| } | ||
| "platform": "windows", | ||
| "window": int(glfw.get_win32_window(window)), | ||
| "vsync": True, | ||
| } | ||
| elif sys.platform.startswith("darwin"): | ||
| return { | ||
| "screen": { | ||
| "platform": "cocoa", | ||
| "window": int(glfw.get_cocoa_window(window)), | ||
| } | ||
| "platform": "cocoa", | ||
| "window": int(glfw.get_cocoa_window(window)), | ||
| "vsync": True, | ||
| } | ||
| elif sys.platform.startswith("linux"): | ||
| if api_is_wayland: | ||
| return { | ||
| "screen": { | ||
| "platform": "wayland", | ||
| "window": int(glfw.get_wayland_window(window)), | ||
| "display": int(glfw.get_wayland_display()), | ||
| } | ||
| "platform": "wayland", | ||
| "window": int(glfw.get_wayland_window(window)), | ||
| "display": int(glfw.get_wayland_display()), | ||
| "vsync": True, | ||
| } | ||
| else: | ||
| return { | ||
| "screen": { | ||
| "platform": "x11", | ||
| "window": int(glfw.get_x11_window(window)), | ||
| "display": int(glfw.get_x11_display()), | ||
| } | ||
| "platform": "x11", | ||
| "window": int(glfw.get_x11_window(window)), | ||
| "display": int(glfw.get_x11_display()), | ||
| "vsync": True, | ||
| } | ||
| else: | ||
| raise RuntimeError(f"Cannot get GLFW surface info on {sys.platform}.") | ||
|
|
@@ -66,43 +62,39 @@ def get_glfw_present_methods(window): | |
| glfw.init() | ||
| atexit.register(glfw.terminate) | ||
|
|
||
| # disable automatic API selection, we are not using opengl | ||
| glfw.window_hint(glfw.CLIENT_API, glfw.NO_API) | ||
| glfw.window_hint(glfw.RESIZABLE, True) | ||
|
|
||
| class MinimalGlfwCanvas: # implements WgpuCanvasInterface | ||
| """Minimal canvas interface required by wgpu.""" | ||
|
|
||
| def __init__(self, title): | ||
| # disable automatic API selection, we are not using opengl | ||
| glfw.window_hint(glfw.CLIENT_API, glfw.NO_API) | ||
| glfw.window_hint(glfw.RESIZABLE, True) | ||
|
|
||
| self.window = glfw.create_window(640, 480, title, None, None) | ||
| self.context = GPUCanvasContext(self, get_glfw_present_methods(self.window)) | ||
| title = "wgpu glfw direct" | ||
| window = glfw.create_window(640, 480, title, None, None) | ||
| present_info = get_glfw_present_info(window) | ||
|
|
||
| def get_physical_size(self): | ||
| """get framebuffer size in integer pixels""" | ||
| psize = glfw.get_framebuffer_size(self.window) | ||
| return int(psize[0]), int(psize[1]) | ||
| context = wgpu.gpu.get_canvas_context(present_info) | ||
|
|
||
| def get_context(self, kind="wgpu"): | ||
| return self.context | ||
| # Initialize physical size once. For robust apps update this on resize events. | ||
| context.set_physical_size(*glfw.get_framebuffer_size(window)) | ||
|
|
||
|
|
||
| def main(): | ||
| # create canvas | ||
| canvas = MinimalGlfwCanvas("wgpu gui direct") | ||
| draw_frame = setup_drawing_sync(canvas) | ||
| draw_frame = setup_drawing_sync(context) | ||
|
|
||
| last_frame_time = time.perf_counter() | ||
| frame_count = 0 | ||
|
|
||
| # render loop | ||
| while not glfw.window_should_close(canvas.window): | ||
| while not glfw.window_should_close(window): | ||
| # process inputs | ||
| glfw.poll_events() | ||
|
|
||
| # resize handling | ||
| context.set_physical_size(*glfw.get_framebuffer_size(window)) | ||
|
|
||
| # draw a frame | ||
| draw_frame() | ||
| # present the frame to the screen | ||
| canvas.context.present() | ||
| context.present() | ||
| # stats | ||
| frame_count += 1 | ||
| etime = time.perf_counter() - last_frame_time | ||
|
|
@@ -111,7 +103,8 @@ def main(): | |
| last_frame_time, frame_count = time.perf_counter(), 0 | ||
|
|
||
| # dispose resources | ||
| glfw.destroy_window(canvas.window) | ||
| context.unconfigure() | ||
| glfw.destroy_window(window) | ||
|
|
||
| # allow proper cleanup (workaround for glfw bug) | ||
| end_time = time.perf_counter() + 0.1 | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.