Форум программистов, компьютерный форум, киберфорум
C (Си)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
0 / 0 / 0
Регистрация: 07.01.2013
Сообщений: 7

Подключаюсь к Си, пишу свой движок для игр

11.01.2025, 21:29. Показов 6118. Ответов 24

Студворк — интернет-сервис помощи студентам
Здравствуйте ребята.
Вливаюсь в Си.
Сам опытный разработчик с 13 годами стажа.
Делаю игры на Unity год назад сделал там свой движок и делал игры этот год только на нем.

Вот решился написать следующую версию без Unity с нуля так сказать.

Начал хорошо, написал корень движка, с первых секунд влюбился в язык Си - он волшебный!
Но вот беда, возникают проблемы с подключением библиотек, каждой что то свое надо.
SDL2, OpenGL, Glew подключить вышло и теперь даже знаю порядок что да как делать.

И настало время поработать с UI в виду того что Nucklear написан на Си без привязки к C++ и довольно обширен, решил воспользоваться им. Но большая беда с ним, он не хочет работать, очень много разных ошибок собака выводит.

В итоге я вроде понял что надо просто файл nuclear.h закинуть в проект и путь к нему указать.
Но все равно все время какие то проблемы возникают и так я и не вывел все еще ничего из него на экран.


Буду весьма благодарен если получу помощь, может совет какой по смене nuklear на что то более подходящее.

Отговаривать и говорить что глупо писать свой движок не надо)) все знаем и учитываем и решение принято на очень трезвую голову и со смыслом.

Если опытный человек в Си помог бы при звонке, ответив на вопросы то я бы с радостью оплатил бы данную помощь.
Буду очень рад желающим.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.01.2025, 21:29
Ответы с готовыми решениями:

Движок для игр
Всем привет!!!, хотел узнать возможно ли создать движок на C++ чтобы экспортировать модели из 3ds...

Движок для игр на основе С++
Всем привет. Подскажите движок для создания игр на основе с++. Без встроенных графических...

Подскажите пожалуйста движок для создания игр с пониманием основ языка Cи и С++.
Подскажите пожалуйста движок для создания игр с пониманием основ языка Cи и С++. Для начала, с чего...

24
Невнимательный
 Аватар для ft4l
2835 / 1254 / 357
Регистрация: 08.02.2013
Сообщений: 7,300
Записей в блоге: 2
11.01.2025, 22:03
Цитата Сообщение от Camad Посмотреть сообщение
просто файл nuclear.h закинуть в проект и путь к нему указать.
гуглятся нюансы какие-то
https://stackoverflow.com/ques... -c-project
nuklear.h can be included in either implementation mode or header-only mode,
...
... optional flags ...
...
#define NK_IMPLEMENTATION //< Include nuklear in implementation mode
#include "nuklear.h"
там-же, до этого, какие-то обяснения как из одного src/nuklear.h делают другой ,) видимо этот самый nuklear.h
0
267 / 199 / 30
Регистрация: 26.11.2022
Сообщений: 859
11.01.2025, 23:30
Цитата Сообщение от Camad Посмотреть сообщение
о большая бида с ним, он не хочет работать, очень много разных ошибок собака выводит.
какие?


Цитата Сообщение от Camad Посмотреть сообщение
Но все равно все время какие то проблемы возникают и так я и не вывел все еще ничего из него на экран.
Начинать надо с того что из примеров взять готовый кусок рендерера - ибо что для nuklear что для imgui вывод изображения это самостоятельный кусок кода.
так что выбираете с чем компилите - SDL или glfw , нативные API, версию и пр. и просто переносите в свой проект.
Потом сможете доработать.

из библиотек для ГУЯ лично мне больше imgui понравился, под мои задачи подошел как нельзя лучше. Хотя я на С пишу но прикрутить одно к другому не проблема. но в imgui всё красивее из коробки и есть дополнительный сторонний функционал: implot и imguifiledialog которые мне очень нужны были.

Цитата Сообщение от Camad Посмотреть сообщение
Но овт беда, возникают проблемы с подключением библиотек, каждой что то свое надо.
как прикручивали? вроде там всё довольно прямолинейно.
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,292
Записей в блоге: 2
12.01.2025, 11:29
Цитата Сообщение от Camad Посмотреть сообщение
влюбился в язык Си
И каждый чих придется писать самому. Помнится фраза, если в С++ легко прострелить себе ногу, то в Си для этого надо будет сначала создать ногу, ружье и патроны к нему, а только потом простреливать себе ногу. Если код не для МК, то лучше уж на С++, ООП, контейнеры и умные указатели сильно упростят жизнь, да и либ побольше будет. Движок это не только графика, но и сеть, звук, физика, менеджмент ресурсов, логгирование, многопоточность, тесты
Цитата Сообщение от Camad Посмотреть сообщение
SDL2, OpenGL, Glew
Тоже странный выбор, SDL это 2д графика и создавать контекст OpenGL для версий выше первой придется дополнительно, хотя в UE используется SDL. Тогда уж лучше использовать связку GLFW (окна), GLAD (загрузчик OpenGL, header only), GLM (математика, матрицы) и STB (картинки, шрифты)
Хотя stb можно заменить на другие, но тогда под каждый формат придется использовать свое, например libpng и libjpg для png и jpg, freetype для шрифтов, zlib как зависимость и для сжатия, для звука libogg или vorbis, для моделей fbxsdk для fbx или универсальный assimp, для json nlohman-json, для звука OpenAL, для физики PhysX или Bullet для 3д или Box2D для 2д и тд.
Цитата Сообщение от Camad Посмотреть сообщение
возникают проблемы с подключением библиотек
Для этого надо использовать системы сборки, например CMake
Про nucklear уже написали, что надо к нему добавлять (либо если есть из либы, либо писать самому) реализацию для графического апи и для создания окна. В этом плане imgui куда приятнее и постоянно обновляется, хотя так же требует тех же реализаций. Но все эти immediate mode гуи прилично портят состояние рендера, которое надо постоянно восстанавливать, имхо от этого только падение фпс и в релизе я бы ничего подобного не использовал, лучше самому написать гуй, тем более в играх он не сложный и обычно отличается от обычных
0
267 / 199 / 30
Регистрация: 26.11.2022
Сообщений: 859
12.01.2025, 12:59
alecss131, SDL оно очень сильно нужно и не только для контекста GL, что для кросплатформенности уже достаточно сложно сделать. Не забывайте прежде всего про то что SDL кросплатформенная и даёт унифицированный интерфейс к клавиатуре, мыши, джойстикам, звуку, таймерам, потокам, мьютексам и пр.

в GLFW есть небольшие траблы с клавиатурой - там не всё прям сразу работает при переключении раскладки (я не говорю про винду). Если в игре предусмотрен чат и надо будет что-то писать по русски то лучше обратить на это внимание.

GLM - вы это серьёзно в разделе языка С предлагаете ? для С подходит https://github.com/HandmadeMath/HandmadeMath

Вот STB это кладезь знаний того как писать на С. так же много вснего можно подсмотреть в исходный кодах https://github.com/nothings/single_file_libs

Для обучения очень хорошо https://kohiengine.com/ как раз движек на С и вулкане. выкачивайте с ютуба ))
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,292
Записей в блоге: 2
12.01.2025, 13:11
Цитата Сообщение от Aledveu Посмотреть сообщение
в игре предусмотрен чат
все прям так пишут онлайн игры...
Цитата Сообщение от Aledveu Посмотреть сообщение
GLM - вы это серьёзно в разделе языка С предлагаете ?
Для Си есть cglm
после плюсов непривычно, но когда привыкнешь, то удобно
Цитата Сообщение от Aledveu Посмотреть сообщение
на С и вулкане
куда еще ниже?
0
0 / 0 / 0
Регистрация: 07.01.2013
Сообщений: 7
12.01.2025, 13:44  [ТС]
Ого вы активные. Спасибо всем!
nuklear выбрал по той причине что он написан на Си и если честно его визуал мне больше понравился.

Не уж то действительно в продакшен его пускать нельзя? И все пилят свое?

Пилить свое меня соблазнило. Единственное шрифты напрягают.
0
9035 / 2936 / 493
Регистрация: 05.10.2013
Сообщений: 7,958
Записей в блоге: 216
01.06.2025, 10:08
Цитата Сообщение от alecss131 Посмотреть сообщение
Тоже странный выбор
Почему SDL - это странный выбор? По каким критериям SDL хуже, чем GLFW? Я знаю только один критерий - это вес. Например, текущий релиз SDL 3.2.14, который вышел 2 недели назад, имеет архив под названием SDL3-3.2.14-win32-x64.zip c SDL3.dll весом 2.34 MB. А текущий релиз GLFW 3.4 под названием glfw-3.4.bin.WIN64.zip (lib-mingw-w64), который вышел 23 февраля 2024 года, то есть 1 год и 5 месяцев назад, имеет размер 298 KB. Вот этого я не понимаю, почему нельзя было сделать отдельный релиз SDL, где было только API SDL для работы низкоуровневый графических API, то есть, создание окна и контекста для OpenGL, Vulkan, DirectX, Metal и т.д. Мне, например, не нужен графический API SDL для рисования 2d графики - это даже нельзя убрать в CMake-GUI при сборке SDL из исходников. Точнее, лишние галочки убрать можно, но вес SDL3.dll будет больше или равен, чем текущий размер 2.34 MB. Я пытался это выяснить у разработчиков SDL на официальном сервере Discord (запрещён в РФ) и как-то повлиять на них, но ничего не получилось. Но с другой стороны даже если создать 100 штук EXE у себя на компьютере, то эти 2.34 MB не будут раздуты до 200 MB, потому что папку c SDL3.dll можно добавить в переменную окружения PATH на Windows. К тому же при распространении приложений на SDL, если добавить несколько файлов шрифтов, картинок, звуковых файлов и т.д., то эти 2.34 MB теряются на фоне веса ассетов.

