Como usar SDL2 com SMART POINTER

🔊 Nesse vídeo veremos que utilizar Ponteiros Inteligentes com SDL2 possui algumas particularidades.


Como usar SDL2 com SMART POINTER


🔊 Nesse vídeo veremos que utilizar Ponteiros Inteligentes com SDL2 possui algumas particularidades devido a Estrutura de Dados do SDL que se diferencia como o C++ trata esses objetos.


Assista ao Vídeo


Códigos Feitos e Usados no Vídeo

Código Procedural com SMART POINTER

main.cpp

#include <SDL2/SDL.h>
#include <memory>

struct SDLContext {
  SDLContext(){
    SDL_Init(SDL_INIT_EVERYTHING);
  }

  ~SDLContext(){
    SDL_Quit();
  }
};

int main() {

  auto sdlContext = std::make_unique<SDLContext>();

  std::unique_ptr<SDL_Window, void(*)(SDL_Window*)> window(
     SDL_CreateWindow(
      "SDL2 It's Works!",
      50, 30,
      1280, 720,
      SDL_WINDOW_SHOWN
      ),
     SDL_DestroyWindow
  );

  std::unique_ptr<SDL_Renderer, void(*)(SDL_Renderer*)> renderer(
     SDL_CreateRenderer(window.get(), -1, 0),
     SDL_DestroyRenderer

  );

  std::unique_ptr<SDL_Surface, void(*)(SDL_Surface*)> surface(
    SDL_LoadBMP("./sdl.bmp"),
    SDL_FreeSurface

  );

  std::unique_ptr<SDL_Texture, void(*)(SDL_Texture*)> logo(
      SDL_CreateTextureFromSurface(renderer.get(), surface.get()),
      SDL_DestroyTexture
  );

   std::unique_ptr<SDL_Rect, void(*)(SDL_Rect*)> rect(
      new SDL_Rect{50, 20, surface->w, surface->h}, 
      [](SDL_Rect * r){delete r;}
   ); 

   std::unique_ptr<SDL_Rect, void(*)(SDL_Rect*)> rect2(
      new SDL_Rect{800, 20, 300, 300}, 
      [](SDL_Rect * r){delete r;}
   ); 

  while(true){
    SDL_Event event;
    while(SDL_PollEvent(&event)){
      if( event.type == SDL_QUIT ){
        exit(0);
      }else if( event.type == SDL_MOUSEBUTTONDOWN ){
        rect2->x -= 20;
      }
    }

    SDL_RenderClear(renderer.get());
    SDL_SetRenderDrawColor(renderer.get(), 255, 255, 255, 255);
    SDL_RenderFillRect(renderer.get(), rect2.get());
    SDL_SetRenderDrawColor(renderer.get(), 9, 20, 33, 255);
    SDL_RenderCopy(renderer.get(), logo.get(), NULL, rect.get());
    SDL_RenderPresent(renderer.get());
  }

  return 0;
}

Compile: g++ -Wall -Werror -Wextra -pedantic -g -fsanitize=address main.cpp -lSDL2


Código com OPP com SMART POINTER

smart.hpp

#pragma once

#include <SDL2/SDL.h>
#include <stdexcept>
#include <memory>

extern std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> window;
extern std::unique_ptr<SDL_Renderer, decltype(&SDL_DestroyRenderer)> renderer;
extern std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surface;
extern std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)> logo;
//extern std::unique_ptr<SDL_Window, void(*)(SDL_Window*)> window;

struct SDLContext {
  SDLContext();
  ~SDLContext();
};

class SmartSdlOop {
  std::unique_ptr<SDLContext> sdlContext;
  std::unique_ptr<SDL_Rect> rect, rect2;
  std::unique_ptr<SDL_Event> event;

  public:
    SmartSdlOop();
    void run();
};

smart.cpp

#include "smart.hpp"

std::unique_ptr<SDL_Window, void(*)(SDL_Window*)> window(nullptr, SDL_DestroyWindow);
std::unique_ptr<SDL_Renderer, void(*)(SDL_Renderer*)> renderer(nullptr, SDL_DestroyRenderer);
std::unique_ptr<SDL_Surface, void(*)(SDL_Surface*)> surface(nullptr, SDL_FreeSurface);
std::unique_ptr<SDL_Texture, void(*)(SDL_Texture*)> logo(nullptr, SDL_DestroyTexture);

SDLContext::SDLContext() {
  if (SDL_Init(SDL_INIT_EVERYTHING  & ~(SDL_INIT_TIMER | SDL_INIT_HAPTIC)) != 0) {
    throw std::runtime_error("Erro ao inicializar o SDL2: " + std::string(SDL_GetError()));
  }
  //SDL_Init(SDL_INIT_EVERYTHING);
}

SDLContext::~SDLContext() {
  SDL_Quit();
}

SmartSdlOop::SmartSdlOop(){

  sdlContext = std::make_unique<SDLContext>();

  window.reset(SDL_CreateWindow("SDL2 It's Works!", 50, 30, 1280, 720, SDL_WINDOW_SHOWN));
  renderer.reset(SDL_CreateRenderer(window.get(), -1, 0));
  surface.reset(SDL_LoadBMP("./sdl.bmp"));
  logo.reset(SDL_CreateTextureFromSurface(renderer.get(), surface.get()));
  rect.reset(new SDL_Rect{50, 20, surface->w, surface->h});
  rect2.reset(new SDL_Rect{ 800, 20, 300, 300 });
  event = std::make_unique<SDL_Event>();
}

void SmartSdlOop::run(){
  while(true){
    while(SDL_PollEvent(event.get())){
      if( event->type == SDL_QUIT ){
        exit(0);
      }else if( event->type == SDL_MOUSEBUTTONDOWN ){
        rect2->x -= 20;
      }
    }

    SDL_RenderClear(renderer.get());
    SDL_SetRenderDrawColor(renderer.get(), 255, 255, 255, 255);
    SDL_RenderFillRect(renderer.get(), rect2.get());
    SDL_SetRenderDrawColor(renderer.get(), 9, 20, 33, 255);
    SDL_RenderCopy(renderer.get(), logo.get(), NULL, rect.get());
    SDL_RenderPresent(renderer.get());
  }
}

main.cpp

#include "smart.hpp"

int main(){
  auto smart = std::make_unique<SmartSdlOop>();
  smart->run();
  return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.27.4)

project(SDL2_DESK_PROCEDURAL)

add_compile_options(-Wall -Wextra -Wpedantic -Wall -Werror -Wextra -pedantic -g -O2)

find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})

add_executable(a.out main.cpp smart.cpp)
target_link_libraries(a.out ${SDL2_LIBRARIES})

# Copia a imagem para dentro do build
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/sdl.bmp
     DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

Compile e rode:

cmake -B build .
cd build && make
./a.out

👀 Veja também:



sdl2 cpp


Compartilhe


Nosso canal no Youtube

Inscreva-se


Marcos Oliveira

Marcos Oliveira

Desenvolvedor de software
https://github.com/terroo

Artigos Relacionados




Crie Aplicativos Gráficos para Linux e Windows com C++

Aprenda C++ Moderno e crie Games, Programas CLI, GUI e TUI de forma fácil.

Saiba Mais

Receba as novidades no seu e-mail!

Após cadastro e confirmação do e-mail, enviaremos semanalmente resumos e também sempre que houver novidades por aqui para que você mantenha-se atualizado!