Tag Archives: SDL

[OpenGL part 5] Matrix operations ( translate, scale, rotate )

Introduction to Matrix Operations


In this part, we’ll be looking at basic matrix math. We’ll be looking at how we create the various transformation matrices that we use for rotating, moving and scaling. If you really want, you can skip to the second part where we look at some code and let glm do the maths for us. But I really recommend actually learning the basics of matrix operations.

Matrices


Matrices are basically small tables of numbers. They are used in graphics programming when transforming vectors and object. We use them to move, rotate and scale objects. The math behind them is relatively simple though some of it can be hard to wrap your mind around first. And there are several mistakes that are easy to make and very hard to debug, so it’s very useful to know a bit about them and how they work.

The basics


In all simplicity, a matrix is just a table of numbers. Like the one you see below. With it comes a lot of simple operations we can do to transform objects ( like we saw with the model/view/projection matrix in the last part. But even though the idea is simple and the operations are basic ( usuaully just addition and multiplication ), they can quickly become confusing

\begin{bmatrix} 1\quad0\quad0\quad0 \\0\quad1\quad0\quad0 \\0\quad0\quad1\quad0\\0\quad0\quad0\quad1\end{bmatrix}

The unit matrix


What you see above is what we call the “unit matrix”. You can look at this like the base matrix or the null matrix. The idea behind it is that anything you multiply it with will remain the same ( we’ll look at this soon. ) That makes the unit matrix the starting point as well as it’s used in a few different, more complex matrix expression.

Matrix – vector multiplication


The simplest operations we’ll be looking at, is multiplying a matrix with a vector. This is quite straight forwards, though there will be a lot of numbers to keep track of so read through it a few times and get comfortable with it before proceeding. The formula for multiplying a 3×3 matrix with a 3d vector is as follows :

Let’s isolate just the top row ( all rows are multiplied in the same way )

We can multiply 4×4 matricies and verticies like this :

Step-by-step guide


  1. Look at first row
    1. Multiply first matrix value on that row with first vector value (x)
    2. Multiply second matrix value on that row with second vector value (y)
    3. Multiply third matrix value on that row with third vector value (z)
    4. Continue until no more more numbers on that line of the matrix
    5. Add all the numbers together
  2. Repeat for next row until no more rows
  3. Done!

You might have noticed that this requires that the number of values in each row of the matrix is the same as the numbers of values in the vector. If we have 3 values in each row of the matrix, the vector needs to have 3 values as well. This isn’t really an issue for us, so we won’t be looking at these cases here.

The unit matrix


As mentioned earlier, the unit matrix won’t change anything we multiply by it. We can see this by doing a multiplying with placeholder values for x, y, z and w

So now that we’ve learned how to do multiplication, let’s test it out and see if it’s really true! Let’s try to multiply it by the vector 1.03, -4.2, 9.81, 13 :

As you can see, we end up with the same as we began with, 1.03, -4.2, 9.81, 13.

Matrix – matrix multiplication


Multiplying a matrix with a vector was quite easy. Now let’s make things a tiny bit more difficult and multiply a matrix with a different matrix. This is one of the most important basic operations we need to do. It plays a huge role in moving/scaling/rotating objects. And, as we’ll see in a later part, it’s a very important part of lighting.

Matrix multiplication depends a bit on the sizes of the two matrices. But we’ll simplify it to say that we’ll always be working with unifrom matrixes ( 2×2, 3×3, 4×4 ). Firstly, lets look at the generic formula :

Now this seems a bit complicated, so let’s look at how to calculate just the first number :

matrix multi first cell

As you can see, for the first part of the multiplication we use the first numbers of both matrices ( A11 and B11 ). But for the second number, we use the next number in the same row for matrix A ( A12 ) and the next number in the same column for matrix B ( B21) This pattern repeats for the next number on that row like this :

matrix multi second cell

Now we move to the next row and repeat the process :

matrix multi third cell

And finally, the last cell :

matrix multi fourth cell


This can also be extended to a 3×3 matrix like this

This is a lot of numbers, but if you look closely, you’ll see it’s a lot like the previous one, only with an extra number on each row and column. So in this case, for the first number, all we did was add + a13 * b31 to the original operation ( which was a11 ∗ b11 + a12 * b21 ) For the second number on the top row we added + a13 ∗ b32 to the original operation. The third number on the top row is new but it follows the same pattern;

For all the numbers on the same row from matrix A

a11, a12, a13

and all the numbers in the same column from matrix B

b13, b23, b33

multiply each pair in the same position and add them together.

a31∗b13 + a32∗b23 + a33∗b33

The unit matrix again


Now let’s try multiplying a vector with the unit matrix again. We should get the same result as we started with, but let’s see…

Success! This product is exactly the same as we started with!

Ordering matters


A very important part of matrix operations is the ordering. Normally in mathematics the ordering is not important. When it comes to simple multiplication it does not matter what order you multiply two numbers 123 * 321 gives the exact same result as 321 * 123. But when it comes to matrices, this is not true. Let’s look at a very simple example :

But if we flip the ordering…

..we end up with something completely different.

Because of this, it is important to keep track of the ordering, otherwise, you’ll end up spending hours debugging!

Using matrices to change vertexes


Now that we’ve learned about the basic math about matrices, it’s time to learn how to use them. We’ll be using them to move, scale and rotate objects. We do this by multiplying each vertex by a matrix. After multiplying the vertex, we get a new vertex back that has been moved/scaled/rotated. After doing this to all the vertexes of the object, the entire object will have been moved/scaled/rotated. Creating these matrices is quite easy though there will be a few numbers to keep track of. Let’s look at the operations one by one.

Moving (translating)


The matrix we use for moving an object is quite simple. It is defined like this :

\begin{bmatrix}
\,\ 1\quad 0\quad 0\quad dx\\
\,\ 0\quad 1\quad 0\quad dy\\
\,\ 0\quad 0\quad 1\quad dz\\
0\quad 0\quad 0\quad 1\\
\end{bmatrix}

Where dx is movement in x direction, dy is movement in y direction and dz is movement in z direction. So in effect, we get this matrix :

\begin{bmatrix}
1 & 0 & 0 & \phantom{-}9.2\\
0 & 1 & 0 & \phantom{-}1.2\\
0 & 0 & 1 & -3.7\\
0 & 0 & 0 & \phantom{-}1\\
\end{bmatrix}

Will move the object 9.2 in the x direction, 1.2 in the y direction and -3.7 in the z direction.

Now this might look a bit familiar. Let’s compare it to the unit matrix :

\begin{bmatrix}
1 & 0 & 0 & 0\\
0 & 1 & 0 & 0\\
0 & 0 & 1 & 0\\
0 & 0 & 0 & 1\\
\end{bmatrix}

That’s right. It’s the same except the dx, dy and dz part. This will come into effect when we do the actual translation.

Since we are using a 4×4 matrix, it is easier to use 4d vector. But that raises a new question; what about the last value? The x, y and z is, of course, the position. But there is a final number we haven’t cared about yet. As it turns out, this has to be 1 we’ll find out why now.

Let’s look at an example. Say we have the vector [11, 1.5, -43] first we need to add the last digit, 1 so we end up with :

\begin{bmatrix}
\phantom{-}11\\
\phantom{-}1.5\\
-43\\
1
\end{bmatrix}

Now for the translation matrix. Let’s use the one from above which will move the object 42 in the x direction, 19 in the y direction and -13 in the z direction.

\begin{bmatrix}
1 & 0 & 0 & \phantom{-}9.2\\
0 & 1 & 0 & \phantom{-}1.2\\
0 & 0 & 1 & -3.7\\
0 & 0 & 0 & \phantom{-}1\\
\end{bmatrix}

Finally we can try the translation. Translating an object is simply just multiplying the vertex and the translation matrix :

This might seem like a bit of over complication. Why not just add the numbers? Just adding the numbers would be practical if we were just moving the object. But we can do other things like scaling and rotating. By using a matrix, we can combine all of these into a single operation. So let’s look at the next operation, scaling.

Making things bigger or smaller (scaling)


The second operation we’ll look at is how to make objects larger or smaller. This is quite similar to translating objects. For scaling we have the base matrix:

\begin{bmatrix}
sx & 0 & 0 & 0\\
0 & sy & 0 & 0\\
0 & 0 & sz & 0\\
0 & 0 & 0 & 1
\end{bmatrix}

And just like with translation matrices, we multiply our vector with this matrix to get the scaled vector back.

Here sx, sy, sz are the scale factors, which are the numbers we need to multiply with in order to get the result :

  • If you don’t want to scale it all all, you se the scale factor to 1.
  • If you want to double the size you have a scale factor of 2, for trippling you have 3, etc…
  • If you want to make it 50% larger, you have a scale factor of 1.5, 25% larger the scale factor is 1.25, etc…>
  • If you want to halve it, you have a scale factor of 0.5, make it 75% smaller the scale factor is 0.25, etc…

Let’s first look at an example:

Say we have the vertex [2.1, 3.4, -9.5] and we want to scale it like the following :

  • Make it 70% smaller in x direction
    • Scale factor becomes 1.0 - 0.7 = 0.3
  • Make it 80% larger in y direction
    • Scale factor becomes 1.8
  • Triple the size in z direcion
    • Scale factor becomes 3.0

This gives us the scale factors [0.3, 1.8, 3.0 and the vertex [2.1, 3.4, -9.5]. Let’s plot these into the matrix operation:

This gives us the scale factors [0.3, 1.8, 3.0 and the vertex 0.63, 6.12, -28.5]… Which tells us that the vertex has been moved :

  • Closer to the center in x direction ( becasue object get smaller in x direction )
  • A little further away from the center in y direction ( which means the object gets larger in y direction )
  • A lot further away from the center in z direction ( getting a lot larger in z direction )
  • And if we apply this to all the vertices in an object, we find that the center of the object remains the same, so we’re not actually moving the object, we’re just moving the individual vertices. Closer to or further away from the center.

    Rotating


    Now this is where things get a little complicated. We need to translate the object using numbers calculated using sin and cos. The formula for calculating the rotated x and y is as follows :


    x2 = cos β * x1 − sinβ * y1
    y2 = sin β * x1 + cosβ * y1

    I won’t go into details about why this formula works, but you can read about it here.

    Specifying axis


    In order to rotate a 3d object, we need an axis to rotate it around. Take a look at the dice below :

    It is laid out like the following :

    Now imagine we want to rotate it so that we see other numbers. In order to do this, we need an axis to rotate it around. Imagine we stick a toothpick throw this dice from 5 to 6 like the following :

    Now we can rotate the dice 90° down and we end up with something like this :

    [Note: If anyone has any tips or can in any way help me improve these illustrations, it’d be much appreciated]

    The math


    When it comes to the actual math, it’s a bit more complicated. I won’t be explaining where we get the matrices for rotation, but if you’re interested, you can read more about it here.

    Like with translating and scaling, we use a matrix to do the rotation. But the matrix itself is a bit complex and is a little different depending on which axis you rotate :

    For X axis

    \begin{bmatrix}
    1 & \phantom{-}0 & 0 & 0\\
    0 & \phantom{-}cos\phantom{-}θ & sin\phantom{-}θ & 0\\
    0 & -sin\phantom{-}θ & cos\phantom{-}θ & 0\\
    0 & \phantom{-}0 & 0 & 1\\
    \end{bmatrix}

    For Y axis

    \begin{bmatrix}
    cos\phantom{-}θ & 0 & -sin\phantom{-}θ & 0\\
    0 & 1 & 0 & 0\\
    sin\phantom{-}θ & 0 & \phantom{-}cos\phantom{-}θ & 0\\
    0 & 0 & 0 & 1\\
    \end{bmatrix}

    For Z axis

    \begin{bmatrix}
    cos\phantom{-}θ & -sin\phantom{-}θ & 0 & 0\\
    sin\phantom{-}θ & \phantom{-}cos\phantom{-}θ & 0 & 0\\
    0 & 0 & 1 & 0\\
    0 & 0 & 0 & 1\\
    \end{bmatrix}

    Why are they so different


    The reason why they are different is how they multiply with the unit matrix

    \begin{bmatrix}
    1 & 0 & 0 & 0\\
    0 & 1 & 0 & 0\\
    0 & 0 & 1 & 0\\
    0 & 0 & 0 & 1\\
    \end{bmatrix}

    You’ll see that the formula for rotating around the x axis :

    \begin{bmatrix}
    1 & \phantom{-}0 & 0 & 0\\
    0 & \phantom{-}cos\phantom{-}θ & sin\phantom{-}θ & 0\\
    0 & -sin\phantom{-}θ & cos\phantom{-}θ & 0\\
    0 & \phantom{-}0 & 0 & 1\\
    \end{bmatrix}

    Has the same first column and row [1, 0, 0, 0] as the unit matrix. If you look at how matrices are multiplied, you’ll see that this won’t change the final x coordinate

    And if you look at the matrices for rotating around y and z, you’ll see the same. The y rotation matrix has the same second column and row as the unit matrix [ 0, 1, 0, 0 ] and the one for z axis has the same third column and row as the unit matrix [ 0, 0, 0, 1]. This means that rotating around z axis doesn’t change the z coordinate, and rotating around the y axis doesn’t change the y coordinate

    Imagine putting a dice on a table. Now turn the dice clockwise or counter-clockwise without lifting the dice in any way. If you define the z axis to be the height above the table, you’re now rotating the dice around the Z axis. And since you’re not lifting it, the z coordinate remains the same.

    Example


    Let’s make a matrix for rotating the point [2,4, 8] by 30 degrees around the x axis.

    As you can see, the y and z coordinates have changed, but the x coordinate is the same. This is due to how matrix multiplication work.

    Other axis


    You might wonder; what if I want to move the object around a combination of two or three axes? Well, that’s a bit more complex, and I won’t go into the math here. But we’ll see how we can use glm to specify an exact axis of rotation below

    Putting it all together


    Before we look at how to do these operations using code, we need to look at how to do it by hand. Or by online matrix calculators in this case… Buy why? As I mentioned earlier, ordering is important here. Do things in the wrong order, and you get weird results.

    In the previous post, we looked at object space, world space, view/camera space camera and projection space. Let’s skip the last two for now and focus on the object and world space.

    Remember that object space is basically the model represented as a set of coordinates around origin [0, 0, 0] and that world space is the position of the object in the game world. So if the object has moved 10 units to the right, it’ll have the position [0, 10, 0] which means we have to move it there. This is where the translation matrix comes in! The object could also have turned around ( rotated ) and grown (scaled). Since the object is defined in object space ( vectors around [0,0,0] ) and this will never change, we need to move/scale and rotate the object every time. So we need to multiply every coordinate with this matrix in order to place/scale/rotate it correctly.

    Luckily we can just multiply the matrices together and reuse this matrix until the object moves. But this is also where we need to be careful about getting the orientation right. Let’s start by moving and scaling.

    Example – Wrong way


    Say we want to scale by 2 units in every direction and move 3 unites in every direction. Remember that the scale matrix looks like this :

    \begin{bmatrix}
    sx & 0 & 0 & 0\\
    0 & sy & 0 & 0\\
    0 & 0 & sz & 0\\
    0 & 0 & 0 & 1
    \end{bmatrix}

    Filling in numbers :

    \begin{bmatrix}
    2 & 0 & 0 & 0\\
    0 & 2 & 0 & 0\\
    0 & 0 & 2 & 0\\
    0 & 0 & 0 & 1
    \end{bmatrix}

    And translation matrix

    \begin{bmatrix}
    \,\ 1\quad 0\quad 0\quad dx\\
    \,\ 0\quad 1\quad 0\quad dy\\
    \,\ 0\quad 0\quad 1\quad dz\\
    0\quad 0\quad 0\quad 1\\
    \end{bmatrix}

    Filling in the numbers, we get :

    \begin{bmatrix}
    \,\ 1\quad 0\quad 0\quad 3\\
    \,\ 0\quad 1\quad 0\quad 3\\
    \,\ 0\quad 0\quad 1\quad 3\\
    0\quad 0\quad 0\quad 1\\
    \end{bmatrix}

    Now let’s multiply them :

    Let’s analyse this. Looking at the scale numbers, we see 2, 2, 2 as we expected. But when we look at the translation, we see 6, 6, 6! That’s wrong! We wanted 3, 3, 3, not 6, 6, 6!

    The reason why this happens is that we multiplied by scale first when we should have started with the translation instead. So let’s reverse the order of the operations and try again

    That’s more like it. We see that we move by 3 and scale by a factor of 2.

    When we add rotation, we can run into the same problem. Imagine if the object is first moved, then rotated we would still move around the origin(0,0,0). But since we already have moved the object away from the origin, we’ll orbit the origin ( much like a planet ) instead.

    The correct order


    In our example ( and in most cases ) the correct order is scale -> translate -> rotate. You might think it would be the other way around, but matrix operations are in the opposite order of what you expected. So you start out with the last thing you want to happen ( scale ) and end with the first (rotate)

    Using glm to do matrix operations


    Luckily, we don’t have to do all of this ourselves. In fact, glm does nearly all the math for us. Including rotation ( fortunately )All of these methods takes a glm 4×4 matrix, called mat4 this is basically just a 4×4 array representing a matrix.

    You can find the documentation here.

    glm::translate


    Takes a matrix, translates it and returns it.

    Parameters :

    • glm::mat4 original – the matrix you want to translate
    • glm::vec3 dist – the distance to move

    Return :

    The original matrix original translated by dist like we looked at earlier

    glm::scale


    Takes a matrix and scales it and returns it

    Parameters :

    • glm::mat4 original – the matrix you want to scale
    • glm::vec3 scale – the factors to scale by

    Return :

    The original matrix original scaled by scale matrix like we looked at earlier

    glm::rotate


    Takes a matrix and rotates it around an axis and returns it

    Parameters :

    • glm::mat4 original – the matrix you want to scale
    • double angle – the amount/angle you want to rotate by ( radians )
    • glm::vec3 axis – the axis to rotate by

    Return :

    The original matrix original rotated by angle around the axis, axis like we looked at earlier

    Putting it all together


    Now that we have looked at the functions, we can easily put them all together.

    This is a simple class that shows how you can use all the operations we’ve looked at.

    File notes


    You can find the source code for an application that lets you move/scale/rotate a cubehere.

    Images with colored matrix/vector multiplications has been made using calcul.com

    Dice illustration has been made using Inkscape


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share

    [ SDL2 – Part 11 ] Text styling

    Text styles using SDL2_ttf


    In the last post we looked at how to render text. Now let’s take this a step further and change the appearance of the font. There are two ways you can change how the font looks. Font style and font outline.

    Fon styles


    SDL TTF allows you to set the style of the font. It supports the following font styles

    • bold
    • italic
    • underlined
    • strikthrough

    You can combine these in any way you like. We’ll start off with just setting a single font style at a time, and then move on to see how we can apply several of them at once.

    Font styles


    Settnig font styles in TTF is easy, it just requires a single function. The function let us you set one or more font styles. Let’s start off by looking at how to set just one font style

    Setting the font style


    We can set the font style using the following function

    Arguments :

    •  TTF_Font *font – the font to set the style on
    • int style       – the style to set on the font

    As you can see, the style parameter is an int and not an enum. I’ll get back to why that is later, but for now let’s look at the possible values for style, these are all self-explanatory so I won’t be adding a description.

    • TTF_STYLE_NORMAL
    • TTF_STYLE_BOLD
    • TTF_STYLE_ITALIC
    • TTF_STYLE_UNDERLINE
    • TTF_STYLE_STRIKETRHOUGH

    Any text you render after setting this font style will have the new effect, but it won’t change any text you have written with a different style. So when you set the style to TTF_STYLE_BOLD, all text you render from that point and until you set a different style will be bold. And as long as you pass any of the above values to the function, the font will only have the one last style you set.

    Let’s do a simple example

    Any text rendered at this point will be normal with no font styles


    Any text rendered at this point will be bold


    Any text rendered at this point will be in italics, but not bold


    Any text rendered at this point will be normal with no font styles


    Any text rendered at this point will be underlined


    As you can see, this is pretty straight forwards. So let’s make things a little bit trickier by setting multiple font styles at once. To do this, we must first look a bit at the binary number system

    Binary numbers


    In order to learn about how to combine these flags, we need to look at binary numbers first of all. If you don’t already know about binary numbers, you should take a look at the above link. It’s not crucial, but it is highly recommended to know a little about them. I might create a blog post about them at some point. For now, I’ll just talk a tiny bit about the binary number system. But as I said, I highly recommend understanding it fully to the point where you can convert back and forth between binary and decimal numbers

    The binary number system


    On a daily basis, we use the decimal number system. The binary numbers system is just a different way of representing numbers. Any numbers can be converted from any other number system. So you can convert binary numbers to decimal numbers ( and the other way around ).

    A computer stores numbers as individual bits ( 0‘s and 1‘s ). They correspond to on / off or true / false.

    Let’s take a look at an 8 bit binary number ( 1 byte )

    1010 0101

    As you can see, it has 8 digits. So that’s eight different flags. Each of these flags have two different possible values : 0 / 1 or false / true. So that’s 8 bools for the price of a single byte!

    Bitwise operations


    So how do we use these 8 booleans? As you know, we have the following boolean operations in C++:

    • and ( && )
    • or ( ||

    These work on an entire variable. An int, for instance will be false if its value is 0, otherwise its true.

    But there are similar operations that does this on all bits of a variable. These are called bitwise operations, simply because they operate on a simple byte. To do a bitwise operation, we need two variables of equal size ( same number of digits ), for instance two bytes. The result of a bitwise operation is a third variable of the same size. So if we do a bitwise operation between two bytes, we get a third byte back as a result.

    Let’s create two bytes, we’ll use these for a few examples

    Byte 1 : 0101 0011 ( 64 + 16 + 2 + 1 = 85 )
    Byte 2 : 0110 0010 ( 32 + 64 + 2 = 98 )

    We’ll be referring to each digit as a position. So the digits in the first position is 0 in both or bytes. In the second position it’s 1 in both bytes and in the third it’s 0 in the first byte and 1 in the second byte.

    Bitwise OR


    A bitwise OR operation means we look at all positions as check if either of them is 1 if so, we set the digit in that position to 0. If no digit in that position is 1, we set it to 0

    The operator for bitwise OR in C++ is | ( just one |, not two )

    Here is a simple example of bitwise OR between two bytes

    0101 0011
    OR
    0110 0010
    =
    0111 0011

    Bitwise AND


    In a bitwise AND operation, we look at each position and see if both of them are 1. If so, we set the digit in that position to 1, otherwise we set it to 0. So in OR we set it to 1 if any of the two is 1, here we only set it to 1 if both are 1.

    The operator for bitwise AND in C++ is & ( just one &, not two )

    Here’s the a simple example :

    0101 0011
    AND
    0110 0010
    =
    0100 0010

    Bitwise XOR


    XOR or exclusive OR is slightly less known than OR and AND. In an XOR operation, we check if the two values are different. So this is equivalent to != in C++.

    • ( true  != false ) = true
    • ( true  != true  ) = false
    • ( false != true  ) = true
    • ( false != false ) = false

    Simply put, an XOR operation is true if the two parts are different. So in a bitwise XOR operation, we look at each position and see if the two digits are different. If so we set the digit at that position to 1, otherwise we set it to 0.

    The operator for bitwise XOR in C++ is !=

    Here is an example :

    0101 0011
    XOR
    0110 0010
    =
    0011 0001

    Bitwise NOT


    We also have the a bitwise version of the NOT opeartion this is done by using the ~ operator in C++. If we used ! we would get the result of NOT on the entire variable, not the individual bits which is what we want. This operation only takes a single element and flips all bits ( turns 1‘s into 0‘s and 0‘s into 1‘s. ). Let’s test it on our two bytes

    The operator for bitwise NOT in C++ is !

    Byte 1 :

    NOT 0101 0011
    =   1010 1100

    Byte 2 :

    NOT 0110 0010
    =   1001 1101

    Setting and checking individual bits


    So now that we know how to do bitwise operations, we need a way of checking and setting the individual bits. This is done simply by using OR, AND and XOR. Before we take a look at how to do this, let’s define a few values to check.

    Remember that the different font styles are ints? This is because they are used to perform bitwise operations to set and unset different bits. Here they are again, this time with their values. For simplicity, I’ll only list the last four bits ( the others are always 0 ). The values are in decimal with the binary representation in parenthesis

    • TTF_STYLE_NORMAL = 0 ( 0000 )
    • TTF_STYLE_BOLD = 1 ( 0001 )
    • TTF_STYLE_ITALIC = 2 ( 0010 )
    • TTF_STYLE_UNDERLINE = 4 ( 0100 )
    • TTF_STYLE_STRIKETRHOUGH = 8 ( 1000 )

    As you can see, they all have only one ( or zero ) bit set. This means we can use AND, OR or XOR on just one bit.

    Setting a bit


    To set a bit ( without affect any other bit ) we use the ORoperation. So say that we have four bits set to 0, 0000 and we want to set the bit for bold on it ( 0001 ). In other words, we want the result 0001. What we do is : that we take our original 4 bits ( 0001 ) and set it to the original 4 bits ( 0001 ) OR‘ed with the bitmask for bold ( 0001 ) :

    0000
    OR
    0001
    ( value of TTF_STYLE_BOLD )
    =
    0001

    Simple as that! This woks for any of the other flags in the same way. They all will end up setting one bit.

    Note that this will not change any other bits. If we try set the italics font style on the above variable we get :

    0001
    OR
    0010
    ( value of TTF_STYLE_ITALIC )
    =
    0011 ( TTF_STYLE_BOLD and TTF_STYLE_ITALIC set )

    Let’s make a simple function that adds a style to a mask.

    Unsetting a bit


    Sometimes we want to unset a bit. Say for instance we want to remove the italics from the font above. How do we do that without affection the other values? This is a bit more complex, because it requires two operations. What we are trying to do is the following :

    Say we have a bitmask ( 0000 1011 ) and we want to unset the bit for bold text, but leave the rest unchanged. So we need to be able to go :

    From 1011 to 1010

    To do this, we need to use an AND operation. This is because we can’t turn of a bit using OR, and XOR would only flip it back and forth between 0 and 1

    But we can’t use AND with the flag we want to unset alone, because that would keep the flag at 1 and change every other to 0!

    0000 0101
    AND
    0000 0001
    =
    0000 0001

    This is the opposite of what we want! Wait? Opposite you say? Well how about we use the NOT operator here to get the opposite result? This works perfectly, because NOT 0000 0001 is 1111 1110. And, as we saw earlier, doing AND 1 won’t change the element we’re AND‘ing with. So we get :

    0000 0101
    AND
    1111 1110
    =
    0000 0100

    Success! Only the bit we were trying to unset has changed. So let’s make a function that does this for us :

    Checking a bit


    To check a bit, we also need to use the bitwise AND operation. And since we are only checking and not setting, we don’t have to store the value anywhere which means we don’t have to worry about changing anything.

    To check a bitmask, simply do an AND operation with the value you want to check for ( in this case, any of the TTF_STYLE_.... values ). So, to check if a text is bold, we do an AND between our mask and TTF_STYLE_BOLD :

    0011 ( our bit mask, TTF_STYLE_BOLD and TTF_STYLE_ITALIC set )
    AND
    0001
    =
    0001

    As you can see, we only check the bit that’s set in our variable ( TTF_STYLE_ITALIC set ) the others will be 0 no matter what our mask is. The value 0001 is not 0, and thus this evaluates to true and we now know that the font is bold.

    If our mask didn’t have the bold bit set ( only the italic one ), our mask would be 0010. An AND between 0010 AND 0001 is false ( they have no bit set to 1 in common ) and the result is 0 aka false.

    So let’s create a function for that too!

    Conclusion


    With a little knowledge about binary numbers and bitwise operations, we can easily set, add, remove and check various font styles in SDL_TTF.

    Since it does involve a little low level code, I made a simple class that does the apparitions for us in a more intuitive way. I strongly suggest using this opposed to “raw” TTF_Fount*


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share

    [ SDL2 – Part 10 ] Text rendering

    Rendering text


    In the previous parts, we’ve look at how to render rectangles and images, both with and without transparency. Now it’s time to look at how we can render text.

    Rendering text is tricky. You’ll want to be able to render any font, in any size and preferably every possible character. Luckily, with the SDL_ttf library, this is easy.

    SDL2_ttf


    SDL2_ttf, just like SDL2_image, is an additional library for SDL2. It can use just about every font, and you can set the size and text styling too!

    What’s TTF?


    TTF, or TrueType Fonts is a type of fonts developed by Apple and Microsoft in the late 90’s. True Type Fonts offers a high degree of control on how the font looks. The internals of TTF fonts and how they work isn’t important here. The important part is that they’re easy to use, will look really nice ( even scaled up. ) And they’re also widely used, so finding fonts shouldn’t be a problem.

    SDL2 TTF?


    As with SDL2_image, SDL2_ttf is an additional library for SDL2 that deals with rendering text and makes it very easy. It is based on libfreetype, a library for writing text using TTF fonts. However, it’s not very practical to use. SDL2_TTF makes using it a lot easier. But if you do want to use it yourself, you can take a look at their tutorial.

    Setting up SDL2_TTF


    Setting up SDL2 requires a tiny bit more work than SDL2_image, but don’t be scared, it’s still very easy. First we need to install the ttf library.

    Installation


    Installing SDL2_ttf is done exactly like SDL2_image. Just replace SDL2_image with SDL2_ttf

    Here’s the short version :

    Linux


    For Linux you can use need to install -lSDL2_ttf or -libSDL2_ttf or -SDL2_ttf ( the actual name might be different in different distributions. )

    The linker flag is -lSDL2_ttf

    The process is more or less identical to that of setting up SDL2_image.

    If you can’t find SDL2_ttf in any repositories and it’s not installed by default, you might have to compile it yourself. For more information, see my blog post about setting up SDL2.

    Windows


    Similar to setting up SDL2 base.

    The difference is that you have to download the development files for SDL2_ttf

    And similarly add SDL2_ttf.lib to library includes and add SDL2_ttf.lib to the library flags ( where you previously added SDL2_image.lib )

    And with that, it should work.

    Mac


    See the first part of my tutorial. Just install SDL2_ttf instead of SDL2

    Initialization


    Unlike SDL2_image does need to be initialized. Why? Because libfreetype, the library that SDL2_ttf builds upon needs to be initialized, so naturally SDL_ttf needs to be initialized too.

    Initializing SDL2_ttf requires a single function, TTF_Init() :

    Just like SDL_Init(Uint32 flags) this function returns -1 on error, but unlike SDL_Init(Uint32 flags), this method does not have any flags.

    Sine this function can fail and return -1, we should print an error if this happens. This means our routine for initializing SDL2_ttf will be the similar to SDL2, just with the two functions above :

    TTF_Font


    The basic object for SDL_TTF is TTF_Font. A TTF_Font basically holds information about a font like the font itself and data about styling and size. The exact internals of TTF_Fonts is only known to the library using it so I won’t go into depths about it.

    The only thing you need to remember about TTF_Fonts is that they hold all information about the font that SDL_TTF needs to render it, and that they need to be loaded and unloaded ( we’ll look at this later. )

    Loading fonts


    This is the central structure of SDL2_ttf. It holds the font itself, the size and some other style information ( I’ll go into this in the next part ). So, in order for us to use an TTF_Font we need to load it. This is done using a load function :

    Arguments :

    • const char *file – a pointer to the .ttf file
    • int ptsize – the size of the font

    Return value :

    A pointer to the created TTF_Font<

    The function returns a NULL pointer of it can’t find the file, or there is another error ( like SDL2_ttf isn’t initialized. So this too should be handled by priting the error using SDL_GetError(), just like when initializing ttf

    Cleaning up fonts


    Just like we with SDL_Texture* and SDL_Surface*, we need to clean our fonts when done. This is just as easy for TTF_Fonts as with SDL_Texture* and SDL_Surface*. We simply call a function that does it for us :

    Rendering text


    There are three functions you can use to render text, depending on what you want. Let’s start with the first one :

    TTF_RenderText_Solid


    This function is used for quick and simple rendering of a text, using a specific font and a font color. The background of this is transparent. Here’s the signature:

    Arguments :

    •  TTF_Font *font – the font to use
    • const char *text – the text to render
    • SDL_Color fg –  the color to use for the text

    Return value :

    A SDL_Surface with the rendered text

    The function returns a NULL pointer of it can’t find the file, or there is another error ( like SDL2_ttf isn’t initialized. So this too should be handled by priting the error using SDL_GetError(), just like when initializing ttf

    The result will look something like this :

    TTF_RenderText_Blended


    The next function is very similar to the previous one

    Arguments :

    •  TTF_Font *font – the font to use
    • const char *text – the text to render
    • SDL_Color fg –  the color to use for the text
    • SDL_Color fg –  the color to use for the text

    Return value :

    A SDL_Surface with the rendered text

    The function returns a NULL pointer of it can’t find the file, or there is another error ( like SDL2_ttf isn’t initialized. So this too should be handled by priting the error using SDL_GetError(), just like when initializing ttf

    As you can see, both the arguments and return value is the same for TTF_RenderText_Solid and TTF_RenderText_Blended. So what’s the difference between TTF_RenderText_Solid and TTF_RenderText_Blended? The difference is that TTF_RenderText_Solid is very quick, but TTF_RenderText_Blended produces a better result. In our game, we won’t be updating our text surfaces all that often, and there’s not a lot of them either, so TTF_RenderText_Blended is a good choice.

    Here’s what TTF_RenderText_Blended looks like :

    And here’s a comparison between TTF_RenderText_Solid and TTF_RenderText_Blended :

    The difference is not huge, but in the actual game it will be more clear. And the difference might also vary from font to font.

    TTF_RenderText_Shaded


    This function is a bit different from the two other ones. It will render the texture with a specified background color.

    Arguments :

    •  TTF_Font *font – the font to use
    • const char *text – the text to render
    • SDL_Color fg –  the color to use for the text
    • SDL_Color bg –  the color to use for the background

    Return value :

    A SDL_Surface with the rendered text

    The function returns a NULL pointer of it can’t find the file, or there is another error ( like SDL2_ttf isn’t initialized. So this too should be handled by priting the error using SDL_GetError(), just like when initializing ttf

    So it’s almost the same as the other two, just with a fourth argument for the background color. The return value is also the same as the other two. The difference in the resulting function is that you will get a texture with a background color. The background color ( bg ) will fill the entire rect around the text. The text will be rendered on top of it with the specified foreground color ( fg ).

    The result will look something like this :

    An example


    Below is a simple example that should run and compile out of the box. For compilation details, look below.

    Compilation notes


    Running it is just as simple as with SDL2_image. So that means compilation on Windows is already set up when you installed TTF

    Linux / Mac


    If you are compiling using the compiler, you have to add -lSDL2_ttf to the compile string like so :

    clang++ main.cpp -std=c++11 -o Game -lSDL2 -lSDL2_image -lSDL2_ttf

    If you want to run it, you simply do

    ./Game

    Updated game code


    I have done a bit of cleaning up in the game code. I’ve added a new Texture class for text, cleaned up include, removed ( and added ) comments, improve delta calculation++ Everything should be explained in comments, but, of course, if you have any questions of any kinds, just comment or contact me, I’ll be happy to help.

    You can find the code here.

    Conclusion

    Text rendering can be hard, but SDL2 makes it quite easy. Just load your TTF_Fonts and you can easily get them as a SDL_Surface.


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share

    [ SDL2 – Part 9 ] No more delays

    Getting rid of SDL_Delay


    Up until now, we’ve been regulating movement by just setting a delay of 16 milliseconds at the end of each frame like so :

    This would work if the frames always lasted less than 1 millisecond, but they don’t. There is absolutely no grantee that the each frame will last as long as the previous one. And when the duration of each frame differs, the animation will become choppy and not smooth like we want it to be. So how can we get smooth animation?

    Method 1 – our current solution


    We’ve set an aim for 60 frames per second. Since there is 1000 millisconds ( ms ) in a second, each frame should take 1000 ms / 60 frames = 16 ms.Since our code is very light, we’ve just assumed that each frame takes less than 1 ms, so we’ve added a 1ms delay.

    Method 2 – using delta


    Another, better way we could limit framerate is to calculate delta time and use that to set the delay. Delta time is the time between each frame ( or update. )

    If a frame takes 3 ms, delta will be 3 ms. In method 1 we had a 16ms delay and ignore the delta time completely. This means there would always be a 16ms delay. If the frame took 3ms, the delay would still be 16ms. This means the entire frame would take 3ms + 16ms = 19ms. If this happened often, the duration of a frame would jump up and down, and the animation would be choppy.

    Using delta time, though, we could simply subtract that from the 16ms to ensure that every frame lasted exactly 16ms. So if a frame lasts 3ms the delay would be 13ms for a total of 16.

    Let’s create a simple example function that takes the delta time and does the delay :

    This is a valid solution, and your game will run relatively smoothly in 60 fps. You can, of course change the framerate as you please simply by 1000ms by the desired framerate to get the delay amount :

    This method will produce smooth animation, but the third method shows an even better method!

    Method 3 – using delta, no delay


    Method 1 and 2 has worked by limiting frame rate. But why limit it? We can just skip the delay altogether and just use the delta time to adjust animation. Most modern games works this way. Since we adjust movement with delta time, it doesn’t matter if we run in 60 fps or 6000 fps. For smooth animation, this method is superior to the ones above. Waiting 16 ms between frame can make objects jump a tiny bit. And having your game run at 200fps will make a difference, even though the human eye sees 24fps as smooth.

    It’s also very simple, just multiply the movement with the delta time.

    Implementation of method 3


    Implementing frame independent movement is quite simple, but there are a few things you need to be aware of in order to get it right.

    Delta time


    Probably the most important point. In order to get animations right, the delta tie needs to be accurate. Very accurate, preferably with microsecond ( µs ), or nanoseconds ( ns )

    There are various ways to do this.

    • The C way
      • – Confusing
        •   Functions takes a struct and fills it with time / date
      • – Not always accurate
      • – Hard to use correctly
      • – Platform dependent
        • No one way to do it in Linux and Winows
      • + No library needed,
      • + Doesn’t need C++11 support
    • Boost
      • – You’d need to download, and link with boost
      • – Adds and a dependency, just for time
      • – Syntax can be hard to understand
      • + Cross-platform
      • + Does everything you need easily
      • + Doesn’t need C++11 support
    • C++11

    In this part, we’ll be using the chrono library. I suggest using it over the old C way. If you can’t compile C++11, you can use the boost version.

    chorno


    chrono is the new timing library in C++11. I covered this in my previous post, and I recommend that you read it before you read on. If you choose not to read it, I will give you the short version of the various part of the chrono library :

    • duration
      • Holds the amount of time between two points in time
      • Can be stored as any time unit ( seconds, millisconds, years, fortnights, .. )
      • Can use both double and int
    • time_point
      • Holds a point in time
      • Subtracting a time_point from another returns a duration
    • Clock
      • Three kinds: steady_clock, system_clock, high_resolution_clock
      • Used to get current time as a time_point

    Getting the delta


    So here’s the code for our simple delta timer :

    Using delta to calculate movements


    Now that the worst part is over, it’s time for some minor details on how to implement frame independent movement.

    First of all, the animated objects needs to have speed. And for better precision, we use doubles. Let’s make a simple struct for holding the speed. Our speed will have values between -1.0 and 1.0.

    We also need an Update( double delta ) functions that’s used to update the position of the object.

    There’s a few things wrong with this, though. First of all, delta values will be really small, and our speed is between-1.0, and 1.0 so the resulting movement will be really small. We can solve this by multiplying with a constant.

    But there is a second issue here : both speed and delta are likely to do decimal numbers. So the result of the multiplication will almost always be a decimal number as well. But we just put it into an int and this means we’ll loose the decimal precision. So if the result is 0.8, we’ll end up adding 0. And if the same things happen in the next frame, we’ve “lost” 1.6 worth of movement. A whole pixel! It might seem like a small thing, but it would make the movement really choppy. So instead we introduce two new member variables to our Texture struct to hold the result of the multiplication.

    Final function


    Here’s our final Update function:

    In Texture :

    Calling it :

    Conclusion


    That concludes the tutorial on delta timers. I’ve made a few updates, put things into different classes and other minor improvements. The full code is too big to include in this blog post, but you can find a full zip of it here.

    I’ve added a new .cpp file, so you need to add that to the compilation string if you’re using clang or gcc

    clang++ main.cpp Texture.cpp -std=c++11 -lSDL2 -lSDL2_image -o Game


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share

    [ SDL2 – Part 8 ] Image rotation

    Introduction


    In the last tutorial we learned how to load and render png files with alpha layers. This time we’re gonna dive into rotating textures.  Or more precisely ; rendering them rotated.

     

    Today we’ll be making a simple, but working, analog clock. This will show how to rotate textures in SDL2. We’ll also improve how we represent textures

    SDL_RenderCopyEx


    Until now, we have been rendering using SDL_RencerCopy. But in order to rotate, we need a different function ;  int SDL_RenderCopyEx it takes a couple more arguments. I’ll try to explain all of them.

    Parameters :

    • renderer – the SDL_Renderer we always use for rendering
    • texture  – the SDL_Texture we want to render
    • srcrect  – which part of the SDL_Texture to render. null for everything.
    • dstrect  – where to render it. Used exactly like in SDL_RenderFillRect)
    • angle     – angle of rotation
    • center    – the center of rotation
    • flip      – flipping of texture ( vertical, horizontal, no flip )

    Return value

    • 0 on success

    As you can see, the first four parameters are identical to SDL_RenderCopy you can read more about them in part 6.

    Texture flip


    Texture flip is represented as an SDL_TextureFlip

    It is simply an enum with the following three values :

    • SDL_FLIP_NONE         – don’t flip at all
    • SDL_FLIP_HORIZONTAL   – flip horizontaly
    • SDL_FLIP_VERTICAL     – flip vertically

    For now, we will just be using SDL_FLIP_NONE.

    Center of rotation


    The center of rotation is given as a position seen from the top-left of the texture ( remember; in SDL 0,0 is the top-left of a texture. ) If the center of rotation is 0,0 you rotate it from the top-left corner.

    Finding the center of rotation is usually quite simple, it’ll usually just be the center of the texture you are using. For a circle, like a spinning wheel, the center of rotation will simply be the center of the wheel. Or for a Tetris piece it will be the center of the Tetros piece. The center of a texture is easy to find. Since a center of any rectangle will be halfway along its x axis and halfway along its y axis, the position can be calculate as follows ;

    The type of center is one we haven’t used before, SDL_Point. But an SDL_Point is simply just a struct with an x and y value.

    In our case we are going to make a working analog wall clock. So we can’t rotate it around the middle ( that would be a weird clock! ) What we need to do, is find the base of the hands ( where they connect to the center of the clock )

    Here is a picture of on our clock hands. The white hole in the middle is where we want the center of rotation to be. All three hands look very similar to this, all hands have a hole in the base, and all of them rotate around that point.

    If you look closely at the green dots, you’ll see that the distance to the hole from either of the sides and the bottom is all the same ( three green dots. ) The green dots span the entire width of the base. So to find the center x value, we simply take half of the width. Looking at the picture, you’ll see that the distance from the bottom to the hole is the same as the distance from the sides subtract half of the width to find the y position of the hole.

    So the code for finding the center of rotation will be as follows:

    Putting things together


    Previously we have worked with simply storing the SDL_Texture and SDL_Rect as separate objects in our main.cpp. But now we also need to store the center of rotation and the angle. So that’s four variables for each texture. With so many variables, it’s a good idea to split it into a separate struct :

    We also need to change main.cpp to make the clock work :

    As you can see, there is very little code needed in main since a lot of it is moved into Texture.h

    Conclusion


    The SDL_RenderCopyEx function can be very useful and is a very simple way of rotating textures. An by wrapping the SDL_Texture in a separate struct we can make the remaining code smaller and simpler while still keeping all the functionality we need.

    The full code can be downloaded here.


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share

    [ SDL 2 – Part 7 ] Loading PNG files

    Using PNG


    In the previous post we learned how to load .bmp files. Which is not optimal. The .bmp format means the files grow large and there is no alpha layer ( no transparency. ) Which means you end up with ugly single-colored edges instead of transparency

    Original with .bmp images

    SDL2_image


    Up until now, we’ve only been using the standard SDL2.0. But the standard SDL2.0 doesn’t support loading of .png files. But fortunately, there is a second SDL library that does this. And since it’s still SDL, it will work perfectly with or other SDL code!

    Installing is almost exactly the same as installing SDL2 itself; you just follow the instructions in part 1 of my tutorial. But instead of installing SDL2, you install SDL2_image.

    New version with png files.

    Note: I apologize for vague and not very thorough descriptions in the below points. I will update them when I have access to Windows and Mac. I also apologize for the horrible background and sprites.

    Linux


    For Linux you can use need to install -lSDL2_image– or -libSDL2_image– ( the actual name might be different in different distributions. )

    The linker flag is -lSDL2_image

    The process is more or less identical to that of setting up SDL2 base. For more information, see my blog post about setting up SDL2.

    Windows


    Similar to setting up SDL2 base.

    The difference is that you have to download the development files for SDL2_image

    And similarly add SDL2_image.lib to library includes and add SDL2_image.lib to the library flags ( where you previusly added SDL2.lb )

    And with that, it should work.

    Mac

    See the first part of my tutorial. Just install SDL2_image instead of SDL2

    Again; I apologize for my poor description on this. I don’t run Mac and have no experience with it. I hope my short descriptions is of any hope, though.

    Loading PNGs using SDL2_image


    In order to use SDL2_image, you need to add the header file, like so :

    #include <SDL2/SDL_image.h>

    The actual loading of .png files is just as easy as loading .bmp files. But since it uses an extension library, we have to use a different function :

    This function will load a file and return it as a SDL_Texture*. This means we don’t have to convert it, so we can just do:

    Note that this function, unlike the one for loading bmps, needs a pointer to the SDL_Renderer this is because it returns a SDL_Texture. As we saw in the previous post, SDL_Texture are hardware optimized, and SDL2 needs the SDL_Renderer to do the actual hardware optimization.

    Running it


    Just like last time, I’m not gonna show the entire code as one long gist ( too much code, and there are images too. )

    Here is a link to the code in .zip form

    Linux / Max


    If you are compiling using the compiler, you have to add -lSDL2_image to the compile string like so :

    clang++ main.cpp -std=c++11 -o Game -lSDL2 -lSDL2_image

    If you want to run it, you simply do

    ./Game


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share

    [ SDL2 – Part 6 ] Using SDL_Textures

    Loading textures


    In this tutorial you will learn how to load images ( just .bmp for now, the next part will cover .png ). First of all, a little info about the two new structs we’ll be using

    SDL_Surface


    This is part of the old SDL ( before 2.0. ) It was used for just about everything related to rendering.

    SDL_Surface is used for holding the raw texture data. Basically it says what the color for every pixels is. Sort of like this :

    • pixel[ 0, 0 ] = 128, 64, 255, 255 ( 128 red, 64 green, 255 blue, 255 alpha )
    • pixel[ 1, 0 ] = 255, 32, 128, 128 ( 255 red, 32 green, 128 blue, 128 alpha )
    • ..etc

    ( This might not be 100% true for all cases, but it’s generally how SDL_Surface stores the pixels. )

    The SDL_Surface structure also holds other data about the texture :

    • width/height ( these are read-only )
    • the pixel format, stores as an SDL_PixelFormat
    • clip_rec, a SDL_Rect used for bliting ( similar to rendering )

    These values are useful to know about if you want to create your own SDL_Surfaces using code or want to use the old form of rendering ( bliting ). I do, however, not recommend learning about it. Bliting is less intuitive and it uses only software rendering. This basically means that the CPU will be doing the rendering, something CPUs are really bad at. We want optimized hardware rendering on the GPU. And that’s where the second struct comes in.

    SDL_Texture


    Like SDL_Surface, SDL_Texture holds texture data. But unlike SDL_Surface, SDL_Texture holds an optimized, driver specific representation of the pixel data. This means rendering will be executed on the GPU, where it belongs. And THAT means it is really, really fast!

    So what’s the point of SDL_Surfaces?

    Well, as I said, the pixel data in SDL_Texture is optimized. And what’s more, it can be very different depending on your driver ( nVidia vs ATI. ) Basically this means that you can’t use the pixel data for anything other than rendering. A second reason will come up when we dive into another new part of SDL, namely image loading.

    Loading images


    Loading a BMP image in SDL is very easy. It can be done using the following function

    Parameters

    • file – the file we want to load

    Return value

    The loaded image as a SDL_Surface. null if failed

    Converting SDL_Surface to SDL_Texture


    We’re not gonna use the SDL_Surface*, we want a SDL_Texture* instead. To get it, we need to use a second function :

    Parameters

    • renderer – our SDL_Renderer
    • surface – the surface we want to make a SDL_Texture from

    Return value

    The resulting SDL_Texture. null if failed. 

    Since we won’t be using the SDL_Surface, we can delete it and free the memory :

    Parameters

    • surface – the SDL_Surface to delete

    Now that all of this is in place, we can wrap it all up in a nice little function :

    Getting the images on screen


    Now that we have loaded the textures, we need to render then on screen. That means no more SDL_RenderFillRect() and THAT means no more rectangles and squares. Finally! To render them, we just need a simple function :

    Parameters

    • renderer – the SDL_Renderer we always use for rendering
    • texture – the SDL_Texture we want to render
    • srcrect – which part of the SDL_Texture to render. null for everything.
    • dstrect – where to render it. Used exactly like in SDL_RenderFillRect)

    Return value

    0 on success

    Even though this function has a few parameters, it’s really quite simple. We can use nullptr for srcrect and the SDL_Rects we used for SDL_RenderFillRect() as dstrect. And then we can remove the SDL_SetRenderDrawColor and end up with a shorter Render() function.

    Putting it all together


    I’m not gonna put the entire code on the blog anymore since this creates a whole wall of text to scroll through. And now there are images you’ll need too. But you can download the images and the source code here.


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share

    [ SDL2 – Part 5 ] Collision detection

    Collision detection


    Collision detection is one of the key aspects of game programming. For all non-rectangular objects it gets harder and harder the more accurate you want it to be. But today we’re gonna continue just using rectangles. This part describes a simple algorithm to check for intersections.

    After we’ve created a functions that does rectangle-rectangle collision detections, we’ll use all of what we’ve learned so far and make a simple game!

    Rectangle – rectangle collisions


    Instead of checking if two rectangles are inside or touching each other, we’re gonna check for the opposite; if they are outside of each other. The algorithm to do so consists of two steps.

    1. Find the x coordinate of the left and right and the y coordinate for top and bottom.


      Say we have two rectangles, rect1, and rect2.

      Finding the x/y of left/right/top/bottom is very easy.

      The process is exactly the same for the second SDL_Rect.

    2. Use the 8 edges to check if they are not colliding


      Take a look at the drawing below

      As you can see, the red rectangle is farther to the right than the blue one. But how do can we easily check that? Simply by checking if redLeft is further to the right than blueRight. If it is ( like it is in our case ) there is no collision. Then it’s just a simple matter of repeating it for the other edges. So we end up with something like this :

      This is the final function for you to copy and test out.

      If you want to shorten the code, you can remove the comments and replace the variables with the rect. x / y / w / h values like so :

      I chose to not do this as the longer version is a bit easier to read and understand.

    Our first game!


    Our first game is of the “lead the chicken safely across the road” kind of things. Or, as in our case, “lead the square from the rectangle, past all the other squares and to the other rectangle.” You control the square with the arrow keys. If you hit a red square, you’ll end up where you started. If you make it to the other side, you’ll also end up where you started, but at least you have that tiny sense of victory for helping our poor little square!

    The code just uses the different things we’ve learned so far, so I won’t explain it other than in code comments and ( hopefully ) descriptive names.

    So without further ado, here’s the code :


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share

    [ SDL2 – Part 4 ] Making things happen

    Make things happen!


    Games without any input would be really boring. Actually it wouldn’t be a game at all, just a movie. So let’s look at how we can get input so that the player can actually play the game. But before we do that, we need to take a look at how we do the things updates every frame. ( A frame is a single image of the game, basically each SDL_RenderPresent(..) is the end of a frame. )

    The game loop


    In a game ( and many other applications ) things need to happen over and over again. So you need a big loop that does all of these things. A minimal game loop covers :

    • Objects needs to be moved
    • Input handling
    • Collision detections
    • ….

    Today we’ll focus on the two first points, we’ll cover collision detection later.

    The game loop itself is usually a form of infinite loop :

    So in order to exit the loop, we need a way of setting the loop bool to yountrue inside the loop.This will make the loop condition ( if ( loop ) ) false and the loop will stop. We could just use a break; to quit the loop. But this won’t work when we start handling input. We’ll see why in a few moments. But first, we need to move on to the next SDL object :

    Events in SDL2


    All events in SDL2 is in the form of a SDL_Event struct. A SDL_Event is a huge structure with tons of member variable with names that generally don’t say a lot about what they’re for. It is used for just about everything ;

    • Quit event
    • Mouse events
    • Keyboard events
    • Window events( resize, minimize, move, focus, …  )
    • Phone events ( touch, scale, flipping, … )
    • …And the list goes on…

    The type of the event is contained int the .event. This is an enum of the type SDL_EventType If you take a look at the documentation, you’ll see that it has a lot of fields. But to start out, we’ll only look at SDL_Quit and SDL_KeyDown.

    Event polling


    Now that we know about the SDL_Event, let’s see how we get the event from SDL. The method for doing this is :

    As you can see, it’s pretty straight forward. Just pass it a pointer to a SDL_Event and it will populate the structure. If it returns 0, there are no more events. There will most likely be more than one SDL_Event in each iteration, so we’ll need to put this function in a loop.

    SDL_Quit


    The first SDL_EventType we’ll be handling is SDL_QUIT. Which occurs when the user quits our game. Either using the x on the top of the window or Alt + F4

    And there we go! Now the user can exit the program. Which is rather important…

    SDL_KeyDown


    Let’s handle a more interesting event. Namely keyboard presses. These have the event type
    SDL_KeyDown. All possible key presses is stored within the enum called SDL_KeyCode. If you want to see all possible values, you can look at the documentation. We won’t dive into the details of the where the SDL_KeyCode is stored right now because, as I said, it’s stored deep inside the SDL_Event. Instead we’ll just tell you were to find the SDL_KeyCode.

    event.key.keysym.sym

    Where the last sym is the actual SDL_KeyCode

    Moving things


    And now we’ve come to the highpoint of this part, namely moving something based on user input. Doing this is fairly easy, we already have most code for it. All we need to do is to store the location ( SDL_Rect ) of what we are trying to move somewhere ( for now we’ll let it be a global variable along with SDL_Renderer and SDL_Window. )

    We can render a rectangle normally like in the last part and move it around based on user input. We’ll use the following SDL_KeyCode values for movement

    • SDLK_LEFT    – left arrow key
    • SDLK_RIGHT – right arrow key
    • SDLK_UP       – up arrow key
    • SDLK_DOWN – down arrow key

    As you can see, the names are very self-explanatory. And moving the item is as simple as incrementing the x and y of the SDL_Rect. So we get

    This will handle arrow key presses and move the object accordingly.


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share

    [ SDL2 – Part 3 ] Drawing rectangles

    Drawing rectangles


    This part will teach you the basics of the coordinate system in SDL( it’s the same for the “old” SDL and SDL2 ). It will also teach you about a new and very important struct, SDL_Rect. You’ll be using it a lot! And finally we’ll draw something!

    Note


    This part assumes you have SDL2 up and running on your computer, and that you have read the previous part. If you haven’t, please scroll down to part1 and use it to install SDL2 before reading on.

    The coordinate system


    The SDL coordinate system is defined as ( 0, 0 ) being the ( top, left ). This means that a higher y value means further down.

    SDL 2 coordinate system

    This also means that if you tell SDL2 to draw a rectangle, you’ll specify the top-left position of the rectangle instead of the bottom left rectangle. More about this later

    The basic rectangle


    In order to draw something, be it textures or plain rectangles or text or anything, you need a rectangle to specify where to draw it and the size of what you are going to draw. And to hold the size and position we use an SDL_Rect

    SDL_Rect


    Data members :

    • uint16 x – the x position of the rectangle
    • uint16 y – the y position of the rectangle
    • uint16 w – the width of the rectangle
    • uint16 h – the height of the rectangle

    And that’s it. It’s a really simple struct, but it’s very important in SDL2 rendering.

    Drawing a rectangle


    Now you have enough knowledge to draw some rectangles in SDL2. Let’s start off by looking at a the function for rendering a simple rectangle 

    Parameters

    • SDL_Renderer* - the SDL_Renderer we created in the previous part
    • SDL_Rect*  - the position and size of the rectangle we want to draw.

    Return value

    0 on success

    Note that it also takes a pointer to the SDL_Rect, and not the SDL_Rect itself.

    “But what about the color?” you might ask. Remember how in last function we look at
    int SDL_SetRenderDrawColor()? Well, basically, the color you set with this function will also be the color you render your objects with. ( For simplicity, I will refer to this color as SDL_DrawColor from now on. )

    And now the fun stuff


    Let’s say you have just created and set up your window and renderer like so:

    But wait! It’s just a red screen?! As you might have guessed, we forgot to change the color after calling SLD_RenderClear() So the rectangle was drawn with the same color as the background. To make the rectangle visible, we need to change SDL_DrawColor in between SDL_RenderClear() and SDL_RenderDrawRect()

    This gives us something like this :

    And now we have a nice little rectangle on our screen.

    Filling it up…


    The function I showed you earlier will only render the edges of the rectangle. What if you want to render the whole rectangle, and not just the edges? Well there is a nearly identical function for that :

    Parameters

    • SDL_Renderer* - the SDL_Renderer we created in the previous part
    • SDL_Rect*  - the position and size of the rectangle we want to draw.

    Return value

    0 on success

    As you can see, the only thing that separates the two us the name. If you switch SDL_RenderDrawRect() with SDL_RenderFillRect() in the example above, you will get the same rectangle with the same color, but this time it will be the whole rectangle and not just the edges.

    Conclusion


    That’s it for today! Feel free to experiment with two new functions. You can draw as many rectangles as you want, both filled and edges. You can also change the color as often as you want. The only thing you need to remember is to put it all between your SDL_RenderClear( renderer ); and SDL_RenderPresent( renderer );

    Have fun! Below is a full working example to experiment with. I have taken the liberty of putting things in different functions to make it easier to read. =)

    The comments in the code should explain most of what’s going on. But you need to run the program to really see what’s going on. The code will draw a single blue rectangle on a green background that you can move around on the screen. Don’t worry about the code for moving the player around ( RunGame() ), it’ll be explained in the next post.


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share