Tag Archives: delphi

SDL3 Primitives Feature Image

Drawing Primitives


For many applications and games drawing operations are essential. The most famous case is, if you create your own graphical user interface (GUI). This means there are buttons (and other GUI elements) of dynamic dimensions and coloring in your application. Explanation of another important case, especially in game development, can be read about here.

Supported Primitives: Points, Lines, Rectangles

SDL3 supports natively the drawing of

  • Points
  • Lines
  • Rectangles (outlines)
  • Filled Rectangles.

Drawing in SDL3

Now lets jump right into the code:

program SDL_DrawingPrimitives;

uses 
  SDL3;

var
  i: Integer;
  sdlWindow1: PSDL_Window;
  sdlRenderer: PSDL_Renderer;
  sdlRect1: TSDL_FRect;
  sdlPoints: array[0..499] of TSDL_FPoint;

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

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

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

  //render and show cleared window with grey background color
  SDL_SetRenderDrawColor(sdlRenderer, 50, 50, 50, SDL_ALPHA_OPAQUE);
  SDL_RenderClear(sdlRenderer);
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(1000);

  //render and show a red line
  SDL_SetRenderDrawColor(sdlRenderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
  SDL_RenderLine(sdlRenderer, 10, 10, 490, 490);
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(1000);

  //render and draw yellow points diagonally with distance between each other
  SDL_SetRenderDrawColor(sdlRenderer, 255, 255, 0, SDL_ALPHA_OPAQUE);
  for i := 0 to 47 do
    SDL_RenderPoint(sdlRenderer, 490-i*10, 10+i*10);
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(1000);
    
  //prepare, render and draw a series of random connected black lines
  Randomize;
  for i := 0 to 499 do
  begin
    sdlPoints[i].x := Random(500);
    sdlPoints[i].y := Random(500);
  end;
  SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
  SDL_RenderLines(sdlRenderer, @sdlPoints, 500);
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(1000);

  //prepare, render and draw a green rectangle outline at upper-right corner
  sdlRect1.x := 260;
  sdlRect1.y := 10;
  sdlRect1.w := 230;
  sdlRect1.h := 230;
  SDL_SetRenderDrawColor(sdlRenderer, 0, 255, 0, SDL_ALPHA_OPAQUE);
  SDL_RenderRect(sdlRenderer, @sdlRect1);

  //render and draw the rectangle with 50% opacity at lower-left corner
  sdlRect1.x := 10;
  sdlRect1.y := 260;
  SDL_SetRenderDrawBlendMode(sdlRenderer, SDL_BLENDMODE_BLEND);
  SDL_SetRenderDrawColor(sdlRenderer, 0, 255, 0, 128);
  SDL_RenderFillRect(sdlRenderer, @sdlRect1);
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(1000);

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

  //shut down SDL3
  SDL_Quit;
end.

Wow, that looks like a big load of new functions, but I promise, drawing in SDL3 is very simple. Running the program should result in something like this (it’s alright, nothing went wrong here 😉

Now, let’s have a closer look to the first lines of code.

program SDL_DrawingPrimitives;

uses
  SDL3;

var
  i: Integer;
  sdlWindow1: PSDL_Window;
  sdlRenderer: PSDL_Renderer;
  sdlRect1: TSDL_FRect;
  sdlPoints: array[0..499] of TSDL_FPoint;
    
begin
  //initilization of video subsystem
  if not SDL_Init(SDL_INIT_VIDEO) then Halt;

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

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

The program is called “SDL_DrawingPrimitives” and uses the SDL3 unit. In the var clause we have a counter variable “i” of native Pascal type integer we need later. We need a window and a renderer and call them “sdlWindow1” and “sdlRenderer” as known from the previous chapters. And in the bottom part of the code snippet they are created as known from last chapter and SDL3 is initialized.

The interesting and new part about this code snippet is in the var clause.

About Rectangles and Points in SDL3

Next we declare a variable “sdlRect1” which is of type TSDL_FRect. The same is true for “sdlPoints” which is an array of 500 elements of type TSDL_FPoint.

TSDL_FRect is a record which is used to describe rectangles in SDL3 by four values:

  • x: x-coordinate of the rectangle
  • y: y-coordinate of the rectangle
  • w: width of the rectangle
  • h: height of the rectangle.

The F indicates that the values are of float point type (Pascal: Single). This allows for sub-pixel precision for coordinates and dimensions.

TSDL_FRect has an older brother, TSDL_Rect, which only allows integer values. Other than that they are identical.

Unsurprisingly, TSDL_FPoint describes a point in SDL3 by just two values:

  • x: x-coordinate of the point
  • y: y-coordinate of the point.

By definition, points have no dimension, so that’s it. Again, the F indicates their values being of float point type. And also TSDL_FPoint has an older counter-part TSDL_Point with integer values instead.

Colours and RGB(A) Notation in SDL3

  //render and show cleared window with grey background color
  SDL_SetRenderDrawColor(sdlRenderer, 50, 50, 50, SDL_ALPHA_OPAQUE);
  SDL_RenderClear(sdlRenderer);
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(1000);  

Now we have something new here: SDL_SetRenderDrawColor(renderer, red value, green value, blue value, alpha value) sets a colour for drawing operations, just as if you choose for a pencil colour to draw something. This function doesn’t draw anything though.

First you need to set the renderer for which this drawing colour is meant. After that you have to set the colours red, green, blue and the alpha value. They can range from 0 to 255 (integer values only). Think in terms of 255 being 100% of that colour and 0 being 0%. As a start let’s neglect the alpha value.

If you like to have a red colour, you need to set the value for the red colour high, e.g. 100%, the maximum value is 255, and since you don’t want to mix in green and blue, they get the minimum value of 0 (hence 0%). Setting up red therefore corresponds to 255/0/0 in terms of r/g/b. For comparison, 0/255/0 leads to green, 0/0/255 to blue, 255/255/255 is white and 0/0/0 is black, and so on. In the example code we used 50/50/50 which leads to a dark grey (mixing up red, green and blue of the same ratio additively). With these three values you can generate every colour possible. For more information on colours in computer graphics, go here.

The Alpha Value

The alpha value determines the transparency. 255 means fully opaque and 0 means full transparency. This is very important for blend effects in computer graphics and will be demonstrated later on in the example. By the way, instead of 255 you could use SDL_ALPHA_OPAQUE.

Setting up a Background in SDL3

The function SDL_RenderClear(renderer) is for clearing the screen with the drawing colour. As argument you just need to tell the renderer. It is simple as that :-). Since we set the drawing colour to dark grey before, the screen will be cleared with that colour.

The cleared screen will be shown for one second by SDL_RenderPresent() and SDL_Delay(). These two procedures are known from the previous chapter.

Drawing Lines and Points in SDL3

  //render and show a red line
  SDL_SetRenderDrawColor(sdlRenderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
  SDL_RenderLine(sdlRenderer, 10, 10, 490, 490);
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(1000); 

Now we change the drawing colour by SDL_SetRenderDrawColor() to red and use SDL_RenderDrawLine(renderer, x1, y1, x2, y2) to draw a simple line, where x1, y1, x2 and y2 refers to coordinate pairs, hence (x1/y1) and (x2/y2). The first pair is (10/10), the second pair is (490/490). The red line should be drawn from coordinate (10/10) to coordinate (490/490). But where are these coordinates exactly in the window?

The Coordinate System in SDL3

This rule applies:

The origin from where to place an object is always the left upper corner of your screen or window.

In a SDL3 window (or screen if fullscreen) the cooodinate (0/0) refers to the left upper corner. The diagram below may help to understand this.

Creative Commons License This image by https://www.freepascal-meets-sdl.net is licensed under a Creative Commons Attribution 4.0 International License.
The window is placed with respect to the left upper corner of the screen.

The coordinate (10/10) means to start at the point ten pixels to the right and ten pixel to the bottom relative to the origin (0/0). Thus, the coordinate (490/490) for the second point is nearly at the right bottom edge of the window and will lead to a diagonal line across. This diagonal line will be 10 pixels short with respect to the window edges.

After that again we ask to render this line to the screen by SDL_RenderPresent() and wait one second by SDL_Delay().

  //render and draw yellow points diagonally with distance between each other
  SDL_SetRenderDrawColor(sdlRenderer, 255, 255, 0, SDL_ALPHA_OPAQUE);
  for i := 0 to 47 do
    SDL_RenderPoint(sdlRenderer, 490-i*10, 10+i*10);
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(1000); 

Now we change the colour to yellow and draw some points by the function SDL_RenderDrawPoint(renderer, x, y). It is nearly identical to SDL_RenderDrawLine() but instead of four coordinates you need just two coordinates where the point should be drawn.

I thought it would be nice to have more than just one point to be drawn, so the function is used in a for-loop to draw altogether 48 points. Here we need the counter variable “i”. Maybe you can guess from the code where the points are and how they are arranged, if not, just run the code ;-). Finally the result is rendered to the screen by SDL_RenderPresent() and the program waits one second by SDL_Delay().

Spread Points Randomly using Arrays

  //prepare, render and draw a series of random connected black lines
  Randomize;
  for i := 0 to 499 do
  begin
    sdlPoints[i].x := Random(500);
    sdlPoints[i].y := Random(500);
  end;
  SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
  SDL_RenderLines(sdlRenderer, @sdlPoints, 500);
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(1000);

Randomize is a Free Pascal procedure (from system unit) to initilize the random number generator. Imagine this as shaking the dice.

Free Pascal’s Random(max. number – 1) function generates random numbers between 0 and the number which is used as argument substracted by one. So we generate 500 times a random x and y value between 0 and 499 and save them into the 500 SDL_Point records of the “sdlPoints” array.

Colour black is set by SDL_SetRenderDrawColor().

To draw the lines which connects the points in the array “sdlPoints” we use SDL_RenderDrawLines(renderer, pointer to point array, number of array elements). First you need to set the renderer, then just a pointer to an array of TSDL_FPoint and finally the number of points. The latter should be consistent with the array. So, if your array has 500 elements, the count should be 500 at maximum. Notice how we are not using a loop here to draw all 500 lines by calling a certain draw function 500 times, which is a slow solution. Instead we just pass an array of points once. This way we save a lot of time at runtime, especially if you think of a real application where even more lines have to be drawn. There are similar functions for points, rectangles and filled rectangles. They are not used in the example but it may be interesting to know, so here they are:

  • SDL_RenderDrawPoints(renderer, pointer to points array, number of array elements)
  • SDL_RenderDrawRects(renderer, pointer to rectangles array, number of array elements)
  • SDL_RenderFillRects(renderer, pointer to rectangles array, number of array elements)

As a hint, try replacing SDL_RenderDrawLines by SDL_RenderDrawPoints.

Often, you will have functions in SDL3, where you can use batches of something

Drawing Rectangles in SDL3

  //prepare, render and draw a green rectangle outline at upper-right corner
  sdlRect1.x := 260;
  sdlRect1.y := 10;
  sdlRect1.w := 230;
  sdlRect1.h := 230;
  SDL_SetRenderDrawColor(sdlRenderer, 0, 255, 0, SDL_ALPHA_OPAQUE);
  SDL_RenderRect(sdlRenderer, @sdlRect1);

The drawing colour is set to green by SDL_SetRenderDrawColor() and a rectangle’s outline is drawn by SDL_RenderDrawRect(renderer, pointer of rectangle). Prior to using a rectangle we define it at position (260/10) with 230 pixels width and 230 pixels height.

It requires the renderer, which is “sdlRenderer” for us and a PSDL_Rect , thus we use the @-operator for the declared rectangle of TSDL_FRect type to get its pointer value. Notice, we neither render the result to the screen now nor do we delay here. We want a second rectangle immediately! 🙂

  //render and draw the rectangle with 50% opacity at lower-left corner
  sdlRect1.x := 10;
  sdlRect1.y := 260;
  SDL_SetRenderDrawBlendMode(sdlRenderer, SDL_BLENDMODE_BLEND);
  SDL_SetRenderDrawColor(sdlRenderer, 0, 255, 0, 128);
  SDL_RenderFillRect(sdlRenderer, @sdlRect1);
  SDL_RenderPresent(sdlRenderer);
  SDL_Delay(1000);

We change the rectangles (x/y) coordinate for the second rectangle to (10/260), but keep its width and height the same. What we are looking for is a filled rectangle that has some transparency. Until now we always used SDL_ALPHA_OPAQUE (opaque) as alpha value. We keep the colour to draw the second rectangle to green by SDL_SetRenderDrawColor(). Notice that the fourth value is 128 (half-transparent) instead of the opaque constant. So everything behind the green rectangle should therefore shine through. To generate a filled rectangle SDL_RenderFillRect(renderer, pointer to rectangle) is used.

The Blend Mode in SDL3

But to be honest, even if you change the alpha value it will be opaque, unless you change the blend mode, which we did by SDL_SetRenderDrawBlendMode(renderer, blend mode). The default settings don’t allow for blending. We need to change this to be able to use the alpha value as desired.

First the renderer for which the blend mode has to be set is chosen. In our case it is “sdlRenderer” again. Then there are seven blend modes available in SDL3 and they determine how the new colours are combined with the already present colours at a certain pixel coordinate. Here is an overview of the four most important ones:

  1. SDL_BLENDMODE_NONE
    • no blending
    • dstRGBA = srcRGBA
    • the final pixel colour is just the new pixel colour
  2. SDL_BLENDMODE_BLEND
    • alpha blending
    • dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA))
    • dstA = srcA + (dstA * (1-srcA))
    • the final pixel colour is an addition of the previous pixel colour the new pixel colour; the ratio is determined by the alpha value
  3. SDL_BLENDMODE_ADD
    • additive blending
    • dstRGB = (srcRGB * srcA) + dstRGB
    • dstA = dstA
    • the final pixel colour is an addition of the previous pixel colour and the new pixel colour; only the previous pixel colour is affected by the alpha value though
  4. SDL_BLENDMODE_MOD
    • color modulate
    • dstRGB = srcRGB * dstRGB
    • dstA = dstA
    • the final pixel colour is a multiplication of the previous and the new pixel colour

