2D Scene Graph

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • 2D Scene Graph

      Hey guys,

      I decided getting started with 2D and OpenGL and I choose using SFML, and i love the archtecture proposed in the book!

      So, I'am in the rendering part where i trying to figure out how the things is draw in the scene!

      About chapter 16 (3D Scenes) i would like to do the same for 2D Scenes to be rendered!

      I just like to know if this is the way to go in 2D world or if there are some way more appropriated to render a scene!
    • I don't have the book in front of me and it's a been a while, so my response will be a bit less specific to the scene nodes from Game Coding Complete.

      The core idea of abstracting render data, spatial partitioning, and scene hierarchies are definitely applicable to 2D. My own personal game engine is a 2D engine and uses these concepts as well, though I've chosen to use other implementations. I'll give a very brief overview of how my own rendering system works so you can see how these concepts are applied. Feel free to ask questions.

      At the highest level, I have a Scene class that serves as the core public interface to the rendering system. It manages the render thread and the render device (the abstraction layer that wraps D3D, OpenGL, or whatever). The magic function is AddObjectToScene(), which takes in a RenderCommand object. The RenderCommand holds exactly what I need to render an object. This includes transform data, texture ID, color/lighting information, etc. Anything that needs to render to the screen calls this function, including entities (my version of actors), the world tiles, and the UI.

      Under the covers, calling this function doesn't render anything. All it does is adds the command to a render queue. The render thread consumes this queue by sorting it and rendering each object. My render thread is always render the frame that the logic thread just built up, so it's basically one frame behind.

      I use a quadtree for spatial partitioning, which helps cull out things I don't need to render.

      -Rez
    • Thanks Rez, very nice answer!

      Your engine seems cool, and yes I have some questions :)

      when you said about
      RenderCommand


      it is a Command design pattern you using ?

      About your Scene Graph, how it is related with the Entity(actor) component system ? Once they have some component that have all of that information your RenderCommand holds to render,

      Thanks for your time on this forum!

    • it is a Command design pattern you using ?

      Not exactly. A RenderCommand encapsulates everything necessary to render a particular type of object. I put them in a list which is sorted and consumed by the render thread on the next frame. It has some similarities to the command pattern, but it's not exactly the same.

      If you're curious, here is the base render command that they all inherit from, copied & pasted directly from my code base:

      Source Code

      1. class RenderCommand
      2. {
      3. protected:
      4. // geometry transform data
      5. float m_x, m_y, m_width, m_height;
      6. int m_z;
      7. float m_sortingYOffset;
      8. // render info
      9. int m_renderStage;
      10. // color
      11. FloatColor m_color;
      12. // An id shared by textures of the same type, but unique among texture
      13. // types (we use ResourceId under the covers)
      14. StringId m_textureId;
      15. public:
      16. // construction
      17. RenderCommand();
      18. virtual ~RenderCommand();
      19. // interface
      20. virtual void RenderColorMap() = 0;
      21. virtual void RenderNormalMap() { }
      22. virtual void RenderSpecularMap() { }
      23. virtual void RenderShadowMap() { }
      24. // accessors
      25. float GetX() const { return m_x; }
      26. float GetY() const { return m_y; }
      27. int GetZ() const { return m_z; }
      28. float GetSortingY() const { return m_sortingYOffset; }
      29. float GetWidth() const { return m_width; }
      30. float GetHeight() const { return m_height; }
      31. const StringId& GetTextureId() const { return m_textureId; }
      32. int GetRenderStage() const { return m_renderStage; }
      33. void SetColor(const FloatColor& color) { m_color = color; }
      34. void SetX(float val) { m_x = val; }
      35. void SetY(float val) { m_y = val; }
      36. void SetZ(int val) { m_z = val; }
      37. void SetSortingY(float val) { m_sortingYOffset = val; }
      38. void SetWidth(float val) { m_width = val; }
      39. void SetHeight(float val) { m_height = val; }
      40. void SetRenderStage(int val) { m_renderStage = val; }
      41. // texture id
      42. void SetTextureId(const StringId& val);
      43. virtual void ApplyCameraOffset(int dx, int dy);
      44. };
      Display All



      About your Scene Graph, how it is related with the Entity(actor) component system ? Once they have some component that have all of that information your RenderCommand holds to render,

      There is a Renderable component (several, actually) that can attached to entities. They have a GetRenderData() function on them that returns a RenderCommand instance, which they generate every frame. The component interfaces with the resource system to load the texture, pulls data from the transform component to figure out where it is, and so on. It's also the thing that a designer tunes.

      -Rez
    • diegorosa wrote:

      Thanks Rez, very nice answer!

      Your engine seems cool, and yes I have some questions :)

      when you said about
      RenderCommand


      it is a Command design pattern you using ?

      About your Scene Graph, how it is related with the Entity(actor) component system ? Once they have some component that have all of that information your RenderCommand holds to render,

      Thanks for your time on this forum!


      I think this is more similar to the "memento" pattern.

      The post was edited 1 time, last by Wolkec ().