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

SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)

Запись от 8Observer8 размещена 11.02.2026 в 14:19. Обновил(-а) 8Observer8 03.03.2026 в 19:38
Показов 3951 Комментарии 0

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

Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным фоном) встроенными средствами библиотеки SDL3. Финальная демка запускается в браузерах на Desktop (Windows, Linux, macOS) и в браузерах на мобильных устройствах (Android и iOS). Исходники результата: finish-native-png-loader-wasm-sdl3-c.zip

Подключение библиотек SDL3 к стартовому примеру



  • Установите Emscripten 4.0.15 и CMake по инструкции: Установка Emscripten SDK (emsdk) и CMake
  • Скачайте стартовый пример: start-native-png-loader-wasm-sdl3-c.zip

    Название: 1f4b01ca-4d6d-4c22-8b66-ce91259de101.png
Просмотров: 2059

Размер: 4.9 Кб
  • Код стартового примера:

    src/main.c

    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
    
    #define SDL_MAIN_USE_CALLBACKS 1 // Use the callbacks instead of main()
     
    #include <SDL3/SDL.h>
    #include <SDL3/SDL_main.h>
    #include <stdio.h>
     
    static SDL_Window *window = NULL;
    static SDL_Renderer *renderer = NULL;
     
    SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
    {
        if (!SDL_Init(SDL_INIT_VIDEO))
        {
            SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
     
        if (!SDL_CreateWindowAndRenderer("Example", 400, 400, 0, &window, &renderer))
        {
            SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
     
        SDL_SetRenderVSync(renderer, 1);
     
        return SDL_APP_CONTINUE;
    }
     
    SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
    {
        if (event->type == SDL_EVENT_QUIT)
        {
            return SDL_APP_SUCCESS; // End the program, reporting success to the OS
        }
     
        return SDL_APP_CONTINUE;
    }
     
    SDL_AppResult SDL_AppIterate(void *appstate)
    {
        // Clear the screen
        SDL_SetRenderDrawColor(renderer, 100, 100, 100, 255);
        SDL_RenderClear(renderer);
     
        // Draw here...
     
        // Update the screen
        SDL_RenderPresent(renderer);
        return SDL_APP_CONTINUE;
    }
     
    void SDL_AppQuit(void *appstate, SDL_AppResult result)
    {
        // SDL will clean up the window/renderer for us
    }
  • Откройте папку со стартовым примером в какой-нибудь редакторе кода, например, в Notepad++ или в Sublime Text 4 (ST4): https://www.sublimetext.com/download
  • Скачайте библиотеку SDL3: SDL3-devel-3.4.0-wasm.zip
  • Извлеките содержимое архива в какую-нибудь новую общую папку, например, с именем "libs" на какой-нибудь диск, например, на C. Таким образом, создайте на диске C папку "lib", скопируйте в неё архивы и извлеките их в текущую папку:
  • Откройте папку "SDL3-devel-3.4.0-wasm", перейдите в папку "lib/cmake/SDL3" и скопируйте абсолютный путь:
  • В файле CMakeLists.txt стартового примера создайте переменную SDL3_DIR и установите ей значение скопированного пути, заменив обратные слеши на прямые:
    Bash
    1
    
    set(SDL3_DIR "C:/libs/SDL3-devel-3.4.0-wasm/lib/cmake/SDL3")
  • К этому моменту CMakeLists.txt выглядит так:

    Bash
    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
    
    cmake_minimum_required(VERSION 3.21)
    project(start-load-png-wasm-sdl3-c)
     
    # Задаем название будущего приложения (в Windows это был бы app.exe, а в вебе будет app.js / app.wasm)
    add_executable(app)
     
    # Устанавливаем стандарт C
    set(CMAKE_C_STANDARD 11)
     
    # Указываем точное местоположение конфигурационных файлов библиотеки SDL3
    # Имя переменной должно строго соответствовать: НазваниеБиблиотеки_DIR
    set(SDL3_DIR "C:/libs/SDL3-devel-3.4.0-wasm/lib/cmake/SDL3")
     
    # Проверяем наличие библиотек в системе
    # Если она не будет найдены, CMake прервет настройку с ошибкой
    # REQUIRED - переводится, как «обязательно» или «требуется»
    find_package(SDL3 REQUIRED)
     
    # Привязываем библиотеки к нашему приложению (настройка линковки и путей include)
    target_link_libraries(app PRIVATE SDL3::SDL3)
     
    # Добавляем исходный код к проекту
    target_sources(app
        PRIVATE
        src/main.c
    )

Тестовая сборка и тестовый запуск стартового примера в браузере на локальном хостинге



  • Откройте консоль (CMD) в корне стартового примера. Для этого можете просто в адресной строке папки (там где путь) написать "cmd" (без кавычек) и нажать Enter
  • В CMD введите команду для конфигурирования:
    Bash
    1
    
    config-web
  • Примечание. "config-web" - это имя bash-файла (батника), который находится в корне папки стартового примера
  • В CMD введите команду сборки проекта:
    Bash
    1
    
    build-web
  • Собранные файлы (app.js и app.wasm) будут скопированы в папку "public/js" (папка "public" лежит в корне проекта)
  • В корне проекта запустите локальный сервер командой:
    Bash
    1
    
    http-server -c-1
  • Примечание 1. Будут выведены адреса:
    Bash
    1
    2
    3
    4
    
    Available on:
      http://192.168.1.65:8080
      http://127.0.0.1:8080
    Hit CTRL-C to stop the server
  • Примечание 2. Адрес 192.168.1.65:8080 можно использовать для запуска приложения на мобильном устройстве, если у вас есть Wi-Fi - просто вводите этот адрес в браузере мобильного устройства и приложение запустится. Если интересен запуск на мобильном устройстве, то пройдите пошаговую инструкцию: Основы отладки веб-приложений на SDL3 по USB и Wi-Fi
  • Откройте новую вкладку в браузере. Если у вас Chrome или Edge, то нажмите Ctrl+Shift+J, чтобы открыть консоль браузера для контроля вывода информации. Если у вас FireFox, то нажмите Ctrl+Shift+K
  • Перейдите по адресу:
    Bash
    1
    
    localhost:8080
  • Примечание. Обновлять страницу после пересборки проекта лучше с очисткой кэша браузера. Для этого (обязательно с открытой консолью браузера) в браузере Chrome нужно найти в левом верхнем углу браузера кнопку обновления страницы (круговая стрелка), нажать по ней правой кнопкой мыши и выбрать "Empty Cache and Hard Reload"
  • В браузере должен выводиться квадрат тёмного-серого цвета - это холст для рисования. Приложение должно собраться и запуститься без ошибок

Добавление файла изображения в проект



  • Скачайте PNG-файл с прозрачным фоном: right-arrow.zip
  • Примечание. Это бесплатный файл, который был взят по ссылке
  • Внутри папки стартового примера создайте вложенную папку "assets/images" и скопируйте в неё скаченный файл:
  • Откройте файл CMakeLists.txt в редакторе кода и скопируйте в него (в конец файла) код для встраивания изображения в файл "app.wasm":
    Bash
    1
    2
    3
    4
    5
    6
    
    # Встраиваем изображение в файл app.wasm
    if (EMSCRIPTEN)
        target_link_options("app" PRIVATE "SHELL:--embed-file \"${CMAKE_CURRENT_SOURCE_DIR}/assets/images/right-arrow.png@/assets/images/right-arrow.png\"")
     
        set_property(TARGET "app" APPEND PROPERTY LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/assets/images/right-arrow.png")
    endif()
  • Изображение добавлено в проект. Таким же образом вы можете добавлять и другие файлы: звуковые файлы, файлы шрифтов и т.д.

Написание кода для вывода изображения



Лучше всего код набирать вручную, а не копировать, чтобы он лучше запоминался и в дальнейшем было проще и проще с ним работать. Мы напишем код пошагово - строка за строкой.

  • Откройте файл src/main.c в редакторе кода
  • Напишите код создания переменной указателя: texture после создания окна (window) и рисовальщика (renderer):
    C
    1
    2
    3
    
    static SDL_Window *window = NULL;
    static SDL_Renderer *renderer = NULL;
    static SDL_Texture *texture = NULL;
  • Примечание 1. Ключевое слово static означает, что имя переменной-указателя будет видимо только в пределах файла.
  • Примечание 2. Для того, чтобы избежать глобальных переменных нужно использовать аргумент appstate (первый аргумент всех 4-x callback-функции SDL3), как в прикреплённом примере этой инструкции по нативной сборки для Android: SDL3 для Android: Работа со звуком через SDL3_mixer
  • Лучше сразу, чтобы не забыть, написать код уничтожения текстуры перед закрытием приложения в функции SDL_AppQuit():
    C
    1
    2
    3
    4
    5
    6
    
    void SDL_AppQuit(void *appstate, SDL_AppResult result)
    {
        // SDL will clean up the window/renderer for us
     
        SDL_DestroyTexture(texture);
    }
  • В начале файла main.c найдите функцию SDL_AppInit(), которая вызывается один раз самой первой:
    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
    {
        if (!SDL_Init(SDL_INIT_VIDEO))
        {
            SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
     
        if (!SDL_CreateWindowAndRenderer("Example", 400, 400, 0, &window, &renderer))
        {
            SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
     
        SDL_SetRenderVSync(renderer, 1);
     
        return SDL_APP_CONTINUE;
    }
  • На данный момент здесь в начале происходит инициализация библиотеки SDL3 с помощью вызова функции SDL_Init():
    C
    1
    2
    3
    4
    5
    
        if (!SDL_Init(SDL_INIT_VIDEO))
        {
            SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
  • Далее создаются окно и рисовальщик с помощью вызова функции SDL_CreateWindowAndRenderer()
  • Вызов функции SDL_SetRenderVSync() включает синхронизацию, то есть вызов функции SDL_AppIterate() будет происходить с той же частотой, с которой работает монитор компьютера
  • После функции SDL_SetRenderVSync() добавьте код загрузки файла-изображения и создания текстуры:
    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
        const char *texturePath = "./assets/images/right-arrow.png";
        SDL_Surface *surface = SDL_LoadPNG(texturePath);
        if (!surface)
        {
            SDL_Log("PNG load failed: %s: %s\n", texturePath, SDL_GetError());
            return SDL_APP_FAILURE;
        }
     
        texture = SDL_CreateTextureFromSurface(renderer, surface);
        SDL_DestroySurface(surface);
  • В функции SDL_AppIterate() добавьте код вывода изображения:
    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    SDL_AppResult SDL_AppIterate(void *appstate)
    {
        // Clear the screen
        SDL_SetRenderDrawColor(renderer, 100, 100, 100, 255);
        SDL_RenderClear(renderer);
     
        SDL_FRect srcRect = { 0, 0, 512, 512 };
        SDL_FRect destRect = { 50, 50, 100, 100 };
        SDL_RenderTexture(renderer, texture, &srcRect, &destRect);
     
        // Update the screen
        SDL_RenderPresent(renderer);
        return SDL_APP_CONTINUE;
    }
  • Сделаем сборку кода и запуск приложения. Сейчас у вас должен быть запущен локальный сервер от тестовой сборки вначале инструкции. Если нет, то запустите локальный сервер в корне проекта из CMD:
    Bash
    1
    
    http-server -c-1
  • Откройте ещё одну консоль внутри папки проекта и выполните команду:
    Bash
    1
    
    build-web
  • Примечание. Не нужно выполнять команду "config-web", потому что её требуется вводить только один раз, а далее CMake будет сам проверять перед сборкой были ли изменения в CMakeLists.txt и если изменения были, то CMake сам переконфигурирует проект
  • Если вы закрыли вкладку браузера, то откройте новую, нажмите Ctrl+Shift+J в Chrome/Edge (Ctrl+Shift+K) в FireFox и обновите страницу
  • Примечание. Можете подключить смартфон по USB-кабелю и протестировать код: Основы отладки веб-приложений на SDL3 по USB и Wi-Fi Если вы уже пробовали, то перейдите на компьютере по адресу chrome://inspect/#devices Найдите приложение в списке и нажмите "inspect". Вы увидите экран смартфона на компьютере
  • В браузере да Desktop и в браузере на мобильном вы увидите результат работы приложения:
    Название: c1383c69-8591-4a3d-b81e-a068130d5870.png
Просмотров: 2073

Размер: 1.0 Кб

Сборка в релиз



  • Для сборки в релиз нужно открыть файл "config-web.bat" в редакторе кода и исправить Debug на Release:

    config-web.bat

    Bash
    1
    
    emcmake cmake -S . -B dist -DCMAKE_BUILD_TYPE=Release
  • Выполните команды конфигурирования и сборки:
    Bash
    1
    2
    
    config-web
    build-web
  • Примечание. Вес файлов после сборки в Debug:
    Code
    1
    2
    
    app.js - 376 KB
    app.wasm - 1.37 MB
    Вес файлов после сборки в Release:
    Code
    1
    2
    
    app.js - 183 KB
    app.wasm - 803 KB

Развёртывание на бесплатном хостинге Vercel



  • Скачайте установщик Node.js и установите: https://nodejs.org/en/download
  • Установите Vercel следующей командой из консоли глобально:
    Bash
    1
    
    npm i vercel -g
  • Зарегистрируйтесь на Vercel: https://vercel.com/
  • Примечание. В стартовом прмер, который скачали в начале, уже есть файл vercel.json для решения проблемы с загрузкой wasm-файла
  • В консоле в корне проекта выполните команду:
    Bash
    1
    
    vercel login
  • Выполните команду:
    Bash
    1
    
    vercel
  • Примечание. Будут заданы вопросы в консоли - просто нажимайте всегда Enter
  • В консоль будет выведен адрес вашего приложения: https://start-native-png-loade... vercel.app
  • Примечание. Когда вы что-то измените в проекте и захотите загрузить изменённое приложение на сервер, то введите команду:
    Bash
    1
    
    vercel --prod

Миниатюры

Нажмите на изображение для увеличения
Название: ef3d275d-68a8-48e3-8534-78a8fed6dce8.png
Просмотров: 2147
Размер:	3.3 Кб
ID:	11523
Нажмите на изображение для увеличения
Название: 67b8b40c-6da7-4da4-86c1-06387b3c699e.png
Просмотров: 2171
Размер:	14.2 Кб
ID:	11524
Нажмите на изображение для увеличения
Название: 400251bc-e2e5-4f86-b58e-f554ac33f829.png
Просмотров: 2160
Размер:	4.8 Кб
ID:	11528
Вложения
Тип файла: zip start-native-png-loader-wasm-sdl3-c.zip (6.3 Кб, 73 просмотров)
Тип файла: zip SDL3-devel-3.4.0-wasm.zip (1.22 Мб, 114 просмотров)
Тип файла: zip right-arrow.zip (1.5 Кб, 75 просмотров)
Тип файла: zip finish-native-png-loader-wasm-sdl3-c.zip (6.4 Кб, 234 просмотров)
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru