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 (Russia only) Сбербанк (только для РФ)
Direct transfer via phone number (Russia only) Перевод по номеру телефона (только для РФ)
USDT TRC20
Support via Cryptocurrency Поддержка криптовалютой