Cropping and Positioning Images

Rendering Multiple Instances of an Image in SDL2

How can I display the same image multiple times in different positions on the screen?

Abstract art representing computer programming

Displaying the same image multiple times in different positions on the screen is a common requirement in many applications, especially games.

In SDL2, we can achieve this by using the same source surface or texture and blitting it to different positions on the destination surface. Here's how you can do it:

#include <SDL.h>

#include <iostream>
#include <vector>

class Image {
public:
  Image(const char* file) : surface{
    SDL_LoadBMP(file)} {
    if (!surface) {
      std::cerr << "Failed to load image: " <<
        SDL_GetError() << '\n';
    }
  }

  void RenderMultiple(SDL_Surface* destSurface,
                      const std::vector<
                        SDL_Point>& positions) {
    if (!surface || !destSurface) return;

    SDL_Rect srcRect{
      0, 0, surface->w, surface->h};

    for (const auto& pos : positions) {
      SDL_Rect destRect{
        pos.x, pos.y, surface->w, surface->h};
      SDL_BlitSurface(surface, &srcRect,
                      destSurface, &destRect);
    }
  }

  ~Image() {
    if (surface) SDL_FreeSurface(surface);
  }

private:
  SDL_Surface* surface;
};

int main() {
  SDL_Init(SDL_INIT_VIDEO);

  SDL_Window* window =
    SDL_CreateWindow("Multiple Images",
                     SDL_WINDOWPOS_UNDEFINED,
                     SDL_WINDOWPOS_UNDEFINED,
                     640, 480, 0);
  SDL_Surface* screenSurface =
    SDL_GetWindowSurface(window);

  Image img{"example.bmp"};

  // Define positions for multiple instances of the image
  std::vector<SDL_Point> positions = {
    {50, 50}, // Top-left
    {500, 50}, // Top-right
    {50, 350}, // Bottom-left
    {500, 350}, // Bottom-right
    {275, 200} // Center
  };

  img.RenderMultiple(screenSurface, positions);

  SDL_UpdateWindowSurface(window);

  SDL_Delay(3000); // Display for 3 seconds

  SDL_DestroyWindow(window);
  SDL_Quit();

  return 0;
}

In this example, we've added a RenderMultiple() method to our Image class. This method takes a vector of SDL_Point structures, each representing a position where we want to render the image.

The key part is the loop inside RenderMultiple():

for (const auto& pos : positions) {
  SDL_Rect destRect{
    pos.x, pos.y, surface->w, surface->h};
  SDL_BlitSurface(
    surface, &srcRect, destSurface, &destRect);
}

This loop iterates through all the positions and blits the image to each one.

In the main() function, we define a vector of positions where we want our image to appear:

std::vector<SDL_Point> positions = {
  {50, 50}, // Top-left
  {500, 50}, // Top-right
  {50, 350}, // Bottom-left
  {500, 350}, // Bottom-right
  {275, 200} // Center
};

Then we call RenderMultiple() with these positions.

This approach is efficient because we only load the image once, but we can display it in multiple locations. It's particularly useful for things like:

  • Tiled backgrounds
  • Repeated UI elements
  • Particle systems
  • Multiple instances of the same game object

Remember to handle potential errors, such as failing to load the image or create the window. Also, in a real application, you'd typically render in a loop rather than using SDL_Delay().

This Question is from the Lesson:

Cropping and Positioning Images

Learn to precisely control image display using source and destination rectangles.

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

Cropping and Positioning Images

Learn to precisely control image display using source and destination rectangles.

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 51 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved