Форум программистов, компьютерный форум, киберфорум
8Observer8
Войти
Регистрация
Восстановить пароль

SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли

Запись от 8Observer8 размещена 30.01.2026 в 23:45. Обновил(-а) 8Observer8 01.02.2026 в 01:01
Показов 2878 Комментарии 0

Содержание блога

Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а привычная функция main() отсутствует:
  • SDL_AppInit (Initialization) - эта функция срабатывает один раз самой первой.
  • SDL_AppEvent (Event Handler) - эта функция срабатывает каждый раз, когда происходит какое-то событие, например, нажатие клавиши, движение мышью, клик мышью, изменение размеров окна и т.д.
  • SDL_AppIterate (Main Loop) - эта функция срабатывает множество раз в секунду. Здесь можно рассчитать dt (delta time) и сделать анимацию, скорость которой не будет зависеть от числа кадров в секунду, который поддерживает монитор.
  • SDL_AppQuit (Clean up) - эта функция сработает один раз перед закрытием приложения. Здесь нужно располагать код для освобождения ресурсов.

Эти функции позволяют собирать один и тот же код для Android, Desktop и WebAssembly без лишних #ifdef и дублирования логики — например, без специфичного для браузера цикла при сборке через Emscripten.

Рассмотрим пример 01-clear в файле clear.c. Я попросил Gemini 3 перевести комментарии на русский, не меняя ничего в коде, даже отступы. Прочитайте этот код. Далее я пошагово опишу, как запустить его на Android:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
 * Этот пример кода создает окно и рендерер SDL, а затем очищает
 * окно разным цветом в каждом кадре, так что вы фактически получите окно,
 * цвет которого плавно меняется.
 *
 * Этот код является общественным достоянием. Не стесняйтесь использовать его в любых целях!
 */
 
#define SDL_MAIN_USE_CALLBACKS 1  /* использовать функции обратного вызова вместо main() */
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
 
/* Мы будем использовать этот рендерер для отрисовки в этом окне в каждом кадре. */
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
 
/* Эта функция запускается один раз при запуске. */
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
    SDL_SetAppMetadata("Example Renderer Clear", "1.0", "com.example.renderer-clear");
 
    if (!SDL_Init(SDL_INIT_VIDEO)) {
        SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
 
    if (!SDL_CreateWindowAndRenderer("examples/renderer/clear", 640, 480, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
        SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
    SDL_SetRenderLogicalPresentation(renderer, 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX);
 
    return SDL_APP_CONTINUE;  /* продолжаем выполнение программы! */
}
 
/* Эта функция запускается, когда происходит новое событие (ввод мыши, нажатия клавиш и т. д.). */
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
    if (event->type == SDL_EVENT_QUIT) {
        return SDL_APP_SUCCESS;  /* завершаем программу, сообщая ОС об успешном завершении. */
    }
    return SDL_APP_CONTINUE;  /* продолжаем выполнение программы! */
}
 
/* Эта функция запускается один раз за кадр и является сердцем программы. */
SDL_AppResult SDL_AppIterate(void *appstate)
{
    const double now = ((double)SDL_GetTicks()) / 1000.0;  /* преобразуем миллисекунды в секунды. */
    /* выбираем цвет для кадра, который будем рисовать. Трюк с синусоидой заставляет цвета плавно сменять друг друга. */
    const float red = (float) (0.5 + 0.5 * SDL_sin(now));
    const float green = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 2 / 3));
    const float blue = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 4 / 3));
    SDL_SetRenderDrawColorFloat(renderer, red, green, blue, SDL_ALPHA_OPAQUE_FLOAT);  /* новый цвет, полная непрозрачность. */
 
    /* очищаем окно цветом отрисовки. */
    SDL_RenderClear(renderer);
 
    /* выводим свежеочищенный рендер на экран. */
    SDL_RenderPresent(renderer);
 
    return SDL_APP_CONTINUE;  /* продолжаем выполнение программы! */
}
 
/* Эта функция запускается один раз при завершении работы. */
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
    /* SDL сама очистит окно/рендерер за нас. */
}
Далее мы по шагам рассмотрим, как собрать этот пример в WASM, запустить в браузере локально и загрузить на бесплатный хостинг Vercel из командной строки.

Если у вас не установлены Emscripten SDK и CMake, то установите их по следующей инструкции: Установка Emscripten SDK (emsdk) и CMake

  • Скачайте стартовый пример: hello-wasm-sdl3-c.zip
  • Проверьте работоспособность этого примера. В инструкции по установке Emscripten SDK мы запускали этот пример командами:
    Bash
    1
    2
    3
    
    config-web
    build-web
    http-server -c-1
  • Перейдите в браузер и введите адрес: localhost:8080 и нажмите Enter
  • Вы увидите результат работы программы в консоли браузера, если нажмёте: Ctrl+Shift+J в Chrome и Edge, либо Ctrl+Shift+K в FireFox
  • Запустите в корне папки проекта вторую консоль, чтобы дальше можно было переконфигурировать и собирать проект в этой консоли, а в первой консоли пусть запущен локальные сервер
  • Откройте скаченный пример в каком-нибудь редакторе кода, например, Notepad++, а лучше в Sublime Text 4: https://www.sublimetext.com/download
  • Скачайте архив SDL3-devel-3.4.0-wasm.zip. Эта библиотека была собрана из исходников с помощью Emscripten SDK 4.0.15
  • Создайте на каком-нибудь локальном диске папку "libs", например, на диске C и разархивируйте скаченный архив в папку "libs"
  • Укажем путь к этой библиотеке в файле CMakeLists.txt. Добавим find_package и target_link_libraries. Читайте комментарии:

    CMakeLists.txt

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    cmake_minimum_required(VERSION 3.21)
    project(hello-wasm-sdl3-c)
     
    # Задаем название будущего приложения (в Windows это был бы app.exe, а в вебе будет app.js / app.wasm)
    add_executable(app)
     
    # Устанавливаем стандарт C
    set(CMAKE_C_STANDARD 11)
     
    # Подсказываем CMake, где искать конфигурационные файлы библиотеки SDL3
    set(SDL3_DIR "C:/libs/SDL3-devel-3.4.0-wasm/lib/cmake/SDL3")
     
    # Загружаем настройки пакета SDL3 (параметры компиляции и пути к заголовкам)
    find_package(SDL3 REQUIRED)
     
    # Привязываем SDL3 к нашему приложению (настройка линковки и путей include)
    target_link_libraries(app PRIVATE SDL3::SDL3)
     
    # Добавляем исходный код к проекту
    target_sources(app
        PRIVATE
        src/main.c
    )
  • Сейчас в примере в файле main.c такой код:

    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    #include <stdio.h>
    #include <emscripten.h>
     
    void loop()
    {
        // Пусто
    }
     
    int main()
    {
        printf("Привет из WebAssembly на Vercel!\n");
        emscripten_set_main_loop(loop, 0, 1); // Это не даст программе закрыться
        return 0;
    }
  • Заменим этот код на код из официального примера, который был показан в начале этого сообщения (пример 01-clear)
  • Откройте в редакторе кода файл "public/index.html" и добавьте элемент <canvas> и удалите элемент <title> (потому что Title задаются в функции SDL_CreateWindowAndRenderer - в первом аргументе этой функции):

    index.html

    PHP/HTML
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    <!DOCTYPE html>
     
    <html>
     
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
     
    <body>
        <canvas id="canvas"></canvas>
     
        <script async src="./js/app.js"></script>
    </body>
  • Введите команды конфигурирования и сборки (на самом деле можно команду build-web, а конфигурирование произойдёт по автомату, потому что CMake проверяет не был ли изменён файл CMakeLists.txt)
    Bash
    1
    2
    
    config-web
    build-web
  • Перейдите в браузер и введите адрес: localhost:8080 и нажмите Enter
  • Обратите внимание, что локальный сервер http-server выводит адреса, например, у меня:
    Code
    1
    2
    3
    4
    5
    
    Available on:
      http://100.116.245.193:8080
      http://192.168.56.1:8080
      http://127.0.0.1:8080
    Hit CTRL-C to stop the server[*]Вы можете взять телефон, который подключён к Wi-Fi и ввести в его браузере адрес 192.168.56.1:8080 и приложение запустится на Android[*]Загрузите это веб-приложение на бесплатный хостинг Vercel по следующей инструкции: [URL="https://www.cyberforum.ru/blogs/416874/10735.html"]Установка Emscripten SDK (emsdk) и CMake[/URL] (пролистайте до "Загрузка веб-приложения на бесплатный хостинг Vercel")
Вложения
Тип файла: zip hello-wasm-sdl3-c.zip (2.8 Кб, 52 просмотров)
Тип файла: zip SDL3-devel-3.4.0-wasm.zip (1.22 Мб, 58 просмотров)
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Новые блоги и статьи
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru