Перейти к основному содержимому

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_Renderer2D-API: clear, draw rect/texture, present — без ручного OpenGL
Surface / TextureSurface — CPU-память; Texture — GPU для renderer
Event loopЦикл SDL_PollEvent; каждое событие — структура SDL_Event
ContextOpenGL/Vulkan контекст, привязанный к окну SDL

Сравнение с C++-обёрткой — SFML. Быстрый монолит — Raylib.


SDL, SFML и Raylib

КритерийSDL2SFMLRaylib
Язык APICC++C
2D rendererSDL_Renderersf::SpriteDrawTexture
3DOpenGL/Vulkan через контекстНетВстроено
ЗвукSDL_mixer / SDL3 audioВстроенВстроен
ГибкостьМаксимальнаяСредняяМеньше, быстрее старт
Экосистемаimage, ttf, mixer, netМодули SFMLМонолит

Правило выбора: SDL — контроль, мобильные порты, свой рендер на OpenGL или Vulkan. SFML — приятнее C++-стиль. Raylib — минимум настройки.


Подсистемы и расширения SDL2

ПодсистемаФлаг SDL_InitНазначение
VideoSDL_INIT_VIDEOОкно, события, renderer
AudioSDL_INIT_AUDIOВывод звука
JoystickSDL_INIT_GAMECONTROLLERГеймпады
Timerядро SDLSDL_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.

Сборка C++ — 1004, 1006.


Минимальный цикл на 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 — аналог SFML clear / 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 — короткий эффект.
  • MusicMix_LoadMUS / Mix_PlayMusic для фона.

Архитектура SDL-проекта

SDL хорошо сочетается с ECS (EnTT, Flecs): система ввода читает SDL_Event, система рендера — только draw. Игровой цикл — 22.


Когда выбирать SDL

СценарийSDL
Кроссплатформенный движок, эмуляторДа
Мобильный порт (Android/iOS)Да
Быстрая учебная 2D без CMake-магииЧасто проще Raylib
Desktop GUIQt
Windows-only низкоуровневый GPUDirectX

Частые ошибки

СимптомПричинаРешение
SDL_Init failedheadless сервер / нет дисплеяXvfb, локальный запуск
УтечкиCreate* без DestroyRAII
Размытые спрайтынекратный scaleinteger scale, SDL_ScaleModeNearest
OpenGL 1.x onlyнет loaderGLAD/GLEW после CreateContext

Что читать дальше