🔊 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
VIDEO
Códigos Feitos e Usados no Vídeo
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
👀 Veja também:
sdl2
cpp
Marcos Oliveira
Desenvolvedor de software