golang-ui / nuklear

This project provides Go bindings for nuklear.h — a small ANSI C GUI library.

Home Page:https://github.com/vurtun/nuklear

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Multiple Window + GL contexts - trouble finding documentation (or not possible?)

mjevans opened this issue · comments

I'm trying to develop an small program that normally has one small control window, but might open up larger temporary windows for more complex and context dependent situations.

However at present the closet I can get is an error like:

github.com/golang-ui/nuklear/nk/nuklear.h:18633: nk_begin_titled: Assertion `win->seq != ctx->seq' failed.
signal: aborted (core dumped)
** (extra at end)

From that error and the documentation it references I know I'm /somehow/ supposed to manage application state... however it's unclear how to do that. As far as I can tell after a few hours of searching, there's something that either I've missed, or that doesn't yet exist in the golang-ui/nuklear library for switching or passing it a context state.

impl_glfw_gl3.go line 260 defines a package global variable...

var state = &platformState{
ogl: &platformDevice{},
}

Which impl_glfw_common.go (27) NkPlatformInit assigns the window and a created state to, as well as calling NkInitDefault (that calls the underlying nk_init_default library binding) that initializes the nuklear context for the window as well.

The structure NkPlatformInit and that single global state heavily suggests that I can't actually have multiple distinct OS level windows. I don't think that's necessarily a limitation of the underlying Nuklear library, but it seems like it might require a major refactoring of this library to use it in a multiple contexts friendly way. Previously I've used higher level frameworks that make such architectural decisions for me, so I'm not even sure if multiple contexts is a good idea.

    // near github.com/golang-ui/nuklear/nk/nuklear.h:18633
    /* update window */
    win->flags &= ~(nk_flags)(NK_WINDOW_PRIVATE-1);
    win->flags |= flags;
    if (!(win->flags & (NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE)))
        win->bounds = bounds;
    /* If this assert triggers you either:
     *
     * I.) Have more than one window with the same name or
     * II.) You forgot to actually draw the window.
     *      More specific you did not call `nk_clear` (nk_clear will be
     *      automatically called for you if you are using one of the
     *      provided demo backends). */
    NK_ASSERT(win->seq != ctx->seq);
    win->seq = ctx->seq;
    if (!ctx->active && !(win->flags & NK_WINDOW_HIDDEN)) {
        ctx->active = win;
        ctx->end = win;
    }

Hi, the documentation is limited to nuklear.h comments, unfortunately I'm just providing bindings and can't know better what's going on.

But the global state in impl_glfw_gl3.go is a problem, yep :(
You can try to fix it right there, try to create a map for GLFW windows. I will merge the changes if they solve your problem..

Part of the problem here is, maybe, the confusion between Nuklear's idea of windows and GLFW's idea of windows. (You can render multiple Nuklear "windows" in a single GLFW window - and, in fact, Nuklear doesn't keep track of target windows in the draw commands list, as it assumes that you can draw into the entire display.)
It's probably better to associate a given Nuklear "context" with a GLFW window - so I would probably make most of the go-nuklear functions (like NkPlatformInit) into methods of a state interface, so you can have 1 "state" per GLFW window if you want more than one.