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.

Shadow Mapping: Point Lights

Success! After having implemented shadow mapping for directional and spot lights, the engine now supports point lights aswell. As usual the code is a bit quick’n dirty and needs some serious cleanup. Nevertheless I’m already very pleased with the perfomance in the unoptimized state. The following video was captured with 4 fully dynamic, shadow casting point lights. FPS was around 70 on my pretty low tech PC: AMD Athlon X2 4450e (2,3Ghz Dual-Core), ATI HD4670. Even CPU usage was very low, so it’s definetly GPU bound. This leaves a lot of room for CPU stuff like game state handling, physics, culling, resource loading, sound and so on…

 

Shadow Mapping: Spot Light

I finished implementing shadow mapping for spot lights today. It’s only the first try, but it already looks pretty nice. I’m sure with some tweaks in the future it will be really good. Here is a screenshot of a single spot light. Blue line is the direction of the light and red lines are the lights view frustum. Bottom right is the shadow map used for the light.

Basic Shadow Mapping

Another step forward: Basic shadow mapping implementation is done. Up to now it’s only working for directional lights and still very hacky. It definetly needs a few optimizations and cleanups, but it’s still a nice start. I have tweaked my demo application a bit and added one directional light which is spinning around the center of the scene.

 

Deferred Shading: Demo

I build a little demo scene and captured a video. It has 4 fully dynamic point lights:

 

Furthermore the engine now supports directional, point and spot lights. All of them integrated into the scene graph and very easy to use. Next up are optimizations and shadow implementation.