Skip to content
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

Window(opengl=True) will now create an OpenGL context #2659

Merged
merged 15 commits into from
May 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion buildconfig/stubs/pygame/window.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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: ...
83 changes: 46 additions & 37 deletions docs/reST/ref/window.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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).

Expand All @@ -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**)`
Expand All @@ -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**)`
Expand All @@ -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
Expand All @@ -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`
Expand All @@ -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`
Expand All @@ -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.

Expand All @@ -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`
Expand All @@ -193,25 +193,25 @@
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`
| :sg:`maximum_size -> (int, int)`

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`.
Expand All @@ -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`
Expand Down Expand Up @@ -256,22 +265,22 @@
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.`
| :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``:

Expand Down Expand Up @@ -355,7 +364,7 @@
| :sl:`Maximize the window`
| :sg:`maximize() -> None`

.. method:: minimize
.. method:: minimize

| :sl:`Minimize the window`
| :sg:`maximize() -> None`
Expand All @@ -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 ##
76 changes: 76 additions & 0 deletions examples/window_opengl.py
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions src_c/doc/window_doc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
1 change: 1 addition & 0 deletions src_c/include/_pygame.h
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ typedef struct {
PyObject_HEAD SDL_Window *_win;
SDL_bool _is_borrowed;
pgSurfaceObject *surf;
SDL_GLContext context;
} pgWindowObject;

#ifndef PYGAMEAPI_WINDOW_INTERNAL
Expand Down
Loading
Loading