We are looking for (common) alpha blending, so we use SDL_BLENDMODE_BLEND as argument for the blend mode.

After doing so the result is rendered to the screen by SDL_RenderPresent() and shown for one second by SDL_Delay(). Both rectangles appear at the same time.

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

  //shut down SDL3
  SDL_Quit; 

Finally all the memory reserved for points, the rectangle, the renderer and the window is free’d and SDL3 shut down by SDL_Quit.

Congratulations, you just finished this chapter :-).

Previous Chapter | Next Chapter

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

First Steps Feature Image SDL3

First Steps with SDL3


Let’s jump right into our first SDL3 application. Every SDL3 application needs to include the SDL3 unit (obviously), because it is that unit which provides all the SDL3 functions and types we use for development.

program FirstSteps;

uses SDL3;

begin

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

    {your SDL2 application/game}
    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, 'First Steps', 'It works!', nil);

  //shutting down video subsystem
  SDL_Quit;

end.

Initialization and Quitting of SDL3

The first function we use is called SDL_Init(subsystem flags). It is used to initialize subsystems of SDL3 and must be called always before using any SDL3 features. These subsystems are:

  • SDL_INIT_AUDIO
  • SDL_INIT_VIDEO
  • SDL_INIT_JOYSTICK
  • SDL_INIT_HAPTIC
  • SDL_INIT_GAMEPAD
  • SDL_INIT_EVENTS
  • SDL_INIT_SENSOR
  • SDL_INIT_CAMERA

The names are self-explanatory, so if you need video functionality you set SDL_INIT_VIDEO. If you need audio functionality, you set SDL_INIT_AUDIO. You can combine subsystems by using the logical or. For video and audio functionality you use SDL_INIT_VIDEO or SDL_INIT_AUDIO.

By the way, with the exception of the haptic flag, all flags do imply the event system, so you don’t need to load it.

You may have wondered why the SDL_Init function is buried in the if-statement. Most functions in SDL3 return a boolean return value which indicates if its execution was successful. This allows for efficient error checking as seen here. If the SDL_Init is returning true the applications proceeds, if not it would exit immediately.

When quitting your application, use the SDL_Quit function.

A simple message box, because we can!

If you see a message box like this…

… then everything works alright. Otherwise, something is is wrong. Most probably the SDL3 library hasn’t been found.

And here you see one great benefit of SDL3. The message box is generated by exactly one simple call to the SDL_ShowSimpleMessageBox(message box flags, title, message, window) function. To realize the same, not to mention on different platforms in a platform-independent way, is whole other question and takes much greater effort.

SDL3 simplifies your (game) development endeavor by a giant margin in many respects.

Previous Chapter | Next Chapter