Up until now we’ve only been using BMP images as they’re the only type supported by the base SDL library,but being restricted to using BMP images isn’t that great. Fortunately there are a set of SDL extension librariesthat add useful features to SDL, such as support for a wide variety of image types through SDL_image. The other available libraries areSDL_ttf which provides TTF rendering support, SDL_net which provides low level networkingand SDL_mixer which provides multi-channel audio playback.
Installing an Extension Library
Conantargetlinklibraries¶ Helper to link all libraries to a specified target. These targets are: A CONANPKG:: target per package in the dependency graph. This is an IMPORTED INTERFACE target. IMPORTED because it is external, a pre-compiled library. Findpackage (mylibrary 1.0 REQUIRED) targetlinklibraries (clienttarget PUBLIC mylibrary) And it will automatically find an appropriate library version and link to a library of matching build type. For an actual complete example, look at the source code of memory itself. The LINKINTERFACELIBRARIES mode appends the libraries to the INTERFACELINKLIBRARIES target property instead of using them for linking. If policy CMP0022 is not NEW, then this mode also appends libraries to the LINKINTERFACELIBRARIES and its per-configuration equivalent. This signature is for compatibility only. Findpackage (Catch2 REQUIRED) addexecutable (tests test.cpp) targetlinklibraries (tests PRIVATE Catch2::Catch2) This target is also provided when Catch2 is used as a subdirectory. Assuming that Catch2 has been cloned to lib/Catch2.
Target_link_libraries Udev
In this lesson we’ll just need SDL_image but the installation process for all the extension libraries is the same. Download the development library for your system from the project pageand follow the instructions below to get SDL_image set up on your system.
- Windows (MinGW or Visual Studio): Merge the extension library’s files into your existing SDL2 directory.You’ll also need to copy the SDL2_image, zlib and any image format dlls (such as libpng) over to your executable directory so that they’re available at runtime
- Linux: Install from your package manager or by downloading the source and building with CMake.
- Mac: Download the .dmg from the site and follow the Readme.
To use the libraries you’ll need to update your includes and build system to link against the new extension library.
Cmake
Grab the appropriate module from the repoand add it to your CMake modules directory (
cmake/
). You can then look up the new extension library using the samefind_package
method used to find SDL2 and include SDL_image.h
in your source file.Visual Studio
Include
SDL_image.h
and add SDL2_image.lib
to your linker dependencies.GCC or Clang on Linux and MinGW on Windows
Include
SDL2/SDL_image.h
and add -lSDL2_image
to the SDLLIB
variable in your makefile.Clang on Mac
Gog rimworld. Include
SDL2_image/SDL_image.h
and add -framework SDL2_image
to the SDL
variable in your makefile.Setting up Tile Properties
In this lesson we’ll see how to load images with SDL_image along with looking into scaling our textures whenthey’re drawn and come up with a method to place tiles based on the window size and the tile size. To do thiswe’ll need to define a tile size constant, which we’ll add below our window constants.
Loading Textures with SDL_image
SDL_image lets us load multiple types of images along with allowing us to load them directly to an SDL_Texturewith
IMG_LoadTexture
. With this function almost all of our loadTexture
code can be replaced and nowwe call IMG_LoadTexture
to load the texture, check for errors and return. We can still use logSDLError
to log errors from the SDL_image library as the IMG_GetError
function is just a define of SDL_GetError
.Specifying Width and Height for Rendering
With SDL2 we’re able to scale textures when they’re rendered by specifying a width and height for the destination rectangle that differ from the texture’s width and height. However it’s also common to draw the textures without any scaling applied and it’d be a real pain if we had to specify the widthand height each time we wanted to draw without scaling. To get around this we’ll create two versions of
renderTexture
.One will take the width and height along with the other parameters while another version will mirror our originaland will use the texture’s width and height for the destination.To set the texture’s width and height for drawing we simply write the width and height we want to the destination rect’s width and height fields instead of getting them from the texture.
We’ll also create a function that provides the old functionality of drawing the texture without any scaling. Thisfunction will just get the width and height from the texture then call our new
renderTexture
function.Initialize SDL_image (Optional)
When loading an image for the first time SDL_image will automatically initialize the necessary image loadingsubsystem, however this will cause some delay in loading the image since SDL_image will have to performits initialization setup first. If you’d like to initialize SDL_image earlierto avoid the delay when loading an image type for the first time you can do so with
IMG_Init
. IMG_Init
will returna bitmask of all the currently initialized image loaders, so we’ll perform an and with the flags we passedto see if initialization was successful. Here we only initialize the PNG loader since that’s all we’ll need for this lesson. This initialization should be done after initializing SDL.We then open a window and renderer the same as we did in lesson 2.
Loading the Textures
Since this lesson is to demonstrate loading PNGs we’ll be using new images for our background and foreground. We’ll also demonstrate that PNG transparency is preserved by using a foreground image with a transparent background drawn on top of a tiled background. Grab them both below.
The images are loaded exactly the same with our
loadTexture
function. Be sure to update the file paths to matchyour project structure.Tiling the Background
Since our tiles are much smaller now we’ll need a lot more than 4 to cover the entire screen and typing theirpositions out by hand would be a real pain. Instead let’s generate the tile draw positions to fill the screenby using some math!
We can determine how many tiles each row will need by dividing the
SCREEN_WIDTH
by the TILE_SIZE
. To determinethe number of tiles per column we can do the same thing but for the SCREEN_HEIGHT
. Since we’ll be filling a squarearea of tiles the total number of tiles will be tiles_per_row * tiles_per_col
. We could use a single for loop to run through all the tiles, or nested for loops to fill each tile in a row for each row. I’ve chosen to go with a single loop. John deere 8400 fs19.In the loop we compute the x and y indices of the tile to determine where it should be placed. Since we’re drawingrow by row in this method the x index will repeat each row, while the y index will increment after each row is filledand we move down to the next row.Thus we can calculate the x index using the absolute tile index modded with the number of tiles per row:
x = tile_idx % tiles_per_row
.For example, if we were drawing a 2x2 grid of tiles we’d expect tile 0 to have the same x index as tile 2, which with this method it will:
0 % 2 0
and 2 % 2 0
.The y index should increase after an entire row of tiles has been placed, so every
tiles_per_row
tiles. Since we’re using integerswe can take advantage of integer truncation and compute this as y = tile_idx / tiles_per_row
. So on our 2x2grid example: row 0 will have tiles 0 and 1: 0/2 0
and 1/2 0
, and row 1 will have tiles 2 and 3: 2/2 1
and 3/2 1
giving the correct y indices.All that’s left to do is convert the indices into the pixel coordinates of the tile, which is done by multiplyingthe x and y indices by the tile size, and our tiling loop is done!
Note: All of this rendering code will be placed within our main loop, similar to lesson 1.
Drawing the Foreground
Our foreground image is drawn the same as before, centered in the screen.
Php find string in string.
We’ll then present the renderer and wait a few seconds before exiting just as we did in Lesson 2.
Cleaning Up
Clean up is the same as in lesson 2 with one added line to quit SDL_image by calling
IMG_Quit
.End of Lesson
If everything went well you should see this draw to your window.
If you have any issues check your error log and check back through the lesson. Feel free tosend an email or tweet for any questions you may have.
I’ll see you again soon in Lesson 4: Handling Events!
Tutorial Index
Helpful Links
SDL DocumentationSDL Forums
IRC: #SDL on freenode
C++ Reference
Code on Github
Cmake Target_link_libraries
Published: 18 August 2013
Start with
find_package
to locate the libraries and header files shipped with Qt. Then, you can use these libraries and header files with the target_link_libraries
command to build Qt-based libraries and applications. This command automatically adds the appropriate include directories, compile definitions, the position-independent-code flag, and links to the qtmain.lib
library on Windows, for example.Build a GUI executable
To build a helloworld GUI executable, you need the following:
For
find_package
to be successful, CMake
must find the Qt installation in one of the following ways:- Set your
CMAKE_PREFIX_PATH
environment variable to the Qt 5 installation prefix. This is the recommended way. - Set the
Qt5_DIR
in theCMake
cache to the location of theQt5Config.cmake
file.
The
CMAKE_AUTOMOC
setting runs moc automatically when required. For more details, see CMake AUTOMOC documentation.Imported library targets
Each Qt module that is loaded defines a CMake library target. The target names start with
Qt5::
, followed by the module name. For example: Qt5::Core
, Qt5::Gui
. Pass the name of the library target to target_link_libraries
to use the respective library.Note: Since Qt 5.15, the CMake targets are also available as
Qt::Core
, Qt::Gui
, and so on. This eases writing CMake code that can work with both Qt 5 and Qt 6.Target_link_libraries Lib
Imported targets are created with the same configurations as when Qt was configured. That is:
- If Qt was configured with the
-debug
switch, an imported target with the DEBUG configuration is created. - If Qt was configured with the
-release
switch, an imported target with the RELEASE configuration is created. - If Qt was configured with the
-debug-and-release
switch, then imported targets are created with both RELEASE and DEBUG configurations.
If your project has custom
CMake
build configurations, you have to map your custom configuration to either the debug or the release Qt configuration.Target_link_libraries
© 2021 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.