Basic GUI work

After having worked a lot on the renderer lighting/shadow mapping part of the engine and having digged through tons of math in the process, I decided to pause my work in that area and instead do something different. So I did some bug hunting, improved OpenGL state handling and cleaned up a lot of code.

Another important thing I started to tackle is the GUI framwork which is overdue for quite some time now. In the process of implementing a nice and simple GUI, I’ll rework the scene graph aswell and integrate it into the GUI as a special 3D-Scene widget. Up to now I have started to code a window and text class. They both are derived from a base class called nx_ScreenElement. Here is a stripped down code snippet of that class:

class nx_ScreenElement
{
  protected:
    nxRect_t m_position;
    I32 m_zOrder;
    bool m_visible;

  public:
    nx_ScreenElement(const nxRect_t& position) : m_position(position), m_zOrder(0), m_visible(true) {}
    virtual ~nx_ScreenElement() {}
    virtual bool onMessage(const nx_Message& message) = 0;
    virtual void update(const F32 deltaTimeInSeconds) = 0;
    virtual void render(const F32 deltaTimeInSeconds) = 0;
    virtual void restore() = 0;

    I32 getZOrder() const { return m_zOrder; }
    void setZOrder(const I32 zOrder) { m_zOrder = zOrder; }

    bool isVisible() const { return m_visible; }
    void setVisible(const bool visible) { m_visible = visible; }

    bool operator<(const nx_ScreenElement& rhs) const { return getZOrder() < rhs.getZOrder(); }
};

 

Every element on the screen will be based on this class. For example: nx_Scene, nx_GUIWindow, nx_GUIText, nx_GUIButton, … There is a master list of all screen elements in the engine which is sorted by z-order. Than system messages like KeyDown, MouseMove, MouseClick, … are send to the elements from front to back via the onMessage method. Each screen element may do some work based on a message and consume it or not. This way it is incredible easy to pass input to all active screen elements. Basically the same happens with update, render and restore. The render method for example is called on all screen elements in the list in reverese order to draw everything from back to front.

I’m still in the early prototyping and testing phase, but the first results are very promising. Here is a screenshot of 4 test windows which could be freely moved and resized on the screen. They are already correctly sorted by z-order and will switch to the front when selected. All colors are still static at the moment, but I have coded the classes in a way that it’ll be extremely easy to make it completely costumizable in the future. There is basic code for texturing/theming support in place aswell, even if I haven’t used it yet.

Leave a Reply

You must be logged in to post a comment.