supernovaengine / supernova

Game engine for 2D and 3D projects with entity component system (ECS) and data-oriented design
http://www.supernovaengine.org
MIT License
291 stars 28 forks source link

Docs on rendering pipeline #10

Open NaLiJa opened 3 weeks ago

NaLiJa commented 3 weeks ago

Hi there, Many thanks for making this engine available, it looks very interesting! Do you perhaps have some minimal docs on the rendering pipeline? I wonder whether it might be possible to integrate rmlui lib into your engine ( a low level ui library). It is rendered directly on a window context (see e.g. https://github.com/mikke89/RmlUi/tree/master/Backends). Do you perhaps have any advice which would be the preferred place to inject this into supernova? Perhaps in subsystem/renderer? Thanks for your great work!

eduardodoria commented 3 weeks ago

I don't know how RmlUi is built, but I have some experience with ImGui and I think they might be similar. I think you have two ways to do this integration. The first one is the best but far more complicated and the second is easier but platform dependent.

  1. Creating a RmlUi backend, renderer and platform for Supernova API:

    Basically, you need to create a backend using engine/core/render classes and integrate system events. This method you maybe need to extend two classes: Rml::RenderInterface and Rml::SystemInterface. So your files could be:

    • RmlUi_Platform_Supernova.cpp
    • RmlUi_Renderer_Supernova.cpp
    • RmlUi_Backend_Supernova.cpp

    Doing like this you can use RmlUi in all supported platforms that is allready (and could be supported in future) by Supernova.

  2. Rendering Supernova scene to a texture and using it in RmlUi:

    I have done something like this in editor project https://github.com/eduardodoria/supernova-editor using (Dear ImGui). It is a very early project and that is why it is not yet integrated into the main repo. This uses features that are only in main branch yet.

    You create an external Framebuffer and uses it to draw entire engine. Something like this:

    Framebuffer framebuffer;
    
    Scene scene;
    Polygon triangle(&scene);
    
    triangle.addVertex(0, -100);
    triangle.addVertex(-50, 50);
    triangle.addVertex(50, 50);
    
    triangle.setPosition(Vector3(300,300,0));
    triangle.setColor(0.6, 0.2, 0.6, 1);
    
    Engine::setScene(&scene);
    Engine::setFramebuffer(&framebuffer);

    So, in your RmlUi project you can use the texture generated by this framebuffer depending of your backend:

    framebuffer.getColorTexture().getGLHandler() // for GL backends
    framebuffer.getColorTexture().getMetalHandler() // for Metal backends
    framebuffer.getColorTexture().getD3D11Handler() // for DX11 backends

    Look also that when render ImGui at my project here, I need to call render.startRenderPass(display_w, display_h) before, to clear some stufs leaved by last framebuffer pass (witch is the Supernova scene) and make sure that ImGui will be rendered at default framebuffer.

NaLiJa commented 3 weeks ago

Thank you very much for your detailed answer! I might give this a try although I am not sure anymore whether it is a good idea overall. What makes your engine so interesting is that it is very lean. Adding rmlui would probably add some notable overhead. Perhaps it might be better to add more ui components directly. if anything useable emerges from my tries I will report back! Thanks again for your fast and kind reply.

eduardodoria commented 3 weeks ago

I know we do not have many UI components this moment, but the ones that exist are already enough to make simple UI like the many of games.

I have two UI samples that you can see here: