```{index} single: SDL2::Video ``` # SDL2::Video ```{pperl-module-badges} SDL2::Video ``` Windows and OpenGL contexts. This is the part of SDL2 that puts something on the screen: it opens a window, moves and resizes it, and - when you ask for one - gives it an OpenGL context to render into. ## The `SDL2::Window` object `SDL2::Window->new` takes named arguments, all optional except that a window with no size is not much use: ```perl my $win = SDL2::Window->new( title => 'my program', # window caption x => undef, # position; undef means "let the system choose" y => undef, w => 640, # size in pixels (default 640 x 480) h => 480, flags => 0, # OR of SDL_WINDOW_* constants shown => 1, # false opens the window hidden opengl => 0, # true adds SDL_WINDOW_OPENGL resizable => 0, # true adds SDL_WINDOW_RESIZABLE ); ``` It calls `SDL_Init(SDL_INIT_VIDEO)` for you if the video subsystem is not up yet, and croaks if the window cannot be created. The window closes and is freed when the last reference to `$win` goes away. Its methods: - `$win->title` / `$win->set_title($text)` - the caption. - `$win->size` - the list `($w, $h)`; `$win->set_size($w, $h)` to change it. - `$win->position` - the list `($x, $y)`; `$win->set_position($x, $y)`. - `$win->show` / `$win->hide` / `$win->raise` - visibility. - `$win->minimize` / `$win->maximize` / `$win->restore`. - `$win->set_fullscreen($flags)` - 0 for windowed, `SDL_WINDOW_FULLSCREEN_DESKTOP` for borderless full screen. - `$win->id` - the numeric id events carry in their `window_id` field. - `$win->flags` - the OR of the `SDL_WINDOW_*` bits currently set. - `$win->wm_info` - the window manager's own handles for this window, as a hash reference. What a graphics API other than OpenGL needs in order to draw here; see below. - `$win->renderer(%opts)` - a `SDL2::Renderer` drawing into this window. - `$win->gl_context` - an `SDL2::GLContext`, made current immediately. - `$win->gl_swap` - show the frame just drawn by OpenGL. - `$win->destroy` - close it now rather than at scope exit. - `$win->handle` - the raw pointer, for passing to the direct layer. ## The `SDL2::GLContext` object `$win->gl_context` returns one, already current. Ask for the OpenGL version you need BEFORE creating the window, with `SDL_GL_SetAttribute`: ```perl SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); my $win = SDL2::Window->new(w => 800, h => 600, opengl => 1); my $ctx = $win->gl_context; ``` Its methods are `$ctx->make_current($win)`, `$ctx->handle` and `$ctx->destroy`. `SDL_GL_GetProcAddress($name)` resolves an OpenGL entry point through the context, which is how a Perl OpenGL binding finds the modern functions without GLEW. ## Drawing on the window with something other than OpenGL A GPU API that is not OpenGL does not take a context from SDL; it takes the window manager's own handles and builds its own surface on them. `$win->wm_info` is where those come from: ```perl my $wm = $win->wm_info; # { subsystem => 2, driver => 'x11', display => ..., window => ... } ``` `driver` is the same lowercase name `SDL_GetCurrentVideoDriver` returns, and it decides which other keys are there: `display` and `window` under X11, `display` and `surface` under Wayland. They are plain integers - a C pointer and an X11 XID - meant to be handed straight back to whatever asked for them, not followed from Perl. `Peta::WebGPU::Device->new(window => $win)` is the one consumer in the runtime today; it reads exactly these keys.