Setting up IXWebSocket with SDL3 and OpenGL (MinGW) Настройка IXWebSocket с SDL3 и OpenGL (MinGW)
Building and running an SDL3 and OpenGL 3.3 desktop application with IXWebSocket networking on Windows using MinGW 13.1 and CMake. Сборка и запуск десктопного приложения SDL3 и OpenGL 3.3 с сетевой частью на IXWebSocket на Windows с помощью MinGW 13.1 и CMake.
-
1. Obtain SDL3 and GLAD 1. Получение SDL3 и GLAD
Follow the guide to install and configure SDL3 and GLAD using CMake: Setting up SDL3 with find_package (MinGW). Следуйте руководству по установке и настройке SDL3 и GLAD с помощью CMake: Настройка SDL3 с помощью find_package (MinGW).
-
2. Obtain IXWebSocket 2. Получение IXWebSocket
Follow the guide to install and configure IXWebSocket using CMake: Building IXWebSocket, MbedTLS, and zlib from Source (MinGW). Следуйте руководству по установке и настройке IXWebSocket с помощью CMake: Сборка IXWebSocket, MbedTLS и zlib из исходного кода (MinGW).
3. Project Structure 3. Структура проекта
Create an empty folder named ixwebsocket-opengl-sdl3-cpp and set up the following files:
Создайте пустую папку с именем ixwebsocket-opengl-sdl3-cpp и подготовьте следующие файлы:
ixwebsocket-opengl-sdl3-cpp/
├── CMakeLists.txt
└── src/
└── main.cpp
4. Project Configuration (CMakeLists.txt) 4. Конфигурация проекта (CMakeLists.txt)
Copy and paste the layout rules below to resolve static headers and add internal Win32 socket subsystems (ws2_32, crypt32, bcrypt):
Скопируйте и вставьте правила конфигурации ниже, чтобы подключить статические заголовки и системные библиотеки сокетов Win32 (ws2_32, crypt32, bcrypt):
set(CMAKE_BUILD_TYPE "Debug")
cmake_minimum_required(VERSION 3.21)
project(ixwebsocket-opengl-sdl3-cpp)
# SDL3 Setup
set(SDL3_DIR "C:/libs/SDL3-devel-3.4.8-mingw/lib/cmake/SDL3")
find_package(SDL3 REQUIRED)
add_executable(app)
# Include Directories
target_include_directories(app PRIVATE
"C:/libs/glad-0.1.36/opengl-3.3/include"
"C:/libs/IXWebSocket-12.0.0-mingw-master/include"
"C:/libs/mbedtls-4.1.0-mingw/include"
"C:/libs/zlib-1.3.2-mingw/include"
)
# Source Mapping
target_sources(app PRIVATE
"C:/libs/glad-0.1.36/opengl-3.3/src/glad.c"
src/main.cpp
)
# Static Link Targets (Order Matters for MinGW Linker Validation!)
target_link_libraries(app PRIVATE
SDL3::SDL3
"C:/libs/IXWebSocket-12.0.0-mingw-master/lib/libixwebsocket.a"
"C:/libs/mbedtls-4.1.0-mingw/lib/libmbedx509.a"
"C:/libs/mbedtls-4.1.0-mingw/lib/libmbedtls.a"
"C:/libs/mbedtls-4.1.0-mingw/lib/libmbedcrypto.a"
"C:/libs/zlib-1.3.2-mingw/lib/libzs.a"
ws2_32
wsock32
crypt32
bcrypt
)
target_link_options(app PRIVATE -mconsole)
5. Source Code 5. Исходный код
This application initializes an OpenGL 3.3 context via the modern SDL3 callback structure while managing a non-blocking WebSocket connection running on a background thread:
Это приложение инициализирует контекст OpenGL 3.3 с помощью современной структуры колбэков SDL3, параллельно управляя неблокирующим WebSocket-подключением, работающим в фоновом потоке:
src/main.cpp
#define SDL_MAIN_USE_CALLBACKS 1
#include <glad/glad.h>
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <ixwebsocket/IXNetSystem.h> // Required header for Network Init
#include <ixwebsocket/IXWebSocket.h>
#include <iostream>
struct AppContext
{
SDL_Window *window;
SDL_GLContext glContext;
ix::WebSocket webSocket;
};
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
// Initialize the network subsystem for Windows (Winsock)
ix::initNetSystem();
if (!SDL_Init(SDL_INIT_VIDEO))
{
std::cerr << "Failed to init SDL Video" << std::endl;
ix::uninitNetSystem();
return SDL_APP_FAILURE;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_Window *window =SDL_CreateWindow("SDL3 + IXWebSocket", 380, 380, SDL_WINDOW_OPENGL);
if (!window)
{
ix::uninitNetSystem();
return SDL_APP_FAILURE;
}
SDL_GLContext glContext =SDL_GL_CreateContext(window);
if (!glContext)
{
ix::uninitNetSystem();
return SDL_APP_FAILURE;
}
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
{
std::cerr << "Failed to init GLAD" << std::endl;
SDL_GL_DestroyContext(glContext);
SDL_DestroyWindow(window);
ix::uninitNetSystem();
return SDL_APP_FAILURE;
}
SDL_GL_SetSwapInterval(1);
// Allocate the state onto the heap and pass it to SDL
AppContext *app = new AppContext();
app->window = window;
app->glContext = glContext;
*appstate = app;
// IXWebSocket Network Initialization
std::string url("ws://localhost:3000");
app->webSocket.setUrl(url);
app->webSocket.setOnMessageCallback([app](const ix::WebSocketMessagePtr &msg) {
if (msg->type == ix::WebSocketMessageType::Message)
{
std::cout << "Received: " << msg->str << std::endl;
}
else if (msg->type == ix::WebSocketMessageType::Open)
{
std::cout << "Connected to WebSocket Server!" << std::endl;
app->webSocket.send("Hello from SDL3 Client!");
}
else if (msg->type == ix::WebSocketMessageType::Close)
{
std::cout << "Disconnected from Server" << std::endl;
}
else if (msg->type == ix::WebSocketMessageType::Error)
{
std::cerr << "Error: " << msg->errorInfo.reason << std::endl;
}
});
std::cout << "Connecting to " << url << "..." << std::endl;
app->webSocket.start(); // Non-blocking background worker thread
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
if (event->type == SDL_EVENT_QUIT)
{
return SDL_APP_SUCCESS;
}
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppIterate(void *appstate)
{
AppContext *app = (AppContext *)appstate;
// Render loop backdrop updates
glClearColor(0.15f, 0.15f, 0.15f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(app->window);
return SDL_APP_CONTINUE;
}
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
AppContext *app = (AppContext *)appstate;
if (app)
{
app->webSocket.stop(); // Cleanly stop background socket thread
SDL_GL_DestroyContext(app->glContext);
SDL_DestroyWindow(app->window);
delete app; // Free allocated memory
}
// Clean up Windows socket resources on exit
ix::uninitNetSystem();
SDL_Quit();
std::cout << "Application exited cleanly." << std::endl;
}
6. Test Node.js WebSocket Server 6. Тестовый сервер WebSocket на Node.js
To verify your application communication layer locally, follow these steps to set up a small WebSocket server:
Чтобы проверить работоспособность коммуникационного слоя локально, выполните следующие шаги для настройки небольшого WebSocket-сервера:
A. Prerequisites & Installation A. Предварительные требования и установка
- Download and install Node.js if you haven't already. Скачайте и установите Node.js, если он еще не установлен.
-
Open your terminal/command prompt and install
nodemonglobally for automatic server restarts: Откройте терминал/командную строку и установитеnodemonглобально для автоматического перезапуска сервера:npm i nodemon -g
B. Create the Server Folder and Script B. Создание папки сервера и скрипта
-
Create a new folder named
serverin your project directory. Создайте новую папку с именемserverв директории вашего проекта. -
Inside the
serverfolder, create a file namedserver.jsand paste the following code: Внутри папкиserverсоздайте файл с именемserver.jsи вставьте следующий код:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 3000 });
wss.on('connection', (ws) => {
console.log('Client connected');
ws.on('message', (message) => {
console.log('Received message:', message.toString());
});
ws.on('close', () => {
console.log('Client disconnected');
});
});
console.log('WebSocket server is listening on ws://localhost:3000');
C. Run the Server C. Запуск сервера
-
Open Command Prompt (CMD) or terminal inside the
serverfolder. Откройте командную строку (CMD) или терминал внутри папкиserver. -
Install the required
wsdependency locally: Установите необходимую зависимостьwsлокально:npm install ws -
Start the server using
nodemon: Запустите сервер с помощьюnodemon:nodemon server.js
Once the server is running and listening on port 3000, proceed to build and run the client application using the automation scripts below.
Как только сервер запустится и начнет прослушивать порт 3000, переходите к сборке и запуску клиентского приложения с помощью скриптов автоматизации ниже.
7. Automation Scripts (.bat) 7. Скрипты автоматизации (.bat)
Create these three quick launch scripts in the root directory of your project to automate desktop builds:
Создайте три файла автоматизации в корневой папке вашего проекта для быстрой сборки десктопной версии:
1. config-exe.bat
cmake -G "MinGW Makefiles" -S . -B dist/exe
2. build-exe.bat
cd dist\exe
cmake --build .
cd ..\..
3. run-exe.bat
dist\exe\app
6. Source Code & Downloads 6. Исходный код и загрузки
You can download the complete configured project as a ZIP archive or explore the source code directly on GitHub: Вы можете скачать готовую настроенную сборку проекта в виде ZIP-архива или изучить исходный код прямо на GitHub:
Support My Work Поддержать проект
If these tutorials helped you, consider buying me a coffee! Если эти туториалы вам помогли, вы можете поддержать автора.
Sberbank
Direct transfer via phone number Перевод по номеру телефона
Bybit (USDT TRC20)
Support via Cryptocurrency Поддержка криптовалютой