• Solar System

  • Security Camera

  • Tabletop

  • Third Person Camera

OpenGL - Graphics


Description

This 3D Scene utilizes various OpenGL techniques; transparency, lighting and planar shadows. As well as Controlled and automated cameras, and a third person camera with a nicely delayed and lerped follow camera. Use of the stencil buffer is used to ensure elements are drawn only where required. 3D and 2D Text rendering is achieved with naïve bitmap font with blending and transparency.

The scene utilizes the use of C++11 threading, to allow the creation of a multi-threaded screen loading system. This ensures the user always knows what is going on. This system is easily scale-able and adaptable with growing needs due to the barrier, and notification system in place. With the use of C++11 lambda functions the queuing of tasks is made incredibly easy.

Going forward

Best options going forward will be the use of shaders to enable signed distance field font rendering, to allow for better fonts at different levels, whilst keeping overhead low. Whilst also implementing shadow mapping, and shadow volume techniques to improve the shadows.

However, going forward, I will be moving towards Direct X 11 due to assignment requirements. Getting these methods working in Direct X will be an interesting experiment.

Challenges encountered

The definition of thread safe is apparently up for debate in the open source community, as the library being used for texture loading was stated as multi-threading safe, however in practice this is only partial true. Under stress testing running multiple threads loading textures threw many errors, this is believed to be due to the way the library handles memory checking and loading, causing a bottle neck in the system causing errors.

This is dealt with within the texture loading code, as even though this requires some textures to be reloaded, there was still an improvement in load times.

Not all free models are created equally, had to change a lot of textures and normals to make them game ready.

Cool code

At least what I found interesting. The use of std::function<void()> allowed for tasks to be easily queued using lambda functions.​

void QueueTask(std::function<void()> function, bool requires_hrc = true);
 
screen_manager_->thread_farm().QueueTask([&] {
    main_skybox_.LoadTexture("bin/textures/space_cubemap.png");
    percentage_ = percentage_ + 0.2f;
    texture_load_.NotifyAll();
});

​The following code was mainly due to the way the Win32 Api works. I was fed up of losing my mouse between different screens.

// Ensures it sets cursor on or off no matter where you call DisplayCursor.
// So much easier than trying to catch all your show and hides for cursor.
inline void DisplayCursor(bool val) {
    int count = ShowCursor(val);
    if (val) {
        while (count < 0) {
            count = ShowCursor(true);
        }
    }
    else {
        while (count >= 0) {
            count = ShowCursor(false);
        }
    }
}

​This function was created for the simple reason of ensuring my laptop didn’t burn out, as their was no way of enabling V Sync. This also allowed a very crude fps check to see if any change had majorly broken the code. Though I did run a large number of tests on various systems.

void Scene3D::SetVSync(bool sync) {
    // Function pointer for the wgl extention function we need to enable/disable    
    typedef BOOL(APIENTRY *PFNWGLSWAPINTERVALPROC)(int);
    PFNWGLSWAPINTERVALPROC wglSwapIntervalEXT = 0;
    // try to get the extension
    wglSwapIntervalEXT = (PFNWGLSWAPINTERVALPROC)wglGetProcAddress("wglSwapIntervalEXT");
 
    // use it if it exists, otherwise meh...
    if (wglSwapIntervalEXT)
        wglSwapIntervalEXT(sync);
}

Other things I’m proud of are a system for changing between; windowed and windowed full-screen modes and then reverting back to its previous size and position. As well as the easy to use thread farm system for queuing tasks and the easy to use planar shadow system.

Products used