Цитата Сообщение от alecss131 Посмотреть сообщение
SDL это 2д графика и создавать контекст OpenGL для версий выше первой придется дополнительно
Я не понял этот аргумент против SDL. Да, SDL имеет API для 2D графики, как дополнение к возможности создания окна для OpenGL, Vulkan и т.д. То есть SDL позволяет создать окно, где можно использовать графический API SDL, так называемый "рисовальщик":
C
1
2
3
4
5
6
7
8
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
 
int main()
{
    SDL_CreateWindowAndRenderer("Example", 500, 500, 0, &window, &renderer);
    return 0;
}
Но при этом SDL - это не только 2D API для рисования графики, но это ещё и:
  • рисование текста с помощью SDL3_ttf
  • работа со звуком с помощью SDL_mixer
  • работа со спрайтами и спрайтовой анимацией с помощью SDL_image
  • работа с сетью с сокетами с помощью SDL_net, например, для создания мультилеера и кооператива в играх, либо для работы неигровых клиент-серверных приложений
При этом если не нужен графический 2D SDL API, а хочется рисовать с помощью OpenGL, то можно создать окно и контекст для OpenGL:

C
1
2
3
4
5
6
int main()
{
    SDL_Window *window = SDL_CreateWindow("Example", 500, 500, SDL_WINDOW_OPENGL);
    SDL_GLContext glContext = SDL_GL_CreateContext(window);
    return 0;
}
Окно и контекст создаются не дополнительно, а вместо рисовальщика. Мы ещё дополнительно получаем возможность работы со звуком с помощь SDL3_mixer и работу с сокетами с помощью SDL_net. В любом случае, что в SDL, что в GLFW нужно подключать GLAD или GLEW для работы с шейдерным OpenGL для сборки для Desktop. Кстати, для сборки для Android и WebAssembly на SDL не нужен GLAD для работы с шейдерным OpenGL.

Я не вижу в чём SDL уступает GLFW, а вот в GLFW я нашёл недостатки для себя:
  • У GLFW отсутствует официальный Discord сервер (Discord запрещён в РФ). У SDL есть очень активный сервер, где частенько отвечают даже самые главные разработчики SDL. Много студентов. Можно практиковать английский, спрашивая или помогая кому-то, либо читая переписки
  • SDL имеет намного более активный официальный форум. Если открыть официальный форум GLFW, то можно увидеть, что там 3 активных темы за месяц, а в темах отвечает в основном один единственный модератор
  • GitHub репозиторий SDL на порядки более активный
  • У SDL официальная поддержка Android (про iOS не знаю) и WebAssembly. Есть уже собранная библиотека в релизах SDL для работы с Android. Я подключал её и собирал APK для Android. Есть официальный скрипт на Python для создания библиотеки SDL для Android из исходников - тоже собирал. Собирал в WebAssembly - тоже всё просто. У SDL реализовано API для работы с Android - без костылей, как у SFML, а на GLFW я не пробовал собирать под Android и в WebAssembly. Есть какие-то неофициальные инструкции, но официально Android на GLFW не поддерживается. Я нашёл тему, где модератор официального форума GLFW (он же один из главных разработчиков GLFW) написал в 2019 году, что поддержку Android и iOS не стоит ожидать в ближайшее время, потому что слишком много работы предстоит: How to use GLFW with OpenGL ES (Android), а GLFW изначально делалась как Desktop only
  • Дополнительно у SDL есть графический 2D API, работа со звуковыми файлами, шрифтами, спрайтовой анимацией, примитивная физика определения столкновений AABB, то есть определение столкновений прямоугольников выровненных по осям координат - то есть без углов поворота
  • Есть ещё новшество под названием SDL_gpu, но я его не пробовал. Мне достаточно OpenGL и WebGL

Цитата Сообщение от Camad Посмотреть сообщение
Начал хорошо, написал корень движка, с первых секунд влюбился в язык Си - он волшебный!
Если корень движка готов, то значит уже есть опыт работы с SDL, но было бы очень странно выбросить этот опыт и потраченное время и переключаться на GLFW. Мало того, что выбросить потраченное время на SDL, так ещё и потратить время, чтобы изучить заново другой API на GLFW. Скорее всего, используется OpenGL 1 - под корнем движка я понимаю вывод картинок, звука, collision detection, обработку нажатий клавиш и мыши. Не вижу причин переходить на GLFW. Можно было бы вообще тренироваться сначала на Си и графическом 2D SDL API, плюс взять SDL3_ttf, SDL3_mixer, SDL3_image. Лучше всего перед C++ хорошенько поработать с Си - не будете отвлекаться на ООП, а проработаете основы, которые пригодятся в C++. Ни одну или две игровые демки переписать и забросить на долгие годы, а писать много демок и совершенствовать их по мере получения знаний и опыта. В первую очередь надо брать физический движок Box2D v3, который был несколько лет назад подностью переписан с C++ на Си. Вы увидите насколько сильно похожа работать с Box2D на работу с Unity. Можно тренироваться переписывая игровые демки с Unity на SDL на сайте NoobTuts Unity. Главное, не просто переписать, а регулярно добавлять что-то своё. У меня есть короткие примеры на PySDL3: https://github.com/Aermoss/PySDL3/discussions/18 и PyOpenGL: https://github.com/Aermoss/PySDL3/discussions/23

Цитата Сообщение от Camad Посмотреть сообщение
Пилить свое меня соблазнило. Единственное шрифты напрягают.
Ничего сложного в шрифтах нет, если с правильно стороны заходить. Надо взять программу Hiero и конвертировать TTF в BMFont. BMFont - это текстурный атлас букв + текстовый файл с текстурными координатами и отступами. Вам надо уметь только накладывать текстуру на прямоугольник. Каждая буква - это отдельный прямоугольник с наложенной на него текстурой из атласа букв. У меня есть пример на PySDL3 и шейдерном OpenGL, который рисует текст на русском и английском. Можете переписать на Си с помощью ChatGPT или DeepSeek



Миниатюры
Вложения
Тип файла: zip hello-world-text-opengl-pysdl3-python.zip (294.1 Кб, 0 просмотров)
0
9035 / 2936 / 493
Регистрация: 05.10.2013
Сообщений: 7,958
Записей в блоге: 216
01.06.2025, 10:27
Цитата Сообщение от Camad Посмотреть сообщение
И настало время поработать с UI в виду того что Nucklear написан на Си без привязки к C++ и довольно обширен, решил воспользоваться им. Но большая бида с ним, он не хочет работать, очень много разных ошибок собака выводит.
Репозиторий Nucklear в архиве с 2019 года. Это значит, что он не поддерживается уже 6 лет. Может в будущем его разморозят и опять начнут поддерживать. Лучше его пока не использовать, потому что вы не сможете создавать Issue на официальном репозитории, то есть заявлять об ошибках, которые бы исправили в новых версиях. Заморозка ещё означает, что, скорее всего, многое кто его использовал стали использовать что-то другое, а новые пользователи не решаются его использовать. В этом случае, когда у вас возникают проблемы, то находится намного меньше людей, кто бы мог помочь решить текущую проблему в изучении библиотеки. Можно было бы взять "cimgui" - это порт ImGui с C++ на C, но, я считаю, что ImGUI плохо подходит для игр - это скорее для CAD, а не игр. Лучше качайте готовые GUI ассеты с itch - гуглите "itch gui assets": https://itch.io/game-assets/tag-gui На панели слева кликните Free и вы увидите сколько там готовых ассетов для GUI. Если текст научились рисовать, то сделать кнопку проще простого - кнопка это текстуры, которые меняются в зависимости от положения и состояния мыши. То есть нажали - показали текстуру нажатия. Это очень полезно в плане обучения - учиться делать минимально необходимый GUI для текущих своих игр. Вам не нужно ставить цель написать универсальный GUI фреймворк, а вам нужно, допустим, кнопка "Start Game", тект отображения жизней, прогресс бар, радио кнопка и т.д. - это всё делается элементарно, это надо учиться и уметь делать на простых играх.

https://itch.io/game-assets/tag-gui (Free)



Миниатюры
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,292
Записей в блоге: 2
01.06.2025, 12:20
Цитата Сообщение от 8Observer8 Посмотреть сообщение
По каким критериям SDL хуже, чем GLFW?
Ну как минимум тем, что у него есть своя инициализация без которой эта либа не работает. И эта инициализация требует своей точки входа, не всегда так можно сделать. Да и звук там только 2д, для 3д нужно иное уже подключать.
Кроссплатформенность мне не интересна, но по той же ссылки где написано про поддержку андроида, есть ссылка на гит где люди показывали рабочий пример на андроиде. Еще я помню создавал контекст для GLES, хоть это было на винде и для запуска требовался транслятор, но поддержка этого есть, значит по сути поддержка андроида уже есть.
Сборка натива для веба считаю бредятиной, думаю найдутся умельцы, а точнее извращенцы, которые соберут нативы под веб, а потом это упакуют в электрона для запуска вне браузера. В любом случае это прикручивание виртуальной машины для исполнения нативного кода.
Про iOS не знаю, особенно что с С/С++ и OpenGL под него, так как там основные языки это ObjC и Swift, хотя про первый уже не уверен. Там и Swift с апи Metal приятнее будут.
И кстати на андроиде для звука есть свое апи, так что никакой OpenAL не нужен, там это OpenSL ES
0
9035 / 2936 / 493
Регистрация: 05.10.2013
Сообщений: 7,958
Записей в блоге: 216
01.06.2025, 14:37
Цитата Сообщение от alecss131 Посмотреть сообщение
Ну как минимум тем, что у него есть своя инициализация без которой эта либа не работает. И эта инициализация требует своей точки входа, не всегда так можно сделать.
Я не настолько глубоко изучил SDL3. Использую её год. Работаю с SDL3 только для сборки EXE для Windows, APK для Android и WebAssembly для запуска в браузере, чтобы ассеты было тяжело изъять. При каких условиях невозможно инициализировать SDL3? На каких платформах? На игровых приставках? Возможно имеется ввиду точка входа на Android и WebAssembly, то да, в этом случае в SDL2 были проблемы со сложностью реализации, на Android и в браузере. В SDL3 появилась отдельная callback-функция для инициализации - SDL_AppInit(), которая автоматически вызывается один раз для инициализации. Функция main() скрыта для программиста. При включенном режиме SDL_MAIN_USE_CALLBACKS всего должно быть определено четыре функции:
  • SDL_AppInit() - вызывается один раз самой первой в самом начале работы приложения. Здесь можно сделать инициализацию SDL3, OpenGL, загрузку ассетов и т.д.
  • SDL_AppEvent() - вызывается, когда происходит какое либо событие, например, нажатие клавиши клавиатуры, клик мыши, касание экрана смартфона и т.д.
  • SDL_AppIterate() - вызывается для отрисовки кадра много раз в секунду, например, 60 раз в секунду, если активировать вертикальную синхронизацию, а монитор поддерживает 60 FPS
  • SDL_AppQuit() - вызывается перед завершением приложение. Здесь можно освободить выделенные ресурсы

