Nuklear use with ORX engine



Some handy dandy links for those of you that aren't familiar with these.

Nuklear: https://github.com/Immediate-Mode-UI/Nuklear
ORX: https://orx-project.org/

Being primarily a C# programmer I have been spending more time in C++ however found that a lot of the appeal of C++ engine development is the control you get. The downside is if you are looking for something like monogame or unity you aren't going to get it (the instant gratification and only focus on the game part).

I went through a few engines, started creating my own and realised I didn't enjoy the engine development process. I do love myself some game programming so I thought I'd settle on that for now and revisit SDL or SFML at a later point when I have an idea cemented.

Anyway I have been working on mainly a UI driven game as a test bed for learning and I like the idea so I found my way through UI options. So many great UI frameworks it is difficult to pick:

There is a great list you can find here: https://philippegroarke.com/posts/2018/c++_ui_solutions/


I wanted something relatively light weight, already had some work proven it could work in ORX and I could scale at my own rate without being a lot of bloat. In the end I integrated ImGui, Nuklear and was looking at implementing Qt (more than I probably need).

Nuklear was light, had good documentation and was modifiable. It has the base of everything needed where you can extend it if desired.

Luckily ainvar has written bindings for ORX as I am unfamiliar with this. I went though his code after integrating it and it was straight forward.

The bindings can be found here: https://bitbucket.org/ainvar/nuklear_orx/src/master/ 

The bindings page comes with quite a few demos to toy around with. I will outline the issues I have run into and solutions:
  • NuklearOrx contains Orx as part of its header. Ensure when including nuklear_orx.h you aren't including orx.h

Initialisation

Initialise your context and keep a reference to it for use in your program. I got the below code from the examples included in the NuclearOrx example.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
    m_nuklearCtx = nk_orx_init();

    struct nk_font_atlas* atlas;
    nk_orx_font_stash_begin(&atlas);

    struct nk_font* font_to_use = orxNULL;
    font_to_use = nk_font_atlas_add_from_file(atlas, "./Roboto-Regular.ttf", FONT_SIZE, 0);
    nk_orx_font_stash_end();

    nk_style_set_font(m_nuklearCtx, &font_to_use->handle);

  Bind the events

1
2
3
 orxEvent_AddHandler(orxEVENT_TYPE_RENDER, NuklearOrx_EventHandler);
 orxEvent_AddHandler(orxEVENT_TYPE_VIEWPORT, NuklearOrx_EventHandler);
 orxEvent_AddHandler(orxEVENT_TYPE_DISPLAY, NuklearOrx_EventHandler);


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
orxSTATUS orxFASTCALL NuklearOrx_EventHandler(const orxEVENT *_pstEvent)
{
    switch (_pstEvent->eType)
    {
    case orxEVENT_TYPE_RENDER:
    {
        /* we render Nuklear stuff on the top so we call it at the end of Orx frame rendering cycle */
        if (_pstEvent->eID == orxRENDER_EVENT_STOP)
            nk_orx_render(NK_ANTI_ALIASING_ON);
    }
    break;

    case orxEVENT_TYPE_DISPLAY:
        NuklearOrx_ResizeViewport();
        break;

    default:
        break;
    }

    return orxSTATUS_SUCCESS;
}
 

Make stuff

Yeah make stuff. Follow the Nuklear documentation and you can make whatever it is you like. Here is what I have been working on.



Drawing

Fortunatley the drawing is handled for us as well. To draw items in the GUI layer like circles. The drawing functions are covered a bit differently in the nuklear documentation so the process is to have them drawn last after input and call them in a fashion such as

nk_command_buffer* commandBuffer = nk_window_get_canvas(nuklearContext);
nk_fill_circle(commandBuffer, nk_rect(x, y, width, height), nk_color);

nk_color example is struct nk_color bg = nk_rgb(0, 0, 0);

Please get in touch if you see any issues, have any questions or anything to better this explanation.



Comments