🔊 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.
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
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