From 8da0e21b7e05e3c6e42ac6f8fec1f9e4dd703e70 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Sun, 7 Jan 2024 01:23:01 -0600 Subject: [PATCH 01/10] Window(opengl=True) will now create an OpenGL context --- docs/reST/ref/window.rst | 4 ++-- src_c/include/_pygame.h | 1 + src_c/window.c | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/reST/ref/window.rst b/docs/reST/ref/window.rst index 83b8191d15..2020e91301 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -26,8 +26,7 @@ the resolution (videomode change). :param bool fullscreen_desktop: Create a fullscreen window using the current desktop resolution. - :param bool opengl: Create a window with support for an OpenGL context. You - will still need to create an OpenGL context separately. + :param bool opengl: Create a window with support for an OpenGL context. :param bool vulkan: Create a window with support for a Vulkan instance. :param bool hidden: Create a hidden window. :param bool borderless: Create a window without borders. @@ -46,6 +45,7 @@ others. .. versionadded:: 2.4.0 + .. versionchanged:: 2.5.0 when ``opengl`` is ``True``, the ``Window`` has an OpenGL context created by pygame .. attribute:: grab_mouse diff --git a/src_c/include/_pygame.h b/src_c/include/_pygame.h index a1a1840581..8e0cd927e7 100644 --- a/src_c/include/_pygame.h +++ b/src_c/include/_pygame.h @@ -497,6 +497,7 @@ typedef struct { PyObject_HEAD SDL_Window *_win; SDL_bool _is_borrowed; pgSurfaceObject *surf; + SDL_GLContext context; } pgWindowObject; #ifndef PYGAMEAPI_WINDOW_INTERNAL diff --git a/src_c/window.c b/src_c/window.c index fddbc6f374..df34051a6c 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -123,6 +123,10 @@ window_destroy(pgWindowObject *self, PyObject *_null) pg_SetDefaultWindow(NULL); } + if (self->context != NULL) { + SDL_GL_DeleteContext(self->_win); + } + SDL_DestroyWindow(self->_win); self->_win = NULL; } @@ -717,6 +721,9 @@ window_dealloc(pgWindowObject *self, PyObject *_null) { if (self->_win) { if (!self->_is_borrowed) { + if (self->context != NULL) { + SDL_GL_DeleteContext(self->_win); + } SDL_DestroyWindow(self->_win); } else if (SDL_GetWindowData(self->_win, "pg_window") != NULL) { @@ -918,6 +925,17 @@ window_init(pgWindowObject *self, PyObject *args, PyObject *kwargs) self->_is_borrowed = SDL_FALSE; self->surf = NULL; + if (SDL_GetWindowFlags(self->_win) & SDL_WINDOW_OPENGL) { + SDL_GLContext context = SDL_GL_CreateContext(self->_win); + if (context == NULL) { + return RAISE(pgExc_SDLError, SDL_GetError()); + } + self->context = context; + } + else { + self->context = NULL; + } + SDL_SetWindowData(_win, "pg_window", self); PyObject *icon = pg_display_resource(icon_defaultname); From db638ac26f13f18f5ad4e1d1c7ed2ca1d83b90f3 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Sun, 7 Jan 2024 01:28:20 -0600 Subject: [PATCH 02/10] fixed some type issues --- src_c/window.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src_c/window.c b/src_c/window.c index df34051a6c..4440083637 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -124,7 +124,7 @@ window_destroy(pgWindowObject *self, PyObject *_null) } if (self->context != NULL) { - SDL_GL_DeleteContext(self->_win); + SDL_GL_DeleteContext(self->context); } SDL_DestroyWindow(self->_win); @@ -722,7 +722,7 @@ window_dealloc(pgWindowObject *self, PyObject *_null) if (self->_win) { if (!self->_is_borrowed) { if (self->context != NULL) { - SDL_GL_DeleteContext(self->_win); + SDL_GL_DeleteContext(self->context); } SDL_DestroyWindow(self->_win); } @@ -928,7 +928,8 @@ window_init(pgWindowObject *self, PyObject *args, PyObject *kwargs) if (SDL_GetWindowFlags(self->_win) & SDL_WINDOW_OPENGL) { SDL_GLContext context = SDL_GL_CreateContext(self->_win); if (context == NULL) { - return RAISE(pgExc_SDLError, SDL_GetError()); + PyErr_SetString(pgExc_SDLError, SDL_GetError()); + return -1; } self->context = context; } From e6aa7ccf900964abb25de0ccbbbdacba754cdb37 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Wed, 17 Jan 2024 21:45:33 -0600 Subject: [PATCH 03/10] opengl now works with a window created with the opengl flag lol --- buildconfig/stubs/pygame/window.pyi | 4 +- docs/reST/ref/window.rst | 71 ++++++++++++++++------------- src_c/doc/window_doc.h | 1 + src_c/window.c | 51 +++++++++++++++++---- test/window_test.py | 29 ++++++++++++ 5 files changed, 114 insertions(+), 42 deletions(-) diff --git a/buildconfig/stubs/pygame/window.pyi b/buildconfig/stubs/pygame/window.pyi index f0c79c476d..9b09e76d2d 100644 --- a/buildconfig/stubs/pygame/window.pyi +++ b/buildconfig/stubs/pygame/window.pyi @@ -28,7 +28,7 @@ class Window: def set_icon(self, icon: Surface, /) -> None: ... def get_surface(self) -> Surface: ... def flip(self) -> None: ... - + grab_mouse: bool grab_keyboard: bool title: str @@ -64,5 +64,7 @@ class Window: def position(self) -> Tuple[int, int]: ... @position.setter def position(self, value: Union[int, Coordinate]) -> None: ... + @property + def opengl(self) -> bool: ... @classmethod def from_display_module(cls) -> Window: ... diff --git a/docs/reST/ref/window.rst b/docs/reST/ref/window.rst index 2020e91301..a89f4ccde8 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -12,7 +12,7 @@ The Window class (formerly known as _sdl2.video.Window), is an experimental feature of pygame-ce. This class allows for programs to drive multiple - Windows on-screen at once, something not possible with the + Windows on-screen at once, something not possible with the :func:`pygame.display.set_mode` API. Not everything possible with :mod:`pygame.display` is possible yet in the Window API, but the new window class will continue to be developed, and we're excited to share @@ -63,19 +63,19 @@ .. seealso:: :attr:`mouse_grabbed` .. versionadded:: 2.4.0 - + .. attribute:: grab_keyboard | :sl:`Get or set the window's keyboard grab mode` | :sg:`grab_keyboard -> bool` - - When this attribute is set to ``True``, the window will try to capture system - keyboard shortcuts like ``Alt+Tab`` or the ``Meta/Super`` key. + + When this attribute is set to ``True``, the window will try to capture system + keyboard shortcuts like ``Alt+Tab`` or the ``Meta/Super`` key. This attribute only set the "mode" of grab. The keyboard may be captured by - another window depending on the window focus. To get if keyboard is currently + another window depending on the window focus. To get if keyboard is currently captured by this window, please use :attr:`keyboard_grabbed`. - + Note that not all system keyboard shortcuts can be captured by applications (one example is ``Ctrl+Alt+Del`` on Windows). @@ -90,7 +90,7 @@ .. seealso:: :attr:`keyboard_grabbed` .. versionadded:: 2.4.0 - + .. attribute:: mouse_grabbed | :sl:`Get if the mouse cursor is confined to the window (**read-only**)` @@ -99,15 +99,15 @@ Get if the mouse cursor is currently grabbed and confined to the window. Roughly equivalent to this expression: - + :: win.grab_mouse and (win is get_grabbed_window()) - + .. seealso:: :attr:`grab_mouse` - + .. versionadded:: 2.4.0 - + .. attribute:: keyboard_grabbed | :sl:`Get if the keyboard shortcuts are captured by the window (**read-only**)` @@ -116,15 +116,15 @@ Get if the keyboard shortcuts are currently grabbed and captured by the window. Roughly equivalent to this expression: - + :: win.grab_keyboard and (win is get_grabbed_window()) - + This attribute requires SDL 2.0.16+. - + .. seealso:: :attr:`grab_keyboard` - + .. versionadded:: 2.4.0 .. attribute:: title @@ -147,7 +147,7 @@ Gets or sets whether the window is borderless. .. note:: You can't change the border state of a fullscreen window. - + .. attribute:: always_on_top | :sl:`Get or set whether the window is always on top` @@ -163,7 +163,7 @@ | :sl:`Get the unique window ID (**read-only**)` | :sg:`id -> int` - + .. attribute:: mouse_rect | :sl:`Get or set the mouse confinement rectangle of the window` @@ -173,7 +173,7 @@ cursor to the specified area of this window. This attribute can be None, meaning that there is no mouse rect. - + Note that this does NOT grab the cursor, it only defines the area a cursor is restricted to when the window has mouse focus. @@ -183,7 +183,7 @@ | :sl:`Get or set the window size in pixels` | :sg:`size -> (int, int)` - + .. attribute:: minimum_size | :sl:`Get or set the minimum size of the window's client area` @@ -193,16 +193,16 @@ was used to create the window and :func:`pygame.display.set_mode` was called with the ``SCALED`` flag, the initial value is the size used in that call. - - Raises a ``ValueError`` if negative values are provided or - if the width or height provided are greater than set - maximum width or height respectively. Unless maximum size + + Raises a ``ValueError`` if negative values are provided or + if the width or height provided are greater than set + maximum width or height respectively. Unless maximum size is ``(0, 0)`` (initial value). .. seealso:: :attr:`maximum_size`. .. versionadded:: 2.4.0 - + .. attribute:: maximum_size | :sl:`Get or set the maximum size of the window's client area` @@ -210,8 +210,8 @@ Initial value is ``(0, 0)``. - Raises a ``ValueError`` if negative values are provided or - if the width or height provided are less than set minimum + Raises a ``ValueError`` if negative values are provided or + if the width or height provided are less than set minimum width or height respectively. .. seealso:: :attr:`minimum_size`. @@ -228,6 +228,15 @@ | :sl:`Get or set the window opacity, between 0.0 (fully transparent) and 1.0 (fully opaque)` | :sg:`opacity -> float` + .. attribute:: opengl + + | :sl:`Get if the window supports OpenGL` + | :sg:`opengl -> bool` + + ``True`` if the ``Window`` has an OpenGL context associated with it, ``False`` otherwise + + .. versionadded:: 2.5.0 + .. classmethod:: from_display_module | :sl:`Create a Window object using window data from display module` @@ -256,11 +265,11 @@ Similarly to the "display surface" returned by :mod:`pygame.display`, this surface will change size with the Window, and will become invalid after the Window's destruction. - + .. seealso:: :func:`flip` .. versionadded:: 2.4.0 - + .. method:: flip | :sl:`Update the display surface to the window.` @@ -355,7 +364,7 @@ | :sl:`Maximize the window` | :sg:`maximize() -> None` - .. method:: minimize + .. method:: minimize | :sl:`Minimize the window` | :sg:`maximize() -> None` @@ -375,7 +384,7 @@ | :sg:`set_modal_for(parent, /) -> None` :param Window parent: The parent window. - + .. note:: This function is only supported on X11. .. ## pygame.Window ## diff --git a/src_c/doc/window_doc.h b/src_c/doc/window_doc.h index 27fdbf1be7..ad23d5562c 100644 --- a/src_c/doc/window_doc.h +++ b/src_c/doc/window_doc.h @@ -15,6 +15,7 @@ #define DOC_WINDOW_MAXIMUMSIZE "maximum_size -> (int, int)\nGet or set the maximum size of the window's client area" #define DOC_WINDOW_POSITION "position -> (int, int) or WINDOWPOS_CENTERED or WINDOWPOS_UNDEFINED\nGet or set the window position in screen coordinates" #define DOC_WINDOW_OPACITY "opacity -> float\nGet or set the window opacity, between 0.0 (fully transparent) and 1.0 (fully opaque)" +#define DOC_WINDOW_OPENGL "opengl -> bool\nGet if the window supports OpenGL" #define DOC_WINDOW_FROMDISPLAYMODULE "from_display_module() -> Window\nCreate a Window object using window data from display module" #define DOC_WINDOW_GETSURFACE "get_surface() -> Surface\nGet the window surface" #define DOC_WINDOW_FLIP "flip() -> None\nUpdate the display surface to the window." diff --git a/src_c/window.c b/src_c/window.c index 7db3585726..70c6e68170 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -187,17 +187,24 @@ window_flip(pgWindowObject *self) { int result; - if (!self->surf) { - return RAISE(pgExc_SDLError, - "the Window has no surface associated with it, did " - "you forget to call Window.get_surface()"); - } + if (self->context == NULL) + { + if (!self->surf) { + return RAISE(pgExc_SDLError, + "the Window has no surface associated with it, did " + "you forget to call Window.get_surface()"); + } - Py_BEGIN_ALLOW_THREADS; - result = SDL_UpdateWindowSurface(self->_win); - Py_END_ALLOW_THREADS; - if (result) { - return RAISE(pgExc_SDLError, SDL_GetError()); + Py_BEGIN_ALLOW_THREADS; + result = SDL_UpdateWindowSurface(self->_win); + Py_END_ALLOW_THREADS; + if (result) { + return RAISE(pgExc_SDLError, SDL_GetError()); + } + } + else + { + SDL_GL_SwapWindow(self->_win); } Py_RETURN_NONE; } @@ -723,6 +730,22 @@ window_get_opacity(pgWindowObject *self, void *v) return PyFloat_FromDouble((double)opacity); } +static PyObject* +window_get_opengl(pgWindowObject *self, void *v) +{ + long hasGL; + if (!self->_is_borrowed) + { + hasGL = self->context != NULL; + } + else + { + int flags = SDL_GetWindowFlags(self->_win); + hasGL = (flags & SDL_WINDOW_OPENGL) > 0; + } + return PyBool_FromLong(hasGL); +} + static void window_dealloc(pgWindowObject *self, PyObject *_null) { @@ -794,7 +817,14 @@ window_init(pgWindowObject *self, PyObject *args, PyObject *kwargs) if (!strcmp(_key_str, "opengl")) { if (_value_bool) + { + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); flags |= SDL_WINDOW_OPENGL; + } + else + { + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0); + } } else if (!strcmp(_key_str, "fullscreen")) { if (_value_bool) @@ -1084,6 +1114,7 @@ static PyGetSetDef _window_getset[] = { {"opacity", (getter)window_get_opacity, (setter)window_set_opacity, DOC_WINDOW_OPACITY, NULL}, {"id", (getter)window_get_window_id, NULL, DOC_WINDOW_ID, NULL}, + {"opengl", (getter)window_get_opengl, NULL, DOC_WINDOW_OPENGL, NULL}, {NULL, 0, NULL, NULL, NULL} /* Sentinel */ }; diff --git a/test/window_test.py b/test/window_test.py index 302ccc78a4..7af4378e59 100644 --- a/test/window_test.py +++ b/test/window_test.py @@ -265,6 +265,11 @@ def test_opacity_set(self): self.assertRaises(TypeError, lambda: setattr(self.win, "opacity", "null str")) def test_init_flags(self): + # test no opengl by default + win = Window() + self.assertFalse(win.opengl) + win.destroy() + # test borderless win = Window(borderless=True) self.assertTrue(win.borderless) @@ -281,6 +286,11 @@ def test_init_flags(self): self.assertTrue(win.resizable) win.destroy() + # test opengl + win = Window(opengl=True) + self.assertTrue(win.opengl) + win.destroy() + # should raise a TypeError if keyword is random self.assertRaises(TypeError, lambda: Window(aaa=True)) self.assertRaises(TypeError, lambda: Window(aaa=False)) @@ -315,6 +325,7 @@ def test_from_display_module(self): win2 = Window.from_display_module() self.assertIs(win1, win2) + self.assertFalse(win1.opengl) pygame.display.quit() pygame.init() @@ -369,6 +380,24 @@ def test_window_flip(self): ) win.destroy() + def test_window_opengl(self): + win1 = Window(opengl=True) + self.assertTrue(win1.opengl) + win1.flip() + win1.destroy() + + win2 = Window(opengl=False) + self.assertFalse(win2.opengl) + win2.get_surface() + win2.flip() + win2.destroy() + + pygame.display.set_mode((640, 480), pygame.OPENGL) + win = Window.from_display_module() + self.assertTrue(win.opengl) + pygame.display.quit() + pygame.init() + def tearDown(self): self.win.destroy() From 3c0e08a1d7cc44717e13c8673f429caf1fbecc32 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Wed, 17 Jan 2024 21:46:34 -0600 Subject: [PATCH 04/10] format --- src_c/window.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src_c/window.c b/src_c/window.c index 70c6e68170..7915f782d0 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -187,12 +187,11 @@ window_flip(pgWindowObject *self) { int result; - if (self->context == NULL) - { + if (self->context == NULL) { if (!self->surf) { return RAISE(pgExc_SDLError, - "the Window has no surface associated with it, did " - "you forget to call Window.get_surface()"); + "the Window has no surface associated with it, did " + "you forget to call Window.get_surface()"); } Py_BEGIN_ALLOW_THREADS; @@ -202,8 +201,7 @@ window_flip(pgWindowObject *self) return RAISE(pgExc_SDLError, SDL_GetError()); } } - else - { + else { SDL_GL_SwapWindow(self->_win); } Py_RETURN_NONE; @@ -730,16 +728,14 @@ window_get_opacity(pgWindowObject *self, void *v) return PyFloat_FromDouble((double)opacity); } -static PyObject* +static PyObject * window_get_opengl(pgWindowObject *self, void *v) { long hasGL; - if (!self->_is_borrowed) - { + if (!self->_is_borrowed) { hasGL = self->context != NULL; } - else - { + else { int flags = SDL_GetWindowFlags(self->_win); hasGL = (flags & SDL_WINDOW_OPENGL) > 0; } @@ -816,13 +812,11 @@ window_init(pgWindowObject *self, PyObject *args, PyObject *kwargs) return -1; if (!strcmp(_key_str, "opengl")) { - if (_value_bool) - { + if (_value_bool) { SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); flags |= SDL_WINDOW_OPENGL; } - else - { + else { SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0); } } From caca6fe8e236dbcc8961171c5f0abbb3788be74b Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Wed, 17 Jan 2024 21:57:03 -0600 Subject: [PATCH 05/10] skip opengl tests if opengl not present --- test/window_test.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/window_test.py b/test/window_test.py index 7af4378e59..b356f5b959 100644 --- a/test/window_test.py +++ b/test/window_test.py @@ -286,11 +286,6 @@ def test_init_flags(self): self.assertTrue(win.resizable) win.destroy() - # test opengl - win = Window(opengl=True) - self.assertTrue(win.opengl) - win.destroy() - # should raise a TypeError if keyword is random self.assertRaises(TypeError, lambda: Window(aaa=True)) self.assertRaises(TypeError, lambda: Window(aaa=False)) @@ -380,6 +375,10 @@ def test_window_flip(self): ) win.destroy() + @unittest.skipIf( + os.environ.get("SDL_VIDEODRIVER") == pygame.NULL_VIDEODRIVER, + "OpenGL requires a non-null SDL_VIDEODRIVER", + ) def test_window_opengl(self): win1 = Window(opengl=True) self.assertTrue(win1.opengl) From cb9494bc725c9f9a741616e1f5a0917a74c28ddb Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Fri, 19 Jan 2024 16:41:30 -0600 Subject: [PATCH 06/10] added example for Window opengl --- examples/window_opengl.py | 76 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 examples/window_opengl.py diff --git a/examples/window_opengl.py b/examples/window_opengl.py new file mode 100644 index 0000000000..237c051687 --- /dev/null +++ b/examples/window_opengl.py @@ -0,0 +1,76 @@ +""" pygame.examples.window_opengl + +Slightly modified version of the example at https://github.com/szabolcsdombi/zengl/blob/main/examples/pygame/hello_world.py +Modified to use Window API instead of the display module + +Posted here with permission from https://github.com/szabolcsdombi given in the PGC discord server +""" + +import pygame +import zengl + +window_size = (1280, 720) + +pygame.init() +window = pygame.Window(size=window_size, opengl=True) + +ctx = zengl.context() + +image = ctx.image(window_size, "rgba8unorm", samples=4) + +pipeline = ctx.pipeline( + vertex_shader=""" + #version 330 core + + out vec3 v_color; + + vec2 vertices[3] = vec2[]( + vec2(0.0, 0.8), + vec2(-0.6, -0.8), + vec2(0.6, -0.8) + ); + + vec3 colors[3] = vec3[]( + vec3(1.0, 0.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 0.0, 1.0) + ); + + void main() { + gl_Position = vec4(vertices[gl_VertexID], 0.0, 1.0); + v_color = colors[gl_VertexID]; + } + """, + fragment_shader=""" + #version 330 core + + in vec3 v_color; + + layout (location = 0) out vec4 out_color; + + void main() { + out_color = vec4(v_color, 1.0); + out_color.rgb = pow(out_color.rgb, vec3(1.0 / 2.2)); + } + """, + framebuffer=[image], + topology="triangles", + vertex_count=3, +) + +clock = pygame.Clock() + +while True: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + quit() + + ctx.new_frame() + image.clear() + pipeline.render() + image.blit() + ctx.end_frame() + + window.flip() + clock.tick(60) \ No newline at end of file From a0c3f14704508bd138cf14cb530d6372f953a538 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Fri, 19 Jan 2024 16:44:51 -0600 Subject: [PATCH 07/10] format --- examples/window_opengl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/window_opengl.py b/examples/window_opengl.py index 237c051687..5b13d4b38e 100644 --- a/examples/window_opengl.py +++ b/examples/window_opengl.py @@ -73,4 +73,4 @@ ctx.end_frame() window.flip() - clock.tick(60) \ No newline at end of file + clock.tick(60) From a7760f81cf314e11e5565688ca4219b4bb113857 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Wed, 24 Apr 2024 21:24:13 -0500 Subject: [PATCH 08/10] release GIL when swapping opengl window --- src_c/window.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src_c/window.c b/src_c/window.c index 7915f782d0..3f71c6317a 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -202,7 +202,9 @@ window_flip(pgWindowObject *self) } } else { + Py_BEGIN_ALLOW_THREADS; SDL_GL_SwapWindow(self->_win); + Py_END_ALLOW_THREADS; } Py_RETURN_NONE; } From 4da1c784fea705dbcde474a98bd7789dd560cc7b Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Mon, 20 May 2024 13:56:40 -0500 Subject: [PATCH 09/10] Formatted example with ruff --- examples/window_opengl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/window_opengl.py b/examples/window_opengl.py index 5b13d4b38e..9f10e4b400 100644 --- a/examples/window_opengl.py +++ b/examples/window_opengl.py @@ -1,4 +1,4 @@ -""" pygame.examples.window_opengl +"""pygame.examples.window_opengl Slightly modified version of the example at https://github.com/szabolcsdombi/zengl/blob/main/examples/pygame/hello_world.py Modified to use Window API instead of the display module From 7405ce6fdc63e187688abd0d4d6609943b675e98 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Fri, 24 May 2024 17:20:11 +0100 Subject: [PATCH 10/10] Add/alter docs for flip --- docs/reST/ref/window.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/reST/ref/window.rst b/docs/reST/ref/window.rst index 7fb1ff47ab..1365b636aa 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -275,12 +275,12 @@ | :sl:`Update the display surface to the window.` | :sg:`flip() -> None` - Update content from the display surface to the window. This is the Window + Update pixel data from memory to be displayed in the window. This is the Window class equivalent of :func:`pygame.display.flip`. - This method allows software rendering (classic pygame rendering) on top - of the Window API. This method should not be called when using hardware - rendering (coming soon). + With ``get_surface()`` this method allows software rendering (classic pygame rendering) flipping pixel data + from an associated surface in memory to be displayed in the window. Alternatively, when this window has an + associated OpenGL context, this method will instead perform a GL buffer swap to the window. Here is a runnable example of using ``get_surface`` and ``flip``: