×

Welcome to TagMyCode

Please login or create account to add a snippet.
0
0
 
0
Language: C++
Posted by: Jose Fernando Lopez Fernandez
Added: May 31, 2018 2:36 AM
Views: 3164
  1.  
  2. #include <iostream>
  3. #include <string>
  4.  
  5. #include <SDL/SDL.h>
  6.  
  7. const auto SCREEN_WIDTH = 640;
  8. const auto SCREEN_HEIGHT = 480;
  9.  
  10. void LogSDLError(std::ostream& os, const std::string& errorMessage) {
  11.         os << errorMessage << " error: " << SDL_GetError() << '\n';
  12. }
  13.  
  14. SDL_Texture* loadTexture(const std::string& filename, SDL_Renderer *renderer) {
  15.         // Initialize to nullptr to avoid dangling pointer issues
  16.         SDL_Texture *texture = nullptr;
  17.  
  18.         // Load the image
  19.         SDL_Surface *loadedImage = SDL_LoadBMP(filename.c_str());
  20.  
  21.         // If the loading went ok, convert to texture and return the texture
  22.         if (loadedImage != nullptr) {
  23.                 texture = SDL_CreateTextureFromSurface(renderer, loadedImage);
  24.                 SDL_FreeSurface(loadedImage);
  25.  
  26.                 // Make sure everything went ok, too
  27.                 if (texture == nullptr) {
  28.                         LogSDLError(std::cerr, "LoadBMP");
  29.                 }
  30.         } else {
  31.                 LogSDLError(std::cerr, "LoadBMP");
  32.         }
  33.  
  34.         return texture;
  35. }
  36.  
  37. void RenderTexture(SDL_Texture *texture, SDL_Renderer *renderer, int x, int y) {
  38.         // Setup the destination rectangle to be at the position we want
  39.         SDL_Rect destination;
  40.         destination.x = x;
  41.         destination.y = y;
  42.  
  43.         // Query the texture to get its width and height to use
  44.         SDL_QueryTexture(texture, NULL, NULL, &destination.w, &destination.x);
  45.         SDL_RenderCopy(renderer, texture, NULL, &destination);
  46. }
  47.  
  48.  
  49.  
  50. int main(int argc, char *argv[])
  51. {
  52.         /** Function: SDL_Init
  53.          *
  54.          *  Description:
  55.          *  To use SDL we first need to initialize the various SDL subsystems we want to use.
  56.          *  This is done through SDL_Init which takes a set of flags OR'd together specifying
  57.          *  the subsystems we'd like to initialize. Note that the event handling subsystem is
  58.          *  initialized automatically when the video system is if not explicitly requested by
  59.          *  itself while the file I/O and threading systems are initialized by default. If
  60.          *  everything goes ok, SDL_Init will return 0; if not, we'll want to print out the
  61.          *  error and exit.
  62.          *
  63.          */
  64.  
  65.         if (SDL_Init(SDL_INIT_VIDEO)) {
  66.                 LogSDLError(std::cerr, "SDL_Init");
  67.  
  68.                 return EXIT_FAILURE;
  69.         }
  70.  
  71.         /** Function: SDl_CreateWindow
  72.          *
  73.          *  Description:
  74.          *  We'll need a window to display our render in. We can create one with SDL_CreateWindow,
  75.          *  which takes a title for the window, the x and y position to create it at, the window width
  76.          *  and height, and some flags to set properties of the window, and then returns an
  77.          *  SDL_Window pointer (*). This pointer will be NULL if anything went wrong when creating the
  78.          *  window. If an error does occur, we need to clean up SDL before exiting the program.
  79.          *
  80.          *  Parameters:
  81.          *              Window Title
  82.          *              x position
  83.          *              y position
  84.          *              width
  85.          *              height
  86.          *              properties
  87.          *
  88.          *  Return: SDL_Window*
  89.          *
  90.          */
  91.  
  92.         SDL_Window *mainWindow = SDL_CreateWindow("Hello, World!", 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
  93.  
  94.         if (!mainWindow) {
  95.                 LogSDLError(std::cerr, "CreateWindow");
  96.                
  97.                 SDL_Quit();
  98.                 return EXIT_FAILURE;
  99.         }
  100.  
  101.         /** Function: SDL_Renderer
  102.          *
  103.          *  Description:
  104.          *  Now we can create a renderer to draw to the window using SDL_CreateRenderer. This function
  105.          *  takes the window to associate the renderer with, the index of the redendering driver to be
  106.          *  used (or -1 to select the first that meets our requirements), and various flags used to
  107.          *  specify what sort of renderer we want. Here we're requesting a hardware accelerated renderer
  108.          *  with vsync enabled. We'll get back an SDL_Renderer pointer (*) which will be NULL if something
  109.          *  went wrong. If an error does occur, we need to clean up anything we've previously created and
  110.          *  quit SDL before exiting the program.
  111.          *
  112.          *  Parameters:
  113.          *              window to associate renderer with
  114.          *              index of the rendering driver to be used (or -1 to select first one that meets our req's)
  115.          *              renderer properties flags
  116.          *
  117.          *  Return: SDL_Renderer*
  118.          *
  119.          */
  120.  
  121.         SDL_Renderer *renderer = SDL_CreateRenderer(mainWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
  122.  
  123.         if (!renderer) {
  124.                 SDL_DestroyWindow(mainWindow);
  125.                
  126.                 LogSDLError(std::cerr, "CreateRenderer");
  127.  
  128.                 SDL_Quit();
  129.                 return EXIT_FAILURE;
  130.         }
  131.  
  132.         /** Function: SDL_CreateTextureFromSurface
  133.          *
  134.          *  Description:
  135.          *  With the image loaded into an SDL_Surface, we can now upload it to the renderer using
  136.          *  SDL_CreateTextureFromSurface. We pass in the rendering context to upload to, as well as the
  137.          *  image in memory (the SDL_Surface), and get back the loaded texture. We're done with the original
  138.          *  surface at this point so we'll free it now.
  139.          *
  140.          *  Parameters:
  141.          *    1. Renderer
  142.          *    2. Image
  143.          *
  144.          *  Return: SDL_Texture*
  145.          *
  146.          */
  147.  
  148.         SDL_Texture *background = loadTexture("C:\\Users\\jflop\\source\\repos\\sdl-test\\sdl-test\\img\\background.bmp", renderer);
  149.         SDL_Texture *foreground = loadTexture("C:\\Users\\jflop\\source\\repos\\sdl-test\\sdl-test\\img\\foreground.bmp", renderer);
  150.  
  151.         if ((!background) || (!foreground)) {
  152.                 SDL_DestroyRenderer(renderer);
  153.                 SDL_DestroyWindow(mainWindow);
  154.  
  155.                 LogSDLError(std::cerr, "LoadTexture");
  156.  
  157.                 SDL_Quit();
  158.                 return EXIT_FAILURE;
  159.         }
  160.  
  161.         for (auto i = 0; i < 3; i++) {
  162.                 SDL_RenderClear(renderer);
  163.  
  164.                 int bW = 0;
  165.                 int bH = 0;
  166.  
  167.                 SDL_QueryTexture(background, NULL, NULL, &bW, &bW);
  168.  
  169.                 RenderTexture(background, renderer, 0, 0);
  170.                 RenderTexture(background, renderer, bW, 0);
  171.                 RenderTexture(background, renderer, 0, bH);
  172.                 RenderTexture(background, renderer, bW, bH);
  173.  
  174.                 int iW = 0;
  175.                 int iH = 0;
  176.  
  177.                 SDL_QueryTexture(foreground, NULL, NULL, &iW, &iH);
  178.  
  179.                 int x = SCREEN_WIDTH / 2 - iW / 2;
  180.                 int y = SCREEN_HEIGHT / 2 - iH / 2;
  181.  
  182.                 RenderTexture(foreground, renderer, x, y);
  183.  
  184.                 SDL_RenderPresent(renderer);
  185.                 SDL_Delay(1000);
  186.         }
  187.  
  188.         /** Before we exit, we've got to destroy all the objects we created through the various SDL_DestroyX
  189.          *  functions, and quit SDL. Error Handling Note: previously in the program we may have encountered
  190.          *  an error and exited early, in which case we'd have to destroy any SDL objects we had created and
  191.          *  quit SDL to properly clean up before exiting. This part of the error handling is omitted from the
  192.          *  lessons since they're such small examples and it helps keep the code a bit shorter, but in a real
  193.          *  world program, proper error handling and clean up is absolutely required.
  194.          *
  195.          */
  196.  
  197.         SDL_DestroyTexture(background);
  198.         SDL_DestroyTexture(foreground);
  199.         SDL_DestroyRenderer(renderer);
  200.         SDL_DestroyWindow(mainWindow);
  201.  
  202.         SDL_Quit();
  203.         return EXIT_SUCCESS;
  204. }