Эти функции позволяют один и тот же код ниже, который просто красит холст на OpenGL, собирать для различных платформ: Windows, Linux, Android, WebAssembly и т.д. Собирается и работает без всяких проблем. Нет проблем вызывать SDL_Init() и т.д.

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#define SDL_MAIN_USE_CALLBACKS 1 // Use the callbacks instead of main()
 
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
 
#ifdef __EMSCRIPTEN__
#include <SDL3/SDL_opengles2.h>
#else
#include <glad/glad.h>
#endif // __EMSCRIPTEN__
 
static SDL_Window *window = NULL;
SDL_GLContext glContext;
 
// This function runs once at startup
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;
    }
 
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); // Enable MULTISAMPLE
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2); // can be 2, 4, 8 or 16
 
    const char *title = "Example in C, SDL3, and OpenGL";
    size_t canvasWidth = 350;
    size_t canvasHeight = 350;
    window = SDL_CreateWindow(title, canvasWidth, canvasHeight, SDL_WINDOW_OPENGL);
    if (!window)
    {
        SDL_Log("Couldn't create the window: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
 
    glContext = SDL_GL_CreateContext(window);
    if (!glContext)
    {
        SDL_Log("Couldn't create the glContext: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
 
    SDL_GL_SetSwapInterval(1); // Turn on vertical sync
 
#ifdef __WIN32__
    if (!gladLoadGL())
    {
        SDL_Log("Failed to initialize OpenGL function pointers");
        return SDL_APP_FAILURE;
    }
#endif // __WIN32__
 
    glClearColor(50.f / 255.f, 50.f / 255.f, 50.f / 255.f, 1.f);
    glViewport(0, 0, canvasWidth, canvasHeight);
 
    return SDL_APP_CONTINUE;
}
 
// This function runs when a new event (mouse input, keypresses, etc) occurs
SDL_AppResult SDL_AppEvent(void *appState, SDL_Event *event)
{
    switch (event->type)
    {
        case SDL_EVENT_QUIT:
        {
            return SDL_APP_SUCCESS;
            break;
        }
        default:
            break;
    }
    return SDL_APP_CONTINUE;
}
 
// This function runs once per frame, and is the heart of the program
SDL_AppResult SDL_AppIterate(void *appState)
{
    glClear(GL_COLOR_BUFFER_BIT);
 
    // Update the screen
    SDL_GL_SwapWindow(window);
    return SDL_APP_CONTINUE;
}
 
// This function runs once at shutdown
void SDL_AppQuit(void *appState, SDL_AppResult result)
{
    // Cleanup
    SDL_GL_DestroyContext(glContext);
 
    // SDL will clean up the window for us
}
Цитата Сообщение от alecss131 Посмотреть сообщение
Да и звук там только 2д, для 3д нужно иное уже подключать.
Смотря какая 3D игра. Есть 3D-игры, где достаточно 2D звука. Моё мнение, что нужно сначала уверенно изучить Си перед C++. Нет вероятности отвлечения на ООП. Бывает часто так, что начинающий написал несколько игровых демок, а потом его поглотила пучина ООП и он уже перестал развивать эти игровые демки. Со звуком не вижу проблемы. Надо сначала набивать руки на 2D играх и лучше на Си и SDL3, чтобы не отвлекаться на ООП. Потом перейти на OpenGL. Изучать основы шейдеров и основы работы с библиотекой CGLM. Надо сразу подключить Box2D v3, особенно, если был опыт с Unity. Box2D v3 как раз переписали с C++ на чистый Си. Там многое значительно упростилось. Есть активный сервер по Box2D v3 в Discord (запрещён в РФ), где сразу помогают, даже нередко сам автор Box2D помогает. Можно тренировать английский. Там русские есть, например, очень активный и продвинутый "Колян".

Цитата Сообщение от alecss131 Посмотреть сообщение
Кроссплатформенность мне не интересна, но по той же ссылки где написано про поддержку андроида, есть ссылка на гит где люди показывали рабочий пример на андроиде. Еще я помню создавал контекст для GLES, хоть это было на винде и для запуска требовался транслятор, но поддержка этого есть, значит по сути поддержка андроида уже есть.
Как правило, это "hello world" проекты, а чуть дальше если продвинуться, например, сделать тач нескольких пальцев, то поддержки от разработчиков нет никакой. К примеру, на SFML даже написано, что есть поддержка Android, но на деле это сделано через такие чуткие костыли с вставками кода Java в C++. Я бы не стал советовать программирование под Android новичкам на SFML. Я не пробовал GLFW на Android, но у меня интуитивное чутьё, что это будет только потеря времени. На главном сайте GLFW написано, что есть поддержка OpenGL ES, но при этом там написано:
GLFW is written in C and supports Windows, macOS, Wayland and X11.
Я понимаю под поддержкой именно поддержку разработчиками. Если я найду баг, то я могу создать Issue. Если у меня есть вопрос, то я могу спросить на официальном Discord, либо на официальном форуме. У меня по Android на SDL3 было много вопросов, как у новичка, мне сильно помог один из самых активных разработчиков - maarten. Там реально очень просто собрать под Android, как первую программу, так и саму SDL3. Я записал, чтобы не забыть: https://8observer8.github.io/t... index.html Там буквально несколько шагов.

Цитата Сообщение от alecss131 Посмотреть сообщение
Сборка натива для веба считаю бредятиной, думаю найдутся умельцы, а точнее извращенцы, которые соберут нативы под веб, а потом это упакуют в электрона для запуска вне браузера.
Сборку в WebAssembly часто делают, например, из Unity-WebGL для браузерных игр, который встраивают в Яндекс Игры, в VK и т.д. Мне не нравится сборка Веб в EXE с помощью Electron, как это сделали с VSCode, потому сильная нагрузка на оперативу и CPU. Мне нравится SDL3 тем, что я могу собрать один и тот же проект на Си или C++ для Windows, Android и WASM. Причём, когда я собрал в WASM и закинул на какой-нибудь хостинг, например, на бесплатный https://www.netlify.com/ (получил URL), то это приложение будет автоматически может быть запущено на многочисленных платформах, где есть браузер. Например, пример выше переписанный с PySDL3 + OpenGL на SDL3 + OpenGL с выводом текста на русском и английском: https://hello-world-text-openg... tlify.app/ можно в один клик запустить на macOS, iOS, Linux и т.д. При этом я могу собрать EXE и APK. Но мне больше нравится вариант вообще отказа от EXE, когда на Desktop запускается только в браузере, тогда можно испльзовать GUI на HTML и CSS. В этом случае, ещё появляется доступ к WebSocket'ам, которые реализованы в Emscripten. Очень интересный факт, что OpenAL (2D и 3D) звук компилируется в Web Audio API, без каких-либо усилий, но OpenAL Soft - это C++ и я думаю на Си нельзя использовать OpenAL. WASM я собираю в APK, потому что код тот же самый, что и для Desktop, а веб легко собирается в APK с помощью Corodva. Иногда чистый JavaScript не очень подходит, так как легко из браузера скачать ассеты, которые не хотелось бы распространять, а при сборке в WASM далеко не каждый может извлечь ассеты - это не так легко, как на JS, где каждый может открыть вкладку Network браузера и скачать ассеты.

Цитата Сообщение от alecss131 Посмотреть сообщение
И кстати на андроиде для звука есть свое апи, так что никакой OpenAL не нужен, там это OpenSL ES
Мне не нравится, когда приходится распыляться на разные технологии. Например, на SDL3 2D или OpenGL можно практиковаться с Python, C, C++. Так же как можно изучать работу с матрицами и векторами и основами шейдерного OpenGL с помощью cglm, GLM, PyGLM. Я уверен это полезно переключаться с Python, на C, на C++, JavaScript и обратно. Может это не всем подходит, а кому-то лучше сосредоточиться на чём-то одном, но я нахожу плюсы во всех перечисленных языках и технологиях. Поддержка OpenAL уже есть в Emscripten. Я подключаю OpenAL-Soft для Windows, а при сборке в WASM OpenAL автоматически преобразуется в Web Audio API. А потом можно с помощью Cordova собрать из WASM в APK. Я собирал WASM в APK и 3D звук работает на Android. Минимум телодвижений. Тем более Web Audio API очень похож на OpenAL, поэтому несложно совмещать эти два API. Что-то можно изучить в Web Audio API на JavaScript, а потом перенести это в OpenAL и наоборот. Не вижу не каких минусов, чтобы так делать. Много плюсов от веб в WASM со сборкой в APK - звук, GUI, веб-сокеты, базы данных, сборка под разные платформы. APK после Cordova из WASM получается несколько МБ и при установке 15 МБ. Сколько времени экономит такая сборка под Android.

Вообще было был лучше изучать OpenGL параллельно на JavaScript на WebGL, потому что на нём ничего не надо ставить и собирать из исходников. Намного меньше, где можно застрять и намного больше возможностей и очень легко обучаться. На готовом графическом 2D API SDL3 много ограничений и почти всё скрыто. Обучаться программированию графики лучше на шейдерах и glMatrix. На JS и WebGL какое-то время можно пользоваться онлайн-редактором https://plnkr.co/ вместо Sublime Text 4. GUI можно делать на HTML и CSS. SQL можно изучать в песочнице Glitch. На Glitch есть встроенная база данных для серверной части - SQLite. Серверную часть можно писать на JavaScript и Node.js Пересылать сообщения от клиента к серверу можно с помощью WebSockets. Приложение не нужно будет собирать в EXE, а достаточно опубликовать ссылку на хостинг (что Plunker, что Glitch, что Netlify) и приложение или игра будет запускаться в один клик на любой ОС. Для звука можно использовать Web Audio API, что поможет изучать OpenAL. Есть порты и сборки Box2D (box2d-core, Box2D-WASM) и Bullet Physics (Ammo.js) - по ссылкам в скобках простые примеры. Практика на JavaScript, HTML и CSS больше даст возможностей зарабатывать. Проще будет зарабатывать на играх, встраивая их в соц. сети. Даже Unity-WebGL сложнее встроить, чем SDL3-WASM, а тем более сложнее, чем JavaScript. Ещё сложнее будет если взять GLFW или SFML для Android. А ещё сложнее собирать в EXE и с EXE пытаться зарабатывать на Steam. Такое моё мнение.

Это пример одного из разработчиков, которого я упоминал выше (maarten): https://github.com/madebr/sdlcross/tree/SDL3 Я собирал этот пример для Android (пример на Си и SDL3 2D API) и я написал пошаговую инструкцию. Если кто-то решит собрать по этой инструкции и запустить на реальном Android и будут проблемы, то пишите. В этом примере при касании экрана в месте касания появляется квадрат. Если коснуться двумя и более пальцами, то появятся несколько квадратов разных размеров. При перемещении пальцев по экрану квадраты будут следовать за пальцами. Хороший пример отлично реализованной поддержки, как поддержки Android в виде реализации необходимого API, так и поддержки разработчиками на Discord (запрещён в РФ), официальном форуме и Github. Мне так же ни раз помогал самый главный разработчик - slouken и многие другие. Я почти уверен, что на GitHub-репозитории GLFW если бы я создал Issue касательно какой-нибудь проблемы на Android, то мне бы ответили, то Android официально не поддерживается. Очень сильно выручает Discord (запрещён в РФ), которого нет у GLFW. Мне по Android и SDL3 очень много помогли - на самом деле, оказалось очень легко работать на Android из SDL3, особенно, после сборки в WASM из Cordova.
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,292
Записей в блоге: 2
01.06.2025, 15:04
Цитата Сообщение от 8Observer8 Посмотреть сообщение
При каких условиях невозможно инициализировать SDL3?
Про 3 не знаю, но по идее тоже самое, в 2 без использования либы SDLmain вызов SDL_Init будет происходить с ошибкой, так как в точке входа внутри SDLmain происходит еще инициализация, включая обработку параметров командной строки.
Сейчас нашел как это правильно отключить
C
1
2
3
4
5
6
#define SDL_MAIN_HANDLED
#include <SDL.h>
 
int main(int argc, char **argv) {
    SDL_SetMainReady();
    if(SDL_Init( SDL_INIT_EVERYTHING)){
Но пишут что это отключит проверку ошибок в либе или что-то в этом роде. Просто далеко не всегда можно (да и порой не возможно) отдавать точку входа подобным либам.
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Функция main() скрыта для программиста.
Оно и так скрыто, ведь внутри SDL есть такое
C
1
#define main    SDL_main
то есть когда используешь SDL и сам пишешь функцию main() то либа ее подменяет
Цитата Сообщение от 8Observer8 Посмотреть сообщение
SDL_MAIN_USE_CALLBACKS всего должно быть определено четыре функции
Такое мне нравится еще меньше, какое-то ардуино выходит (а оно имеет крайне низкую и сомнительную репутацию). И с таким подходом надо использовать глобальные объекты, что как по мне ужасно.
Цитата Сообщение от 8Observer8 Посмотреть сообщение
OpenGL ES
Только вот эта технология нативная только для arm, в те времена когда все создавалось, десктопов на армах не было, хотя сейчас кроме мака на армах десктопов не найти, а на маке лучше использовать метал, так как они могут дропнуть opengl, что к тому может и идти, так как есть слухи что они решили отказаться от x86 в пользу арм (в смысле не выпускать новые ос под х86).
Я писал на С++ и OpenGL на андроиде, но без ввода, GLFW Не использовал, а для OpenGL там никакие загрузчики не нужны, создание контекста не сложное и есть полностью в стартовом проекте если выбрать GameActivity.
У меня в планах дальше разбираться в андроиде (в рамках С++ больше), включая ввод. После беглого поиска нашел что можно сделать ввод и мультитач и джойстики без использования Jni
Цитата Сообщение от 8Observer8 Посмотреть сообщение
для серверной части - SQLite
Для серверов самый плохой выбор, эта база не подходит для многопоточности и чего-то крупнее чем простое хранение огромного количества данных в удобном формате когда не нужна производительность. Даже для простых серверов где нужны бд лучше использовать полноценные базы данных.
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Вообще было был лучше изучать OpenGL параллельно на JavaScript на WebGL, потому что на нём ничего не надо ставить и собирать из исходников.
Это единственный его плюс. А так смысла даже изучать OpenGL нету, так как технология мертва, на этом не заработать. Если писать игры, то на готовых движках, а низкоуровневые апи только для написания движков и прочих сапр. И вообще я считаю что веб для графики самый плохой выбор. Веб это сайты, игры это нативы. Всякие яндекс игры и прочая помойка не в счет.
Не надо поддерживать зло в виде упаковки веба в электрон и выдачу этих поделий за программы, которые едят дофига и тормозят и лагают.
0
9035 / 2936 / 493
Регистрация: 05.10.2013
Сообщений: 7,958
Записей в блоге: 216
01.06.2025, 17:29
Цитата Сообщение от alecss131 Посмотреть сообщение
И с таким подходом надо использовать глобальные объекты, что как по мне ужасно.
Да, в примере выше две переменные-указателя глобальные, а чтобы избежать этого был придуман appState:

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
typedef struct
{
    SDL_Window *window;
    SDL_GLContext glContext;
} AppContext;
 
// This function runs once at startup
SDL_AppResult SDL_AppInit(void **appState, int argc, char *argv[])
{
    // Allocate memory for AppContext
    AppContext *ctx = malloc(sizeof(AppContext));
    if (!ctx)
        return SDL_APP_FAILURE;
 
    ctx->window = SDL_CreateWindow("Example", 400, 400, SDL_WINDOW_OPENGL);
    ctx->glContext = SDL_GL_CreateContext(ctx->window);
 
    *appState = ctx;
}
 
// This function runs once per frame, and is the heart of the program
SDL_AppResult SDL_AppIterate(void *appState)
{
    AppContext *ctx = (AppContext *)appState;
 
    glClear(GL_COLOR_BUFFER_BIT);
 
    // Update the screen
    SDL_GL_SwapWindow(ctx->window);
    return SDL_APP_CONTINUE;
}
 
// This function runs once at shutdown
void SDL_AppQuit(void *appState, SDL_AppResult result)
{
    AppContext *ctx = (AppContext *)appState;
 
    if (ctx->glContext)
        SDL_GL_DestroyContext(ctx->glContext);
 
    if (ctx->window)
        SDL_DestroyWindow(ctx->window);
 
    free(ctx);
}
Но с другой стороны я не вижу проблем в глобальных переменных в пределах одного файла, с ключевым словом static:

C
1
2
static SDL_Window *window = NULL;
static SDL_GLContext glContext;
Для автора темы, если он вернётся когда-нибудь или для ещё кого-нибудь поясню, что "static" в Си - это видимость в пределах одного файла. Я стараюсь разбивать проекты на небольшие файлы порядка 100 - 200 строк кода, иногда чуть больше. Визуально в таком файле легче ориентироваться по глобальным переменных в пределах файла. Не хотелось усложнять пример с помощью appState. Я к Си больше отношусь, как маленькому учебному языку, чтобы показывать примеры начинающим, как и к Python, да JavaScript - хотя это же нечто большее. В учебных примерах не стоит усложнять.

Небольшая инструкция, как собрать проект с помощью MinGW GCC 11.2, взятому из Qt 6.6.3:
  • Скачать MinGW с Mediafire или TeraBox (zip - 182.3 MB, unzipped - 571 MB)
  • Скачать и установить CMake: https://github.com/Kitware/CMake/releases
  • Распаковать архив, например, на диск C и добавить путь к извлечённой папке + bin у переменную окружения PATH, например, такой путь: C:\mingw64_11.2\bin
  • Прикреплённый пример уже содержит библиотеки SDL 3.1.6 и GLAD 2.0.8 в папке libs и подключены в файлах config-exe.bat, config-web.bat
  • Из корня проекта в CMD выполнить команду: config-exe
  • Выполнить команду: build-exe
  • Будет создан app.exe, который можно запустить командой: dist\win\app
  • Можно ещё установить Emscripten и выполнить команды: config-web и build-web и закинуть папку public на бесплатный хостинг https://www.netlify.com/ переносом мыши. У вас будет EXE и ссылка на приложение, которое можно запустить в один клик в браузере. Данную сборку я закинул на Netlify: https://app-state-opengl-sdl3-c.netlify.app/ Вы делаете игру, закидываете на этот хостинг и ваша игра сразу доступна в один клик на Windows, macOS, Android и т.д.

Структура проекта:

Название: 652750b18a16dfdafb2991e091371ebe529b2bef.png
Просмотров: 219

Размер: 2.8 Кб

Может кому-то пригодится. Если авторе темы вернётся, то может попробует и задаст вопросы, если что-то не работает или что-то непонятно.

Прикрепил код примера.

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#define SDL_MAIN_USE_CALLBACKS 1 // Use the callbacks instead of main()
 
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <stdlib.h>
 
#ifdef __EMSCRIPTEN__
#include <SDL3/SDL_opengles2.h>
#else
#include <glad/glad.h>
#endif // __EMSCRIPTEN__
 
typedef struct
{
    SDL_Window *window;
    SDL_GLContext glContext;
} AppContext;
 
// This function runs once at startup
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;
    }
 
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); // Enable MULTISAMPLE
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2); // can be 2, 4, 8 or 16
 
    // Allocate memory for AppContext
    AppContext *ctx = malloc(sizeof(AppContext));
    if (!ctx)
        return SDL_APP_FAILURE;
 
    ctx->window = SDL_CreateWindow("Example", 400, 400, SDL_WINDOW_OPENGL);
    if (!ctx->window)
    {
        SDL_Log("Couldn't create the window: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
 
    ctx->glContext = SDL_GL_CreateContext(ctx->window);
    if (!ctx->glContext)
    {
        SDL_Log("Couldn't create the glContext: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
 
    *appState = ctx;
 
    SDL_GL_SetSwapInterval(1); // Turn on vertical sync
 
#ifdef __WIN32__
    if (!gladLoadGL())
    {
        SDL_Log("Failed to initialize OpenGL function pointers");
        return SDL_APP_FAILURE;
    }
#endif // __WIN32__
 
    glClearColor(0.2f, 0.2f, 0.2f / 0.2f, 1.f);
 
    return SDL_APP_CONTINUE;
}
 
// This function runs when a new event (mouse input, keypresses, etc) occurs
SDL_AppResult SDL_AppEvent(void *appState, SDL_Event *event)
{
    switch (event->type)
    {
        case SDL_EVENT_QUIT:
        {
            return SDL_APP_SUCCESS;
            break;
        }
        default:
            break;
    }
    return SDL_APP_CONTINUE;
}
 
// This function runs once per frame, and is the heart of the program
SDL_AppResult SDL_AppIterate(void *appState)
{
    AppContext *ctx = (AppContext *)appState;
 
    glClear(GL_COLOR_BUFFER_BIT);
 
    // Update the screen
    SDL_GL_SwapWindow(ctx->window);
    return SDL_APP_CONTINUE;
}
 
// This function runs once at shutdown
void SDL_AppQuit(void *appState, SDL_AppResult result)
{
    AppContext *ctx = (AppContext *)appState;
 
    if (ctx->glContext)
        SDL_GL_DestroyContext(ctx->glContext);
 
    if (ctx->window)
        SDL_DestroyWindow(ctx->window);
 
    free(ctx);
}
Вложения
Тип файла: zip app-state-opengl-sdl3-c.zip (6.22 Мб, 0 просмотров)
0
9035 / 2936 / 493
Регистрация: 05.10.2013
Сообщений: 7,958
Записей в блоге: 216
01.06.2025, 21:19
Цитата Сообщение от alecss131 Посмотреть сообщение
Про 3 не знаю, но по идее тоже самое, в 2 без использования либы SDLmain вызов SDL_Init будет происходить с ошибкой, так как в точке входа внутри SDLmain происходит еще инициализация, включая обработку параметров командной строки.
Сейчас нашел как это правильно отключить
Да, если закомментировать подключение SDL_main.h:

C
1
2
3
4
#define SDL_MAIN_USE_CALLBACKS 1 // Use the callbacks instead of main()
 
#include <SDL3/SDL.h>
// #include <SDL3/SDL_main.h>
то выводится ошибка:

undefined reference to `WinMain'
Значит не надо её удалять и придумывать проблемы на пустом месте. Не надо извращаться - есть официальный template.c на GitHub-репозитории SDL3:

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
/*
 * This example code $WHAT_IT_DOES.
 *
 * This code is public domain. Feel free to use it for any purpose!
 */
 
#define SDL_MAIN_USE_CALLBACKS 1  /* use the callbacks instead of main() */
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
 
/* We will use this renderer to draw into this window every frame. */
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
 
 
/* This function runs once at startup. */
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
    SDL_SetAppMetadata("Example HUMAN READABLE NAME", "1.0", "com.example.CATEGORY-NAME");
 
    if (!SDL_Init(SDL_INIT_VIDEO)) {
        SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
 
    if (!SDL_CreateWindowAndRenderer("examples/CATEGORY/NAME", 640, 480, 0, &window, &renderer)) {
        SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
    return SDL_APP_CONTINUE;  /* carry on with the program! */
}
 
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
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;  /* carry on with the program! */
}
 
/* This function runs once per frame, and is the heart of the program. */
SDL_AppResult SDL_AppIterate(void *appstate)
{
    return SDL_APP_CONTINUE;  /* carry on with the program! */
}
 
/* This function runs once at shutdown. */
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
    /* SDL will clean up the window/renderer for us. */
}
, а так же есть официальные примеры: https://github.com/libsdl-org/... n/examples

Надо брать примеры в разработку и тренироваться программировать, упражняясь на простых играх + Box2D v3, а так же попутно изучать программирование графики. Понятно, что лучше начинать с 2D. Больше 10 лет назад я прочитал книгу Кернигана и Ритчи сначала на русском, потом на английском. Очень хорошая. Если автор вернётся, то найдите эту книгу. Она так же актуальная как первая ступень на пути к C++.

Цитата Сообщение от alecss131 Посмотреть сообщение
Но пишут что это отключит проверку ошибок в либе или что-то в этом роде. Просто далеко не всегда можно (да и порой не возможно) отдавать точку входа подобным либам.
Не понимаю о чём вы. Вы, наверное, какой-то эмулятор писали, типа NES или PS1. Наверное, хотели встроить SDL в Qt? Что-то типа такого. В остальных обычных случая берутся официальные примеры и либо создаётся своё окно для SDL для 2D графики, либо своё окно для OpenGL графики, а там по списку: Vulkan, Metal и т.д. Не надо лезть сразу в эмуляторы и встраивать в Qt. Есть же эмулятор DuckStation для PS1. Там GUI на Qt, а графика на SDL + разные графические API типа OpenGL, Vulkan, Direct3D 11 (12) и Metal. Если в DuckStation это реализовано, значит SDL может работать в Qt. Не надо сейчас удалять SDL_main.h - пусть будет.

Цитата Сообщение от alecss131 Посмотреть сообщение
а на маке лучше использовать метал
Надо оценивать, какие плюсы и минусы. Какой подход менее затратный по времени и деньгам. Можно и такой подход сделать, что переписывать один и тот же код для расширения аудитории. Например
  • для старых ноутбуков и Android писать на OpenGL и WebGL
  • для новых ноутбуков и Android писать на Vulkan и WebGPU
  • для macOS и iOS писать на Metal
Но сколько это сил возьмёт, а на SDL3 ввел команду, собрался EXE, ввёл команду - собрался WASM. Этот WASM может в браузере запуститься. А это значит, что не надо покупать Mac. Пользователь на Linux и iOS тоже могут запустить. Вот только без наличия Mac не собрать в исполняемый файл для Mac и iOS. Но ничего, хотя бы в браузере можно запустить. Это уже позволяет запускать на всех ОС без траты кучи времени.

Цитата Сообщение от alecss131 Посмотреть сообщение
а для OpenGL там никакие загрузчики не нужны, создание контекста не сложное и есть полностью в стартовом проекте если выбрать GameActivity.
Но это выглядит сложнее, чем использовать SDL3 для создания EXE, WASM и APK. На SDL3 это раз плюнуть, а с вашим подходом нужно будет сначала написать Android проект, потом написать проект для сборки в EXE, потом в WASM. Кстати, Emscripten очень тщательно тестирует SDL3. У них даже какая-то версия SDL встроена в Emscripten. Я не хочу чтобы у меня был только APK, или только EXE. Мне знаком GameActivity - я когда-то пробовал запускать SDL2 на Android - вроде получалось, то через такие костыли. Сейчас SDL3 полностью поддерживает Android. Я думаю, что SDL3 с его callbacks это идеальный вариант если нужно быстро получить небольшой EXE, APK и WASM.

Цитата Сообщение от alecss131 Посмотреть сообщение
У меня в планах дальше разбираться в андроиде (в рамках С++ больше), включая ввод.
У меня тоже, то в рамках SDL3-WASM (C и C++) и WebGL (JS). Без браузера на Android это боль и мучения. У меня есть сборки Box2D v2 и v3 для WASM, но собирать в натив библиотеки для Android и подключать их я даже пока не собираюсь. Все библиотеки подключенный в сборке в WASM работают в сборке в APK с помощью Cordova - это вообще гениальное изобретение, столько времени экономит. На C++ для Android без мучений это не только SDL3-WASM+Cordova, но конечно, Qt, но Qt я отложил из-за этих проблем, потому что на Desktop он не позволяет сделать перемещение от первого лица в браузере (при сборке в WASM) и мои Issue закрыли. Зато SDL3 позволяет.

Цитата Сообщение от alecss131 Посмотреть сообщение
Для серверов самый плохой выбор
SQLite + онлайн редактор и хостинг Glitch отлично подходят для создания туториалов для начинающих по языку SQL и клиент-серверному программирования простых игр с Box2D и графикой на WebGL. Туда же можно запихнуть клинта на SDL3-WASM. Это один из единственных способов, как можно разместить в интернете бесплатно и сервер и базу данных. Я делал чат с сервером на Render.com и клиентом на SDL3 + HTML/CSS, он работает и плюс там SQLite база данных сохраняет сообщения, только не пишите матом: https://chat-sdl3-wasm-cpp.onrender.com/ (на бесплатном хостинге надо подождать 30-50 секунд, а на Glitch всего 15 секунд) Я как написал в чате в летом 2024-го так оно там и осталось. Сейчас опять написал. Никто не пробовал. Попробуйте кто-нибудь, я потом сотру. На сервере Node.js на Glitch можно подключить MongoDB, PostgreSQL, MySQL, MariaSQL с бесплатного хостинга: https://filess.io/ Я там пробовал MongoDB и PostgreSQL. По-моему, MySQL пробовал. Glitch - это отличный вариант поупражняться с этими базами данных - можно создавать GUI на HTML/CSS и JavaScript + Node.js - это проще, даже чем Qt.

Цитата Сообщение от alecss131 Посмотреть сообщение
А так смысла даже изучать OpenGL нету, так как технология мертва, на этом не заработать.
Полностью умер только OpenGL версии выше 4.2 включительно на MacOS, а версия 4.1 и ниже работает для совместимости - сам не проверял, но много, где пишут. Мне, например, очевидно, что написание учебных игр для изучения программирования компьютерной графики и сопутствующих технологий понятнее и полезнее делать на шейдерном OpenGL и достаточно версии не выше 2.1 включительно, потому что этих основ более чем достаточно, а углубляться смысла нет - либо по мере острой необходимости по очень специализированным вопросам. То что можно сделать на Pygame и SFML, можно сделать без проблем на OpenGL и Box2D. Пользы больше, потому что наглядно всё, например, видно, как перемножаются матрицы между собой, а потом в вершинном шейдере, можно вмещаться в покраску пикселей и сделать клик по объекту по цветовому ID. Больше всего смысла, если изучать WebGL, JS, HTML, CSS, Node.js, Box2D, WebSocket через простые игры. На C или C++ гораздо сложнее организовать клиент-серверное взаимодействие на реальном бесплатном хостинге и взаимодействие с базой данных из сервера на C/C++.

Цитата Сообщение от alecss131 Посмотреть сообщение
И вообще я считаю что веб для графики самый плохой выбор. Веб это сайты, игры это нативы. Всякие яндекс игры и прочая помойка не в счет.
EXE мало кто будет скачивать на форуме, потому что вдруг там вирус, да и лень может быть. Зачем мне прикреплять EXE на SDL3 если я могу собрать его в WASM, чтобы оно могло запускаться в один клик. Я могу и то и то делать. Тут хотя бы выбор появляется. Мне кажется, что неправильно так называть игры, в которые множество людей вкладывают душу. Наверняка там много достойных игр, просто мы не играем. У корпораций больше возможностей делать топовые игры типа Atomic Heart. Из РФ я знаю только одну "настоящую" игру. Да их и в мире немного выходит. Из крайнего, что я помню это "Stalker 2" (запрещённый в РФ - на всякий случай). Программирование игрушек для веб можно использовать хотя бы как полезное хобби, чтобы изучать всякие интересные и полезные веб-технологии, основы линейной алгебры, основы физических симуляций на Box2D и Bullet Physics, делиться каким-то опытом. Тоже самое программирование клиент-серверных приложений на веб-сокетах - тоже можно использовать для самообучения. Типа, написать шашки по сети или морской бой на двоих человек. На C/C++ такой сервер трудно разместить бесплатно в интернете, на на Glitch и Render.com - запросто. Полученные знания и опыт в JS, HTML, можно использовать для создания сайтов. 2D и 3D графика давно используется в браузерах не только в играх, но и в рекламе в каких-то демонстрациях научных знаний. Я находил приложение на WebGL на сайте НАСА, где можно было управлять луноходом. Если перемещения 360-градусов, как в Google Map, где перемещаются по квартирам и другим объектам. Тот же Google Map - замечательный пример применения WebGL.

Цитата Сообщение от alecss131 Посмотреть сообщение
Не надо поддерживать зло в виде упаковки веба в электрон и выдачу этих поделий за программы, которые едят дофига и тормозят и лагают.
Я отношусь к Electron очень отрицательно, потому что такие EXE отнимают много места на жёстком, где-то 200-300 MB и тормозят, ну и оперативу жрут сильно. Мне поэтому не нравится UE4, так как EXE ведёт себя как Electron - тоже столько же весит и так же тормозит. Такое EXE даже на форуме не прикрепишь - только отгружать на Google Drive и быстро тогда закончатся 15 GB. Я писал, в прошлом сообщении, что Electron не нравится, а Cordova - это круто, потому что APK получаются маленькими - 3-5 МB если собрать из WASM, а устанавливаются на 15 МБ. Для EXE я специально взял SDL3, чтобы был маленький размер, запускалось быстро, требовало 1-2% CPU, очень мало GPU и немного оперативы. WebGL - для разработки и отладки и обучения, а SDL3 + OpenGL - если нужно создать EXE, APK и WASM.
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,292
Записей в блоге: 2
01.06.2025, 23:05
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Значит не надо её удалять и придумывать проблемы на пустом месте. Не надо извращаться - есть официальный template.c на GitHub-репозитории SDL3
Я всегда использовал 2 версию и больше всего с Tiny C Compiler, там либа не собирается, но отлично используется собранная в виде dll, но без SDLmain не работает, а она всегда в статике. Тогда придумал костыль переписав и обрезав максимально файл из SDLmain.
Попробовал третью, работает как я привык, хорошо что они по умолчанию отключили использование своей точки входа.
Создал себе шаблонный проект, так мне куда приятнее и привычнее
Swift
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
import CSDL3
 
guard SDL_Init(SDL_INIT_VIDEO) else {
    print("Could not initialize SDL: \(String(cString: SDL_GetError()))")
    exit(1)
}
guard let window = SDL_CreateWindow("Window", 800, 600, 0) else {
    print("Could not create a window: \(String(cString: SDL_GetError()))")
    SDL_Quit()
    exit(2)
}
guard var renderer = SDL_CreateRenderer(window, nil) else {
    print("Could not create a renderer: \(String(cString: SDL_GetError()))")
    SDL_DestroyWindow(window)
    SDL_Quit()
    exit(3)
}
 
var run = true
 
while run {
    var event = SDL_Event()
    while SDL_PollEvent(&event) {
        if event.type == SDL_EVENT_QUIT.rawValue {
            run = false
        }
    }
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255)
    SDL_RenderClear(renderer)
    SDL_SetRenderDrawColor(renderer, 128, 255, 0, 255)
    var rect = SDL_FRect(x: 350, y: 250, w: 100, h: 100)
    SDL_RenderFillRect(renderer, &rect)
    SDL_RenderPresent(renderer)
}
 
SDL_DestroyWindow(window)
SDL_Quit()
И тут уже точку входа не поменять, в языке она жестко задана, а в коде либо файл main.swift и там весь код, либо struct/class/enum с пометкой @main и функцией static func main(). То есть при старте язык передает управление в 2 указанных места в коде.
Использовал уже собранную студией на винде, только распихал по нужным папкам в проекте, подключил и написал модуль файл. Либа не модифицировалась для работы с языком.
0
9035 / 2936 / 493
Регистрация: 05.10.2013
Сообщений: 7,958
Записей в блоге: 216
02.06.2025, 13:33
Я уверен, что студентам практиковаться со основами GLSL в OpenGL очень сильно полезно хотя бы на самых базовых основах, даже если они будут использовать Unity, а скорее всего, именно Unity будут использовать более 90% студентов, кто выбрал разработку игр в качестве будущего заработка, потому что Unity самый популярный в РФ по вакансиям и прост в программировании на C#, поэтому на Unity больше шансов студентам найти работу. С определённого этапа в Unity надо писать шейдеры на языке HLSL, или вносить правки в существующие шейдеры, а GLSL очень похож на HLSL. Я считаю, что какой-то минимальный опыт работы с вершинным и фрагментым шейдером нужно получить и получить его на любом языке - особо неважно на каком, так как работа с GLSL абсолютно одинакова на любом языке программирования. Для изучения этих базовых основ GLSL подойдёт любой язык: C, С++, JavaScript, Python, Java, C# и т.д. Надо ограничиться только самыми базовыми основами работы с вершинным и фрагментным шейдером, а дальше лезть в изучение OpenGL нет никакого смысла. Достаточно изучить базовое направленное освещение, точечное освещение, shadow map, normal map, specular map, определение клика по color id, базовую скелетную анимацию и можно затронуть смешивание анимаций - для базового понимания линейной алгебры для работы с матрицами и векторами этого дотаточно. Лучше всего параллельно изучать Unity и основы GLSL.

В Unity очень часто для 2D игр и даже для 3D (например, для 3D-платформеров c 2D физикой) используется Box2D, но в Unity-обёртке, которая почти один в одни повторяет Box2D. В инспекторе Unity можно увидеть теже самые настройки физики, как если использовать Box2D в чистом виде. Поэтому, я считаю, что очень полезно познакомиться с основами Box2D на каком-нибудь языке и неважно какой это язык, хоть C, хоть JavaScript. Можно на C#, чтобы было проще переключаться на Unity. Для каждого языка есть свой порт Box2D, в том числе на C#. Можно взять LibGDX на Java, в котором есть Box2D. LibGDX по работе с 2D API точно такой же, как Pygame, SDL, SFML, Phaser и т.д. У LibGDX огромное сообщество на Discord (запрещён в РФ) - можно практиковать английский. Для знакомства с основами Box2D неважно какой язык взять, как и для изучения основ GLSL.

Соглашусь, что очень глупо тратить время на погружение в дебри низкоуровневых API типа OpenGL 4.6, Vulkan, Direct3D и т.д. У студентов обычно Windows или Linux, поэтому Metal тоже отметаем. Достаточно только самый базовых основ GLSL, которые я перечислил выше и работы с матрицами для понимания базовой линейной алгебры на примере анимаций: перемещения, поворота, изменения размера, keyframe-анимации, скелетной анимации, анимаций на физических движках Box2D и Bullet Physics. Поэтому для изучения основ GLSL надо брать OpenGL 2.1 и не выше или WebGL 1.0 (который базируется на OpenGL ES 2.0). Начинать изучать Vulkan или OpenGL 4.6 студентам - это абсолютно мёртвый путь, туда ходить ни в коем случае не надо. Vulkan отнимет кучу времени и никак не поможет в понимании основ компьютерной графики, редактировании или написании шейдеров на HLSL в Unity. Может даже лучше изучать основы GLSL на C# и OpenTK, чтобы проще переключаться на Unity, а проще всего на WebGL и JavaScript по книге с Ozon: WebGL. Программирование трехмерной графики (авторы: Kouichi Matsuda и Rodger Lea). Правда, стоит она сейчас 2 тыс. рублей, а я покупал более 5 лет назад на 900 рублей. Первый раз можно прочитать на русском, а потом лучше читать на английском. Здесь примеры с использование glMatrix (аналог GLM): Небольшие примеры на WebGL
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,292
Записей в блоге: 2
02.06.2025, 14:46
Цитата Сообщение от 8Observer8 Посмотреть сообщение
У студентов обычно Windows или Linux, поэтому Metal тоже отметаем.
Крайне глупое решение. Не стоит судить по себе и выкидывать то чем не пользуешься, маков куда больше чем кажется.
Цитата Сообщение от 8Observer8 Посмотреть сообщение
низкоуровневых API типа OpenGL 4.6
Хахаха. Он не низкоуровневый, он только более удобный и исправляет многие проблемы более старых версий OpenGL.
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Начинать изучать Vulkan или OpenGL 4.6 студентам - это абсолютно мёртвый путь, туда ходить ни в коем случае не надо.
Вот так, не 4.6 версию а вообще не стоит это ископаемое трогать. Вулкан в этом плане полезнее, так как ближе к железу и позволяет лучше понять то как работает видеокарта.
Изучение графических апи полезно только для написания движков. Просто так учить графику бесполезно и просто потеря времени. Пользы никакой. Что ogl 1 что glsl.
Даже на движка игры создавать в одиночку такое себе, игры создаются командами, причем без дизайнеров никуда.
0
9035 / 2936 / 493
Регистрация: 05.10.2013
Сообщений: 7,958
Записей в блоге: 216
02.06.2025, 23:28
Цитата Сообщение от alecss131 Посмотреть сообщение
Крайне глупое решение. Не стоит судить по себе и выкидывать то чем не пользуешься, маков куда больше чем кажется.
Я нагуглил, что macOS - это всего 15% пользователей в РФ, а Windows - 75%, 4% - Linux и ещё там что-то. Если автор темы возьмёт Metal и будет делать учебные игровые демки, то скачать и поиграть в них не получится у большинства форумчан. Это же интересно выложить свою демку, это мотивирует. В процессе программирования таких демок учишься. Это полезнее и интереснее, чем смотреть глупые видео и деградировать на досуге. Отличное хобби, даже если не получится на этом зарабатывать.

Цитата Сообщение от alecss131 Посмотреть сообщение
Хахаха. Он не низкоуровневый, он только более удобный и исправляет многие проблемы более старых версий OpenGL.
Хорошо, 4.6 - самый высокоуровневый. А какая разница удобный он или нет, если глупо тратить время на углубленное изучение графических API, чтобы писать конкурента Unity с нуля? Глупо тратить время на 2D графический API SFML, Pygame, SDL. Конечно, глупо писать конкурента Unity с нуля - он это никто не спорит. Речь о том, что основы компьютерной графики далеко от проблем старых версий OpenGL. Гораздо полезнее понять, как работают текстурные координаты и наложить текстур на два прямоугольник. Этого достаточно, что сделать спрайтовую анимацию, кнопки, радио кнопки. Не надо погружаться в спецификации OpenGL.

Цитата Сообщение от alecss131 Посмотреть сообщение
Вулкан в этом плане полезнее, так как ближе к железу и позволяет лучше понять то как работает видеокарта.
Vulkan нужен тем кто работает в офисах компании Epic Games в США, Канаде и Западной Европе и развивает Unreal Engine. У них на сайте есть вакансии. Он так же нужен программистам, которые развивают игровой движок Creation Engine в компании Bethesda Game Studio. А в РФ нет таких гигантских корпораций как Unity Technologies, Adobe и т.д. Например, для автора данной темы для изучения основ компьютерной графики, линейной алгебры и наложения текстуры на объекты Vulkan - это огромный overkill.

Цитата Сообщение от alecss131 Посмотреть сообщение
Изучение графических апи полезно только для написания движков. Просто так учить графику бесполезно и просто потеря времени. Пользы никакой. Что ogl 1 что glsl.
Не только для сотрудников компаний США развивающие свои игровые движки. Надо выкинуть в топку графические 2D API библиотек Pygame, LibGDX, SFML, SDL, Pixi.js, Phaser и т.д. Вместо них гораздо полезнее рисовать текстуру на OpenGL - этого достаточно и не надо прям "изучать" OpenGL, а можно ограничиться минимальными его возможностями. От шейдеров нужно только несколько строчек для отображения текстуры - это заменяет все эти SFML, Pygame, LibGDX и т.д. Использование графики не ограничивается только играми. Это могут быть 2D/3D интерактивные анимации в браузере, визуализация данных, интерактивные графики, фотографии 360 в браузере. Браузеры умеют не только показывать сайты в виде текста и картинок - хотя это тоже графика, но могут воспроизводить видео, звук, а так же есть люди которые зарабатывать на браузерных играх, а значит есть люди кто играет в них. Можно ещё геометрию изучать в 2D и 3D, отображая в браузере на WebGL - и это можно делать доступным для других людей в один клик.

Цитата Сообщение от alecss131 Посмотреть сообщение
Даже на движка игры создавать в одиночку такое себе, игры создаются командами, причем без дизайнеров никуда.
Смотря какие игры и смотря какие цели. Могут быть маленькие учебные игры, как полезное хобби. Если цель заработок, то нужно идти в офис на Unity на разработку мобильных игр. В РФ во много раз больше шансов получить работу на Unity, чем на Godot или Unreal. На Unreal очень завышенные ожидания для игроков, кто покупает игры на Steam. Поэтому игры на Unreal Engine требуют команд от сотен людей. Atomic Heart делали более 120 человек. По титрам таких игр можно увидеть, что там в командах может быть несколько сотен и более.
0
9035 / 2936 / 493
Регистрация: 05.10.2013
Сообщений: 7,958
Записей в блоге: 216
03.06.2025, 00:14
Цитата Сообщение от Camad Посмотреть сообщение
пишу свой движок для игр
Может вы ещё вернётесь. GUI можно выводить с помощью библиотеки stb_image, но об это позже. Нужно оговориться, что, конечно, очевидно, что это ваш маленький движок - это набор вспомогательных файлов исходников и он должен быть конкретно под вашу игру. Какие-то файлы исходного кода могут быть универсальными для разных ваших учебных игрушек. Лучше всего, конечно же, делать маленькие игровые демки и по мере их создания и совершенствования создавать и улучшать вспомогательные файлы. Например, я вынес некоторые функции в отдельные файлы:

Code
1
2
3
4
5
6
7
line-drawer.h - рисование линии от одной точке к другой с заданной шириной и заданным цветом
line-drawer.c
main.c - главный файл
math-helper.h - вспомогательные математические функции
math-helper.c
shader-program.h - шейдерная программа для загрузки шейдеров на видеокарту
shader-program.c
Рисование линии заданной толщины между двух указанных точек - это очень сильно необходимая вещь. Например, она крайне необходима при рисовании коллайдеров физического движка Box2D. Она необходимо если у вас неигровой проект и вам надо нарисовать график функций. Например, синус можно нарисовать короткими отрезками с заданной шириной.

Демка в браузере (WASM)

Я подключил библиотеки: SDL3, cglm и glad. Можно собрать прикреплённый проект по инструкции.



Кликните здесь для просмотра всего текста
Вложения
Тип файла: zip line-drawer-cglm-opengl-sdl3-c.zip (7.67 Мб, 4 просмотров)
0
9035 / 2936 / 493
Регистрация: 05.10.2013
Сообщений: 7,958
Записей в блоге: 216
08.06.2025, 14:57
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Репозиторий Nucklear в архиве с 2019 года. Это значит, что он не поддерживается уже 6 лет. Может в будущем его разморозят и опять начнут поддерживать. Лучше его пока не использовать, потому что вы не сможете создавать Issue на официальном репозитории, то есть заявлять об ошибках, которые бы исправили в новых версиях. Заморозка ещё означает, что, скорее всего, многое кто его использовал стали использовать что-то другое, а новые пользователи не решаются его использовать. В этом случае, когда у вас возникают проблемы, то находится намного меньше людей, кто бы мог помочь решить текущую проблему в изучении библиотеки.
В том ответе у меня возникла путаница между библиотеками с одним названием, но с разных репозиториев:
Потому что если гуглить "Nuklear GitHub", то "/vurtun/nuklear" будет выше в списке в поиске. Первая библиотека в списке выше заморожена с 2019 года, а вторая активна. По первой ссылке в описании написано (автоматический перевод):

Уважаемый посетитель,

этот репозиторий, трекер проблем и т. д. заброшен в пользу https://github.com/Immediate-Mode-UI/Nuklear . Любая активность в этом трекере проблем, любые запросы на извлечение и т. д. будут игнорироваться.

Ждем ваших сообщений в https://github.com/Immediate-Mode-UI/Nuklear

Сообщество Nuklear
Мне не понравилось, что Nuklear до сих пор официально не поддерживает SDL3. Я нашёл тему, где человек предложил решение ещё в самом начале года: SDL3 support

Shouldn't be hard, just a few patches to nuklear_sdl_gl3.h

Here's my working solution using CMake:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
file(READ ${NUKLEAR_PREFIX_INCLUDE}/nuklear_sdl_gl3.h SDL_FILE_CONTENTS)
string(REPLACE "SDL2" "SDL3" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDL_GetTicks64" "SDL_GetTicks" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDL_GL_GetDrawableSize" "SDL_GetWindowSizeInPixels" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDL_TRUE" "true" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDL_FALSE" "false" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDL_KEYUP" "SDL_EVENT_KEY_UP" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDL_KEYDOWN" "SDL_EVENT_KEY_DOWN" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDL_MOUSEBUTTONUP" "SDL_EVENT_MOUSE_BUTTON_UP" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDL_MOUSEBUTTONDOWN" "SDL_EVENT_MOUSE_BUTTON_DOWN" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDL_MOUSEMOTION" "SDL_EVENT_MOUSE_MOTION" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDL_MOUSEWHEEL" "SDL_EVENT_MOUSE_WHEEL" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDL_TEXTINPUT" "SDL_EVENT_TEXT_INPUT" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDLK_b" "SDLK_B" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDLK_c" "SDLK_C" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDLK_e" "SDLK_E" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDLK_r" "SDLK_R" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDLK_v" "SDLK_V" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDLK_x" "SDLK_X" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDLK_z" "SDLK_Z" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "const Uint8* state = SDL_GetKeyboardState(0);" "const _Bool* state = SDL_GetKeyboardState(0);" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "SDL_SetRelativeMouseMode(" "SDL_SetWindowRelativeMouseMode(sdl.win, " SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "switch(evt->key.keysym.sym)" "switch(evt->key.key)" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
file(WRITE ${NUKLEAR_PREFIX_INCLUDE}/nuklear_sdl_gl3.h "${SDL_FILE_CONTENTS}")
Я взял файл nuklear_sdl_gles2.h из папки demo/sdl_opengles2 и применил изменения выше. Можно вручную заменить SDL_KEYDOWN на SDL_EVENT_KEY_DOWN и т.д. Но ещё мне пришлось добавить эти замены:

Code
1
2
3
4
string(REPLACE "SDLK_a" "SDLK_A" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "evt->wheel.preciseX, evt->wheel.preciseY" "evt->wheel.x, evt->wheel.y" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "KMOD_LCTRL" "SDL_KMOD_LCTRL" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
string(REPLACE "KMOD_RCTRL" "SDL_KMOD_RCTRL" SDL_FILE_CONTENTS "${SDL_FILE_CONTENTS}")
Нажатие кнопки работает на Windows и в браузере и текст при нажатии кнопки выводится в консоль, но не работает ввод в Edit Box ни на Desktop и на WebAssembly. Ещё не понравилась, что WASM-демка ниже не открывается на Android, если на форум зайти с телефона и нажать на ссылку ниже - просто белый экран и всё и поэтому я создал Issue: My simple WASM-demo does not work on Android

Демка в браузере: https://nuklear-opengl-sdl3-c.netlify.app/



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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#define SDL_MAIN_USE_CALLBACKS 1 // Use the callbacks instead of main()
 
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
 
#ifdef __EMSCRIPTEN__
#include <SDL3/SDL_opengles2.h>
#else
#include <glad/glad.h>
#endif // __EMSCRIPTEN__
 
#define NK_INCLUDE_FIXED_TYPES
#define NK_INCLUDE_STANDARD_IO
#define NK_INCLUDE_STANDARD_VARARGS
#define NK_INCLUDE_DEFAULT_ALLOCATOR
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
#define NK_INCLUDE_FONT_BAKING
#define NK_INCLUDE_DEFAULT_FONT
#define NK_IMPLEMENTATION
#define NK_SDL_GLES2_IMPLEMENTATION
#include "nuklear.h"
#include "nuklear_sdl3_gles2.h"
 
static SDL_Window *window = NULL;
SDL_GLContext glContext;
 
struct nk_context *ctx;
 
char buffer[256];
int text_len = 0;
 
// This function runs once at startup
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;
    }
 
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); // Enable MULTISAMPLE
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2); // can be 2, 4, 8 or 16
 
    const char *title = "Example in C, SDL3, and OpenGL";
    size_t canvasWidth = 350;
    size_t canvasHeight = 350;
    window = SDL_CreateWindow(title, canvasWidth, canvasHeight, SDL_WINDOW_OPENGL);
    if (!window)
    {
        SDL_Log("Couldn't create the window: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
 
    glContext = SDL_GL_CreateContext(window);
    if (!glContext)
    {
        SDL_Log("Couldn't create the glContext: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
 
    SDL_GL_SetSwapInterval(1); // Turn on vertical sync
    SDL_StartTextInput(NULL);
 
#ifdef __WIN32__
    if (!gladLoadGL())
    {
        SDL_Log("Failed to initialize OpenGL function pointers");
        return SDL_APP_FAILURE;
    }
#endif // __WIN32__
 
    glClearColor(50.f / 255.f, 50.f / 255.f, 50.f / 255.f, 1.f);
    glViewport(0, 0, canvasWidth, canvasHeight);
 
    // Init Nuklear
    ctx = nk_sdl_init(window);
 
    // Fonts (optional)
    struct nk_font_atlas *atlas;
    nk_sdl_font_stash_begin(&atlas);
    nk_sdl_font_stash_end();
 
    return SDL_APP_CONTINUE;
}
 
// This function runs when a new event (mouse input, keypresses, etc) occurs
SDL_AppResult SDL_AppEvent(void *appState, SDL_Event *event)
{
    if (event->type == SDL_EVENT_QUIT)
        return SDL_APP_SUCCESS;
 
    nk_input_begin(ctx);
    nk_sdl_handle_event(event);
    nk_input_end(ctx);
 
    return SDL_APP_CONTINUE;
}
 
// This function runs once per frame, and is the heart of the program
SDL_AppResult SDL_AppIterate(void *appState)
{
    // GUI
    if (nk_begin(ctx, "Demo", nk_rect(50, 50, 220, 150),
            NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE |
                NK_WINDOW_MINIMIZABLE | NK_WINDOW_TITLE))
    {
        // nk_layout_row_static(ctx, 30, 200, 1);
        // nk_label(ctx, "Hello, Nuklear!", NK_TEXT_LEFT);
        // if (nk_button_label(ctx, "Press Me"))
        // {
        //     SDL_Log("Button was pressed!");
        // }
 
        nk_layout_row_dynamic(ctx, 30, 1);
        nk_label(ctx, "Enter your name:", NK_TEXT_LEFT);
        nk_edit_string(ctx, NK_EDIT_FIELD | NK_EDIT_CLIPBOARD,
            buffer, &text_len, sizeof(buffer),
            nk_filter_default);
 
        nk_label(ctx, "Hello, Nuklear!", NK_TEXT_LEFT);
        if (nk_button_label(ctx, "Press Me"))
        {
            SDL_Log("Button was pressed!");
        }
    }
    nk_end(ctx);
 
    glClear(GL_COLOR_BUFFER_BIT);
    nk_sdl_render(NK_ANTI_ALIASING_ON, 512 * 1024, 128 * 1024);
 
    // Update the screen
    SDL_GL_SwapWindow(window);
    return SDL_APP_CONTINUE;
}
 
// This function runs once at shutdown
void SDL_AppQuit(void *appState, SDL_AppResult result)
{
    // Cleanup
    nk_sdl_shutdown();
    SDL_GL_DestroyContext(glContext);
 
    // SDL will clean up the window for us
}
Я задал этот вопрос в Issue: SDL3 support

Инструкция по сборке примера для Windows и WASM с помощью MinGW Но надо будет скопировать папку SDL3 и glad в libs и поменять пути на относительные пути в config.bat и CMakeLists.txt или использовать абсолютные пути а библиотеки положить в одну общую папку, например, в папку E:/libs, так как в прикреплённом примере к данному сообщению я подключил библиотеки из общей папки по абсолютным путям.

Миниатюры
Вложения
Тип файла: zip nuklear-opengl-sdl3-c.zip (229.9 Кб, 2 просмотров)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
08.06.2025, 14:57
Помогаю со студенческими работами здесь

Как правильно изучать язык C++ для разработки игр? + какой игровой движок посоветуете?
Здравствуйте! Хочу задать уже не раз, наверное, заданный вопрос, на который хотел бы получить...

под движок Source делаю свой мод
Всем здрасте! Есть вопрос: я программирую под движок Source делаю свой мод, вот только проблема в...

как написать свой движок для сайта?
Всем привет. Дорогие форумчане, меня интересует один несрочный вопросец - как написать свой движок...

Написать свой движок с нуля
Как написать свой движок с нуля при помощью C++. Заранее спасибо.

Закрепить в проект свой движок
Добрый день, можете объяснить или дать ссылку как &quot;закрепить&quot; свой движок в проект. Есть...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
PowerShell Snippets
iNNOKENTIY21 11.11.2025
Модуль PowerShell 5. 1+ : Snippets. psm1 У меня модуль расположен в пользовательской папке модулей, по умолчанию: \Documents\WindowsPowerShell\Modules\Snippets\ А в самом низу файла-профиля. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru