digitalmars.D.learn - Threading with SDL
- Adrian =?UTF-8?B?UHJldcOf?= (29/29) Nov 19 2024 Hey,
- user1234 (5/33) Nov 19 2024 Given the information it's hard to reply but I'd say pass a
- Salih Dincer (105/119) Nov 19 2024 ```d
- Adrian =?UTF-8?B?UHJldcOf?= (8/8) Nov 20 2024 I think I have found the problem: SDL2 for window creation.
- Salih Dincer (7/11) Nov 20 2024 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 2024
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 2024
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
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
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