Title Window SDL3

Window and Renderer in SDL3


Every SDL3 application with graphic output has to have at least one SDL3 window and a SDL3 renderer. The window is the entity that is showing the graphic output and the renderer is the “machine” that is generating the output. The code to set up a window and a renderer is as follows.

program SDL_WindowAndRenderer;

uses SDL3;

var
  sdlWindow1: PSDL_Window;
  sdlRenderer: PSDL_Renderer;

begin

  //initilization of video subsystem
  if not SDL_Init(SDL_INIT_VIDEO) then Halt;

  // full set up
  sdlWindow1 := SDL_CreateWindow('Window1', 500, 500, 0);
  if sdlWindow1 = nil then Halt;

  sdlRenderer := SDL_CreateRenderer(sdlWindow1, nil);
  if sdlRenderer = nil then Halt;

  // quick set up
  {
  if not SDL_CreateWindowAndRenderer(500, 500, 0, @sdlWindow1, @sdlRenderer)
    then Halt;
  }

  // show window with rendered content for 2 seconds
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(2000);

  // clear memory
  SDL_DestroyRenderer(sdlRenderer);
  SDL_DestroyWindow (sdlWindow1);

  //closing SDL3
  SDL_Quit;

end.

Getting a Window with SDL3

With SDL3 you can create as many windows as you like, and each window is adressed by a variable of pointer type PSDL_Window. We just need one window we define in the var clause, let’s call it “sdlWindow1”.

It defines the window’s properties, e.g. size, appearance, border, title name and so on. And it holds the content it shows.

Creation of a Window in SDL3

  sdlWindow1 := SDL_CreateWindow('Window1', 500, 500, 0);
  if sdlWindow1 = nil then Halt;

The actual creation of a window in SDL3 is as simple as using the function SDL_CreateWindow(title, width, height, flags). If it fails, sdlWindow1 will be nil afterwards. You should always check this.

In our example the window is titled “Window1”, it has a width and height of 500 pixels respectively. And we don’t want to set a specific flag. This will generate a common window as typical for your operating system at the screen’s center.

Hint for MacOS users: Window creation doesn’t work without an event loop in MacOS in SDL2. Please let me know, if this also applies for SDL3.

SDL3 Window Flags

The SDL3 window flags decide for the properties of the window. Look at the following list of possible flags and you may get an idea what they do. E.g. SDL_WINDOW_FULLSCREEN will create a fullscreen window and SDL_WINDOW_BORDERLESS will create a borderless window. You may combine several flags by the logical OR (if appropriate).

  • SDL_WINDOW_FULLSCREEN: fullscreen window at desktop resolution
  • SDL_WINDOW_OPENGL: window usable with an OpenGL context
  • SDL_WINDOW_OCCLUDED: window partially or completely obscured by another window
  • SDL_WINDOW_HIDDEN: window is not visible
  • SDL_WINDOW_BORDERLESS: no window decoration
  • SDL_WINDOW_RESIZABLE: window can be resized
  • SDL_WINDOW_MINIMIZED: window is minimized
  • SDL_WINDOW_MAXIMIZED: window is maximized
  • SDL_WINDOW_MOUSE_GRABBED: window has grabbed mouse focus
  • SDL_WINDOW_INPUT_FOCUS: window has input focus
  • SDL_WINDOW_MOUSE_FOCUS: window has mouse focus
  • SDL_WINDOW_EXTERNAL: window not created by SDL
  • SDL_WINDOW_MODAL: window is modal
  • SDL_WINDOW_HIGH_PIXEL_DENSITY: window uses high pixel density back buffer if possible
  • SDL_WINDOW_MOUSE_CAPTURE: window has mouse captured (unrelated to MOUSE_GRABBED)
  • SDL_WINDOW_ALWAYS_ON_TOP: window should always be above others
  • SDL_WINDOW_UTILITY: window should be treated as a utility window, not showing in the task bar and window list
  • SDL_WINDOW_TOOLTIP: window should be treated as a tooltip and does not get mouse or keyboard focus, requires a parent window
  • SDL_WINDOW_POPUP_MENU: window should be treated as a popup menu, requires a parent window
  • SDL_WINDOW_KEYBOARD_GRABBED: window has grabbed keyboard input
  • SDL_WINDOW_VULKAN: window usable with a Vulkan instance
  • SDL_WINDOW_METAL: window usable with a Metal instance
  • SDL_WINDOW_TRANSPARENT: window with transparent buffer
  • SDL_WINDOW_NOT_FOCUSABLE: window should not be focusable

The Renderer

In computer graphics rendering means the process of synthesizing the final image on your screen from the individual basic data structures, be it some lines, a flat background, a texture, a 3d object, or whatever. Hence we need a renderer to draw some content to the window.

The PSDL_Renderer pointer (which we declared in the var clause) is responsible for this and we call our PSDL_Renderer handle “sdlRenderer”. You could have many different renderers in an application, but oftentimes you use just one.

Creation of a Renderer in SDL3

  sdlRenderer := SDL_CreateRenderer(sdlWindow1, nil);
  if sdlRenderer = nil then Halt;

The creation of a renderer is as simple as one function call of SDL_CreateRenderer(window, name). If it fails, sdlRenderer is nil afterwards. The first argument is the window where the rendered output should be shown. That will be sdlWindow1 in our case.

The second argument should be nil which means SDL3 is choosing the best renderer for you. Otherwise you could specify a renderer by name, but that is not necessary for now.

Quick Creation of a Window and a Renderer

  if not SDL_CreateWindowAndRenderer(500, 500, 0, @sdlWindow1, @sdlRenderer)
    then Halt;

Instead of creating the window and the renderer separately as demonstrated, you may use SDL_CreateWindowAndRenderer(width, height, window flags, window pointer pointer, renderer pointer pointer). This has the advantage that you just need one line to set up a window and a renderer. Since the window and renderer parameters are double pointers, you need to use the @ operator to make the window and renderer pointers available to the function.

Just remove the curly brackets and enclose the “full set up” -part in the example code to try it.

The function returns a logical false on failure.

Rendering a SDL3 Scene

The actual rendering is achieved by SDL_RenderPresent(renderer).

Freezing (delaying) a running application in SDL3

SDL_Delay(time in milliseconds) is a simple, yet powerful and important procedure to stop the program running for a certain time in milliseconds. 2000 milliseconds are two seconds. This is kind of a twin of Pascal’s Delay procedure.

  // show window with rendered content for 2 seconds
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(2000);

Clean up the Memory in SDL3

Now the final lines of code are discussed. One of the most important rules for sophisticated programming is followed here:

Always clean up the memory on program finish.

For nearly any pointer type generated by SDL3, there is a destroy procedure to remove it from memory. These procedures are comparable to Pascal’s dispose procedure to remove pointer types from memory. Make sure to destroy the objects in the opposite sequence of their generation. We first created a window, then a renderer. So now we go the opposite way, first destroy the renderer and then the window by the procedures SDL_DestroyRenderer(renderer) and SDL_DestroyWindow(window) respectively.

  // clear memory
  SDL_DestroyRenderer(sdlRenderer);
  SDL_DestroyWindow (sdlWindow1);
  
  //closing SDL3
  SDL_Quit;

Finally quit SDL3.

That’s it. And now things are going to get really interesting :-).

Previous Chapter | Next Chapter

Leave a Reply

Your email address will not be published. Required fields are marked *