SDL2
Створення простого SDL2-додатку з нуля
На цій сторінці я покажу, як з нуля визначити та створити графічний додаток SDL2, використовуючи лише улюблений текстовий редактор. Документ написаний для у Linux, оскільки це найкраща платформа для вивчення програмування.
Створення зразка програми
Тепер нам потрібно створити файл вихідного коду та файл визначення збірки cmake. Ми взагалі не будемо використовувати SDL, а почнемо з простої програми, яка лише друкує певний текст. Як тільки вона запрацює, ми зможемо розширити її для відображення графіки. Вихідний код зберігається у файлі main.cpp та має такий вміст:
#include <iostream>
int main(int argc, char **argv) {
std::cout<<"App is running.\n";
return 0;
}
Визначення збірки зберігається у файлі з назвою CMakeLists.txt та виглядає так:
cmake_minimum_required(VERSION 3.11)
project(sdlprog)
add_executable(${PROJECT_NAME} src/main.cpp)
Після цього ми можемо розпочати збірку за допомогою наступної команди:
cmake -B builddir -G="Unix Makefiles"
Ось builddir каталог збірки , все, що генерується під час збірки, поміщається в цей каталог. Після запуску це має виглядати ось так.
IMG
Програма компілюється з такою командою:
cmake --build builddir -j$(nproc)
Програма буде знаходитися в каталозі збірки та може бути запущена таким чином:
./builddir/sdlprog
Вихід має виглядати ось так.
IMG
Оновлення програми для використання SDL
Код, необхідний для запуску SDL
, трохи складніший, і ми не будемо вдаватися в
деталі його роботи. Просто замінимо вміст main.cpp
на наступне:
#if defined(__linux)
#include <SDL2/SDL.h>
#elif defined(WIN32)
#include <SDL.h>
#endif
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
struct SDL_Guard {
SDL_Guard(Uint32 flags) {
if (0 > SDL_Init(flags))
throw std::runtime_error("Couldn't initialize SDL:" +
std::string(SDL_GetError()));
}
~SDL_Guard() { SDL_Quit(); }
};
using UniqueWindow = std::unique_ptr<SDL_Window, void (*)(SDL_Window *)>;
#if defined(_WIN32)
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
#elif defined(__APPLE__)
int main(int argc, char **argv)
#elif defined(__linux)
int main(int argc, char **argv, char **env)
#else
int main(int argc, char **argv)
#endif
try {
SDL_Guard sdl_guart(SDL_INIT_EVERYTHING);
const int WINDOW_WIDTH = {320}, WINDOWS_HEIGHT = {240};
UniqueWindow the_window{SDL_CreateWindow("Example", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
WINDOW_WIDTH, WINDOWS_HEIGHT,
SDL_WINDOW_SHOWN),
SDL_DestroyWindow};
if (!the_window)
throw std::runtime_error("Error creating window: " +
std::string(SDL_GetError()));
SDL_Surface *winSurface{SDL_GetWindowSurface(the_window.get())};
if (!winSurface)
throw std::runtime_error("Error getting surface: " +
std::string(SDL_GetError()));
SDL_FillRect(winSurface, NULL,
SDL_MapRGB(winSurface->format, 0x00, 0x00, 0x00));
SDL_UpdateWindowSurface(the_window.get());
SDL_Event e;
bool quit = {false};
do {
SDL_UpdateWindowSurface(the_window.get());
while (SDL_PollEvent(&e)) {
switch (e.type) {
case SDL_QUIT:
quit = true;
break;
default:
break;
}
}
} while (!quit);
return EXIT_SUCCESS;
}
catch (const std::exception &e) {
std::cout << e.what() << std::endl;
return EXIT_FAILURE;
}
catch (...) {
std::cout << "Something wrong\n";
return -EXIT_FAILURE;
}
cmake_minimum_required(VERSION 3.11)
project(sdlprog)
find_package(SDL2 REQUIRED)
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARIES})