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

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

Запись от 8Observer8 размещена 11.02.2026 в 14:19. Обновил(-а) 8Observer8 03.03.2026 в 19:38
Показов 3371 Комментарии 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
Просмотров: 2006

Размер: 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
Просмотров: 2002

Размер: 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
Просмотров: 2051
Размер:	3.3 Кб
ID:	11523
Нажмите на изображение для увеличения
Название: 67b8b40c-6da7-4da4-86c1-06387b3c699e.png
Просмотров: 2058
Размер:	14.2 Кб
ID:	11524
Нажмите на изображение для увеличения
Название: 400251bc-e2e5-4f86-b58e-f554ac33f829.png
Просмотров: 2067
Размер:	4.8 Кб
ID:	11528
Вложения
Тип файла: zip start-native-png-loader-wasm-sdl3-c.zip (6.3 Кб, 51 просмотров)
Тип файла: zip SDL3-devel-3.4.0-wasm.zip (1.22 Мб, 85 просмотров)
Тип файла: zip right-arrow.zip (1.5 Кб, 43 просмотров)
Тип файла: zip finish-native-png-loader-wasm-sdl3-c.zip (6.4 Кб, 104 просмотров)
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru