www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Threading with SDL

reply Adrian =?UTF-8?B?UHJldcOf?= <adrian.preuss icloud.com> writes:
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 2024
next sibling parent user1234 <user1234 12.de> writes:
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.d
Well 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 2024
prev sibling next sibling parent Salih Dincer <salihdb hotmail.com> writes:
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 2024
prev sibling parent reply Adrian =?UTF-8?B?UHJldcOf?= <adrian.preuss icloud.com> writes:
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 2024
parent Salih Dincer <salihdb hotmail.com> writes:
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 2024