SDL — мультимедиа и окна на C++
Что такое SDL
SDL (Simple DirectMedia Layer), сейчас SDL2 — библиотека на C, дающая единый доступ к окну, клавиатуре, мыши, геймпадам, аудио и таймерам на Windows, Linux, macOS, Android, iOS и других платформах.
SDL — не игровой движок. Он не рисует "игру из коробки", а поставляет примитивы: создать окно, прочитать событие, вывести прямоугольник или передать управление OpenGL / Vulkan. Поверх SDL строят Godot (на части платформ), эмуляторы, indie-игры и обёртки вроде Pygame в Python (игры на Python).
В C++ SDL вызывают напрямую; указатели SDL_Window* удобно оборачивать в RAII — см. Управление памятью и Идиомы.
Ключевые понятия
| Термин | Определение |
|---|---|
| Подсистема | Часть SDL (video, audio, joystick), инициализируемая флагами SDL_Init |
| SDL_Renderer | 2D-API: clear, draw rect/texture, present — без ручного OpenGL |
| Surface / Texture | Surface — CPU-память; Texture — GPU для renderer |
| Event loop | Цикл SDL_PollEvent; каждое событие — структура SDL_Event |
| Context | OpenGL/Vulkan контекст, привязанный к окну SDL |
Сравнение с C++-обёрткой — SFML. Быстрый монолит — Raylib.
SDL, SFML и Raylib
| Критерий | SDL2 | SFML | Raylib |
|---|---|---|---|
| Язык API | C | C++ | C |
| 2D renderer | SDL_Renderer | sf::Sprite | DrawTexture |
| 3D | OpenGL/Vulkan через контекст | Нет | Встроено |
| Звук | SDL_mixer / SDL3 audio | Встроен | Встроен |
| Гибкость | Максимальная | Средняя | Меньше, быстрее старт |
| Экосистема | image, ttf, mixer, net | Модули SFML | Монолит |
Правило выбора: SDL — контроль, мобильные порты, свой рендер на OpenGL или Vulkan. SFML — приятнее C++-стиль. Raylib — минимум настройки.
Подсистемы и расширения SDL2
| Подсистема | Флаг SDL_Init | Назначение |
|---|---|---|
| Video | SDL_INIT_VIDEO | Окно, события, renderer |
| Audio | SDL_INIT_AUDIO | Вывод звука |
| Joystick | SDL_INIT_GAMECONTROLLER | Геймпады |
| Timer | ядро SDL | SDL_GetTicks, callbacks |
Отдельные библиотеки (ставятся дополнительно):
- SDL_image — PNG, JPG, WebP;
- SDL_mixer — WAV, OGG, музыка;
- SDL_ttf — TrueType шрифты;
- SDL_net — TCP/UDP.
CMake и vcpkg
cmake_minimum_required(VERSION 3.16)
project(sdl_demo CXX)
set(CMAKE_CXX_STANDARD 17)
find_package(SDL2 CONFIG REQUIRED)
find_package(SDL2_image CONFIG REQUIRED)
add_executable(game main.cpp)
target_link_libraries(game PRIVATE SDL2::SDL2 SDL2_image::SDL2_image)
vcpkg install sdl2 sdl2-image sdl2-mixer— типичный набор для игры.- Linux:
sudo apt install libsdl2-dev libsdl2-image-dev.
Минимальный цикл на SDL_Renderer
#include <SDL.h>
#include <SDL_image.h>
int main(int argc, char* argv[]) {
SDL_Init(SDL_INIT_VIDEO);
IMG_Init(IMG_INIT_PNG);
SDL_Window* window = SDL_CreateWindow(
"SDL demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
800, 600, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(
window, -1, SDL_RENDERER_ACCELERATED);
bool running = true;
while (running) {
SDL_Event e;
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) running = false;
}
SDL_SetRenderDrawColor(renderer, 30, 30, 40, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 80, 200, 120, 255);
SDL_Rect rect{350, 250, 100, 100};
SDL_RenderFillRect(renderer, &rect);
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
return 0;
}
Разбор построчно
SDL_Init(SDL_INIT_VIDEO)— поднимает video-подсистему; при ошибке возвращает< 0, нуженSDL_GetError().IMG_Init(IMG_INIT_PNG)— регистрирует декодеры SDL_image; симметричноIMG_Quit().SDL_CreateWindow— native-окно; координатыCENTERED— по центру экрана.SDL_CreateRenderer(..., SDL_RENDERER_ACCELERATED)— 2D backend на GPU, если доступен.SDL_PollEvent— неблокирующий опрос;SDL_QUIT— закрытие окна или Alt+F4.RenderClear+RenderFillRect+RenderPresent— аналог SFMLclear/draw/display.Destroy*иQuit— освобождение ресурсов; в C++ лучше RAII-обёртки с custom deleter.
SDL с OpenGL и Vulkan
Для 3D SDL создаёт окно и surface, рендер — ваш код:
SDL_Window* window = SDL_CreateWindow(
"3D", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
1280, 720, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
SDL_GLContext glContext = SDL_GL_CreateContext(window);
// GLAD/GLEW — загрузка функций OpenGL 3.3+
Флаг SDL_WINDOW_VULKAN + SDL_Vulkan_CreateSurface — вход в Vulkan. SDL здесь не рисует треугольник — только связь с ОС.
Подробнее — OpenGL на C++.
Аудио через SDL_mixer
#include <SDL_mixer.h>
Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048);
Mix_Chunk* hit = Mix_LoadWAV("hit.wav");
Mix_PlayChannel(-1, hit, 0);
Mix_FreeChunk(hit);
Mix_CloseAudio();
- Chunk — короткий эффект.
- Music —
Mix_LoadMUS/Mix_PlayMusicдля фона.
Архитектура SDL-проекта
SDL хорошо сочетается с ECS (EnTT, Flecs): система ввода читает SDL_Event, система рендера — только draw. Игровой цикл — 22.
Когда выбирать SDL
| Сценарий | SDL |
|---|---|
| Кроссплатформенный движок, эмулятор | Да |
| Мобильный порт (Android/iOS) | Да |
| Быстрая учебная 2D без CMake-магии | Часто проще Raylib |
| Desktop GUI | Qt |
| Windows-only низкоуровневый GPU | DirectX |
Частые ошибки
| Симптом | Причина | Решение |
|---|---|---|
SDL_Init failed | headless сервер / нет дисплея | Xvfb, локальный запуск |
| Утечки | Create* без Destroy | RAII |
| Размытые спрайты | некратный scale | integer scale, SDL_ScaleModeNearest |
| OpenGL 1.x only | нет loader | GLAD/GLEW после CreateContext |