digitalmars.D.learn - Threading with SDL
- Adrian =?UTF-8?B?UHJldcOf?= (29/29) Nov 19 Hey,
- user1234 (5/33) Nov 19 Given the information it's hard to reply but I'd say pass a
- Salih Dincer (105/119) Nov 19 ```d
- Adrian =?UTF-8?B?UHJldcOf?= (8/8) Nov 20 I think I have found the problem: SDL2 for window creation.
- Salih Dincer (7/11) Nov 20 It seems like it can complicate things when you want to use
Hey, I'm looking at **D** right now because I find it much easier to create native applications as opposed to C++. I have the following project structure: ``` - main.d (Booting) - client.d - Renderer.d - Manager - SDL2.d - GLFW.d - RenderingTargets - DirectX.d - Vulkan.d - OpenGL.d ``` A new client instance is created in main.d. This will later serve as the “main game” instance. A new instance of Renderer.d is created here. This contains the window manager (e.g. via `SDL2` or `GLFW`) and the respective rendering engine (`Vulkan`, `DirectX`, `OpenGL`, etc.). However, as soon as I initialize the window in SDL2.d and then want to render it, the whole thing blocks the client. The RenderingTarget must create `SDL2` or `GLFW` as an instance here, as there are differences between the individual graphics interfaces and `GLFW`, for example, does not support DirectX. How can I implement the whole thing thread-based so that the client functions are executed as soon as `SDL2` blocks the application?
Nov 19
On Tuesday, 19 November 2024 at 09:08:46 UTC, Adrian Preuß wrote:Hey, I'm looking at **D** right now because I find it much easier to create native applications as opposed to C++. I have the following project structure: ``` - main.d (Booting) - client.d - Renderer.d - Manager - SDL2.d - GLFW.d - RenderingTargets - DirectX.dWell given the informations> - Vulkan.d- OpenGL.d ``` A new client instance is created in main.d. This will later serve as the “main game” instance. A new instance of Renderer.d is created here. This contains the window manager (e.g. via `SDL2` or `GLFW`) and the respective rendering engine (`Vulkan`, `DirectX`, `OpenGL`, etc.). However, as soon as I initialize the window in SDL2.d and then want to render it, the whole thing blocks the client. The RenderingTarget must create `SDL2` or `GLFW` as an instance here, as there are differences between the individual graphics interfaces and `GLFW`, for example, does not support DirectX. How can I implement the whole thing thread-based so that the client functions are executed as soon as `SDL2` blocks the application?Given the information it's hard to reply but I'd say pass a delegate instead of using static constructors, so that when the basement is there, the basement can launch what depends on it.
Nov 19
On Tuesday, 19 November 2024 at 09:08:46 UTC, Adrian Preuß wrote:I have the following project structure: ``` - main.d (Booting) - client.d - Renderer.d - Manager - SDL2.d - GLFW.d - RenderingTargets - DirectX.d - Vulkan.d - OpenGL.d ``````d module game.main; import core.thread; import core.sync.semaphore; import std.stdio; import std.concurrency; // Renderer interface abstract class Renderer { private bool isRunning = true; protected Tid mainThreadId; this(Tid mainThreadId) { this.mainThreadId = mainThreadId; } void initialize() { // Initialization logic } void run() { while (isRunning) { // Rendering loop renderFrame(); } } protected void renderFrame() { // Implement rendering logic } void stop() { isRunning = false; } } // SDL2 Specific Renderer class SDL2Renderer : Renderer { this(Tid mainThreadId) { super(mainThreadId); } override void initialize() { // SDL2 specific initialization import derelict.sdl2.sdl; DerelictSDL2.load(); SDL_Init(SDL_INIT_VIDEO); // Create window, context, etc. } override protected void renderFrame() { import derelict.sdl2.sdl; SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: send(mainThreadId, "renderer_stopped"); stop(); break; default: break; } } // Actual rendering logic // SDL_GL_SwapWindow(), etc. } } // Game Client class GameClient { private Renderer renderer; private Tid rendererThread; this() { // Create a thread for rendering rendererThread = spawn(&rendererLoop, thisTid); } private void rendererLoop() { // Initialize renderer on its own thread auto sdlRenderer = new SDL2Renderer(thisTid); sdlRenderer.initialize(); sdlRenderer.run(); } void run() { // Main game loop while (true) { // Non-blocking game logic updateGameState(); // Check for renderer messages receiveTimeout( dur!"msecs"(10), (string msg) { if (msg == "renderer_stopped") { break; } } ); } } private void updateGameState() { // Game state update logic // This runs independently of rendering } void shutdown() { // Send stop signal to renderer thread send(rendererThread, "stop"); } } // Main entry point void main() { auto game = new GameClient(); game.run(); } ``` SDB 79
Nov 19
I think I have found the problem: SDL2 for window creation. Now I implemented my own window manager with contextual graphics bindings for Vulkan, OpenGL and DirectX (9/10/11/12) with a focus on threading and it seems that this is a good solution now. Predefined libs/dubs like SDL2 or GLFW assume that the main handling exists on a static basis. I've spent hours trying to make it asynchronous, but it doesn't really work and only causes problems.
Nov 20
On Wednesday, 20 November 2024 at 11:53:09 UTC, Adrian Preuß wrote:I think I have found the problem: SDL2 for window creation. Now I implemented my own window manager with contextual graphics bindings for Vulkan, OpenGL and DirectX (9/10/11/12) ...It seems like it can complicate things when you want to use multiple threads for rendering and window management. I hope that your own solution will overcome the limitations of SDL2 with messaging and stateful control. Good luck... SDB 79
Nov 20