diff --git a/demo/glfw_opengl3/main.c b/demo/glfw_opengl3/main.c index 529e88cc..e1cc27ed 100644 --- a/demo/glfw_opengl3/main.c +++ b/demo/glfw_opengl3/main.c @@ -75,7 +75,8 @@ static void error_callback(int e, const char *d) int main(void) { /* Platform */ - static GLFWwindow *win; + struct nk_glfw glfw = {0}; + GLFWwindow *win; int width = 0, height = 0; struct nk_context *ctx; struct nk_colorf bg; @@ -104,18 +105,18 @@ int main(void) exit(1); } - ctx = nk_glfw3_init(win, NK_GLFW3_INSTALL_CALLBACKS); + ctx = nk_glfw3_init(&glfw, win, NK_GLFW3_INSTALL_CALLBACKS); /* Load Fonts: if none of these are loaded a default font will be used */ /* Load Cursor: if you uncomment cursor loading please hide the cursor */ {struct nk_font_atlas *atlas; - nk_glfw3_font_stash_begin(&atlas); + nk_glfw3_font_stash_begin(&glfw, &atlas); /*struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14, 0);*/ /*struct nk_font *roboto = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 14, 0);*/ /*struct nk_font *future = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13, 0);*/ /*struct nk_font *clean = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12, 0);*/ /*struct nk_font *tiny = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10, 0);*/ /*struct nk_font *cousine = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13, 0);*/ - nk_glfw3_font_stash_end(); + nk_glfw3_font_stash_end(&glfw); /*nk_style_load_all_cursors(ctx, atlas->cursors);*/ /*nk_style_set_font(ctx, &droid->handle);*/} @@ -131,7 +132,7 @@ int main(void) { /* Input */ glfwPollEvents(); - nk_glfw3_new_frame(); + nk_glfw3_new_frame(&glfw); /* GUI */ if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250), @@ -190,10 +191,10 @@ int main(void) * defaults everything back into a default state. * Make sure to either a.) save and restore or b.) reset your own state after * rendering the UI. */ - nk_glfw3_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_BUFFER, MAX_ELEMENT_BUFFER); + nk_glfw3_render(&glfw, NK_ANTI_ALIASING_ON, MAX_VERTEX_BUFFER, MAX_ELEMENT_BUFFER); glfwSwapBuffers(win); } - nk_glfw3_shutdown(); + nk_glfw3_shutdown(&glfw); glfwTerminate(); return 0; } diff --git a/demo/glfw_opengl3/nuklear_glfw_gl3.h b/demo/glfw_opengl3/nuklear_glfw_gl3.h index c8c69160..b16c6f05 100644 --- a/demo/glfw_opengl3/nuklear_glfw_gl3.h +++ b/demo/glfw_opengl3/nuklear_glfw_gl3.h @@ -20,18 +20,20 @@ enum nk_glfw_init_state{ NK_GLFW3_INSTALL_CALLBACKS }; -NK_API struct nk_context* nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state); -NK_API void nk_glfw3_shutdown(void); -NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas); -NK_API void nk_glfw3_font_stash_end(void); -NK_API void nk_glfw3_new_frame(void); -NK_API void nk_glfw3_render(enum nk_anti_aliasing, int max_vertex_buffer, int max_element_buffer); +struct nk_glfw; -NK_API void nk_glfw3_device_destroy(void); -NK_API void nk_glfw3_device_create(void); +NK_API struct nk_context* nk_glfw3_init(struct nk_glfw* glfw, GLFWwindow *win, enum nk_glfw_init_state); +NK_API void nk_glfw3_shutdown(struct nk_glfw* glfw); +NK_API void nk_glfw3_font_stash_begin(struct nk_glfw* glfw, struct nk_font_atlas **atlas); +NK_API void nk_glfw3_font_stash_end(struct nk_glfw* glfw); +NK_API void nk_glfw3_new_frame(struct nk_glfw* glfw); +NK_API void nk_glfw3_render(struct nk_glfw* glfw, enum nk_anti_aliasing, int max_vertex_buffer, int max_element_buffer); + +NK_API void nk_glfw3_device_destroy(struct nk_glfw* glfw); +NK_API void nk_glfw3_device_create(struct nk_glfw* glfw); NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint); -NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff); +NK_API void nk_glfw3_scroll_callback(GLFWwindow *win, double xoff, double yoff); NK_API void nk_glfw3_mouse_button_callback(GLFWwindow *win, int button, int action, int mods); #endif @@ -75,7 +77,7 @@ struct nk_glfw_vertex { nk_byte col[4]; }; -static struct nk_glfw { +struct nk_glfw { GLFWwindow *win; int width, height; int display_width, display_height; @@ -89,7 +91,7 @@ static struct nk_glfw { double last_button_click; int is_double_click_down; struct nk_vec2 double_click_pos; -} glfw; +}; #ifdef __APPLE__ #define NK_SHADER_VERSION "#version 150\n" @@ -98,7 +100,7 @@ static struct nk_glfw { #endif NK_API void -nk_glfw3_device_create(void) +nk_glfw3_device_create(struct nk_glfw* glfw) { GLint status; static const GLchar *vertex_shader = @@ -125,7 +127,7 @@ nk_glfw3_device_create(void) " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" "}\n"; - struct nk_glfw_device *dev = &glfw.ogl; + struct nk_glfw_device *dev = &glfw->ogl; nk_buffer_init_default(&dev->cmds); dev->prog = glCreateProgram(); dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER); @@ -181,9 +183,9 @@ nk_glfw3_device_create(void) } NK_INTERN void -nk_glfw3_device_upload_atlas(const void *image, int width, int height) +nk_glfw3_device_upload_atlas(struct nk_glfw* glfw, const void *image, int width, int height) { - struct nk_glfw_device *dev = &glfw.ogl; + struct nk_glfw_device *dev = &glfw->ogl; glGenTextures(1, &dev->font_tex); glBindTexture(GL_TEXTURE_2D, dev->font_tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -193,9 +195,9 @@ nk_glfw3_device_upload_atlas(const void *image, int width, int height) } NK_API void -nk_glfw3_device_destroy(void) +nk_glfw3_device_destroy(struct nk_glfw* glfw) { - struct nk_glfw_device *dev = &glfw.ogl; + struct nk_glfw_device *dev = &glfw->ogl; glDetachShader(dev->prog, dev->vert_shdr); glDetachShader(dev->prog, dev->frag_shdr); glDeleteShader(dev->vert_shdr); @@ -208,9 +210,9 @@ nk_glfw3_device_destroy(void) } NK_API void -nk_glfw3_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer) +nk_glfw3_render(struct nk_glfw* glfw, enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer) { - struct nk_glfw_device *dev = &glfw.ogl; + struct nk_glfw_device *dev = &glfw->ogl; struct nk_buffer vbuf, ebuf; GLfloat ortho[4][4] = { {2.0f, 0.0f, 0.0f, 0.0f}, @@ -218,8 +220,8 @@ nk_glfw3_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element {0.0f, 0.0f,-1.0f, 0.0f}, {-1.0f,1.0f, 0.0f, 1.0f}, }; - ortho[0][0] /= (GLfloat)glfw.width; - ortho[1][1] /= (GLfloat)glfw.height; + ortho[0][0] /= (GLfloat)glfw->width; + ortho[1][1] /= (GLfloat)glfw->height; /* setup global state */ glEnable(GL_BLEND); @@ -234,7 +236,7 @@ nk_glfw3_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element glUseProgram(dev->prog); glUniform1i(dev->uniform_tex, 0); glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]); - glViewport(0,0,(GLsizei)glfw.display_width,(GLsizei)glfw.display_height); + glViewport(0,0,(GLsizei)glfw->display_width,(GLsizei)glfw->display_height); { /* convert from command queue into draw list and draw to screen */ const struct nk_draw_command *cmd; @@ -276,25 +278,25 @@ nk_glfw3_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element /* setup buffers to load vertices and elements */ nk_buffer_init_fixed(&vbuf, vertices, (size_t)max_vertex_buffer); nk_buffer_init_fixed(&ebuf, elements, (size_t)max_element_buffer); - nk_convert(&glfw.ctx, &dev->cmds, &vbuf, &ebuf, &config); + nk_convert(&glfw->ctx, &dev->cmds, &vbuf, &ebuf, &config); } glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); /* iterate over and execute each draw command */ - nk_draw_foreach(cmd, &glfw.ctx, &dev->cmds) + nk_draw_foreach(cmd, &glfw->ctx, &dev->cmds) { if (!cmd->elem_count) continue; glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id); glScissor( - (GLint)(cmd->clip_rect.x * glfw.fb_scale.x), - (GLint)((glfw.height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * glfw.fb_scale.y), - (GLint)(cmd->clip_rect.w * glfw.fb_scale.x), - (GLint)(cmd->clip_rect.h * glfw.fb_scale.y)); + (GLint)(cmd->clip_rect.x * glfw->fb_scale.x), + (GLint)((glfw->height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * glfw->fb_scale.y), + (GLint)(cmd->clip_rect.w * glfw->fb_scale.x), + (GLint)(cmd->clip_rect.h * glfw->fb_scale.y)); glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset); offset += cmd->elem_count; } - nk_clear(&glfw.ctx); + nk_clear(&glfw->ctx); } /* default OpenGL state */ @@ -309,39 +311,43 @@ nk_glfw3_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint) { + struct nk_glfw* glfw = glfwGetWindowUserPointer(win); (void)win; - if (glfw.text_len < NK_GLFW_TEXT_MAX) - glfw.text[glfw.text_len++] = codepoint; + if (glfw->text_len < NK_GLFW_TEXT_MAX) + glfw->text[glfw->text_len++] = codepoint; } NK_API void -nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff) +nk_glfw3_scroll_callback(GLFWwindow *win, double xoff, double yoff) { + struct nk_glfw* glfw = glfwGetWindowUserPointer(win); (void)win; (void)xoff; - glfw.scroll.x += (float)xoff; - glfw.scroll.y += (float)yoff; + glfw->scroll.x += (float)xoff; + glfw->scroll.y += (float)yoff; } NK_API void -nk_glfw3_mouse_button_callback(GLFWwindow* window, int button, int action, int mods) +nk_glfw3_mouse_button_callback(GLFWwindow* win, int button, int action, int mods) { + struct nk_glfw* glfw = glfwGetWindowUserPointer(win); double x, y; if (button != GLFW_MOUSE_BUTTON_LEFT) return; - glfwGetCursorPos(window, &x, &y); + glfwGetCursorPos(win, &x, &y); if (action == GLFW_PRESS) { - double dt = glfwGetTime() - glfw.last_button_click; + double dt = glfwGetTime() - glfw->last_button_click; if (dt > NK_GLFW_DOUBLE_CLICK_LO && dt < NK_GLFW_DOUBLE_CLICK_HI) { - glfw.is_double_click_down = nk_true; - glfw.double_click_pos = nk_vec2((float)x, (float)y); + glfw->is_double_click_down = nk_true; + glfw->double_click_pos = nk_vec2((float)x, (float)y); } - glfw.last_button_click = glfwGetTime(); - } else glfw.is_double_click_down = nk_false; + glfw->last_button_click = glfwGetTime(); + } else glfw->is_double_click_down = nk_false; } NK_INTERN void nk_glfw3_clipboard_paste(nk_handle usr, struct nk_text_edit *edit) { - const char *text = glfwGetClipboardString(glfw.win); + struct nk_glfw* glfw = usr.ptr; + const char *text = glfwGetClipboardString(glfw->win); if (text) nk_textedit_paste(edit, text, nk_strlen(text)); (void)usr; } @@ -349,6 +355,7 @@ nk_glfw3_clipboard_paste(nk_handle usr, struct nk_text_edit *edit) NK_INTERN void nk_glfw3_clipboard_copy(nk_handle usr, const char *text, int len) { + struct nk_glfw* glfw = usr.ptr; char *str = 0; (void)usr; if (!len) return; @@ -356,74 +363,76 @@ nk_glfw3_clipboard_copy(nk_handle usr, const char *text, int len) if (!str) return; memcpy(str, text, (size_t)len); str[len] = '\0'; - glfwSetClipboardString(glfw.win, str); + glfwSetClipboardString(glfw->win, str); free(str); } NK_API struct nk_context* -nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state) +nk_glfw3_init(struct nk_glfw* glfw, GLFWwindow *win, enum nk_glfw_init_state init_state) { - glfw.win = win; + glfwSetWindowUserPointer(win, glfw); + glfw->win = win; if (init_state == NK_GLFW3_INSTALL_CALLBACKS) { - glfwSetScrollCallback(win, nk_gflw3_scroll_callback); + glfwSetScrollCallback(win, nk_glfw3_scroll_callback); glfwSetCharCallback(win, nk_glfw3_char_callback); glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback); } - nk_init_default(&glfw.ctx, 0); - glfw.ctx.clip.copy = nk_glfw3_clipboard_copy; - glfw.ctx.clip.paste = nk_glfw3_clipboard_paste; - glfw.ctx.clip.userdata = nk_handle_ptr(0); - glfw.last_button_click = 0; - nk_glfw3_device_create(); - - glfw.is_double_click_down = nk_false; - glfw.double_click_pos = nk_vec2(0, 0); - - return &glfw.ctx; + nk_init_default(&glfw->ctx, 0); + glfw->ctx.clip.copy = nk_glfw3_clipboard_copy; + glfw->ctx.clip.paste = nk_glfw3_clipboard_paste; + glfw->ctx.clip.userdata = nk_handle_ptr(0); + glfw->ctx.clip.userdata.ptr = glfw; + glfw->last_button_click = 0; + nk_glfw3_device_create(glfw); + + glfw->is_double_click_down = nk_false; + glfw->double_click_pos = nk_vec2(0, 0); + + return &glfw->ctx; } NK_API void -nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas) +nk_glfw3_font_stash_begin(struct nk_glfw* glfw, struct nk_font_atlas **atlas) { - nk_font_atlas_init_default(&glfw.atlas); - nk_font_atlas_begin(&glfw.atlas); - *atlas = &glfw.atlas; + nk_font_atlas_init_default(&glfw->atlas); + nk_font_atlas_begin(&glfw->atlas); + *atlas = &glfw->atlas; } NK_API void -nk_glfw3_font_stash_end(void) +nk_glfw3_font_stash_end(struct nk_glfw* glfw) { const void *image; int w, h; - image = nk_font_atlas_bake(&glfw.atlas, &w, &h, NK_FONT_ATLAS_RGBA32); - nk_glfw3_device_upload_atlas(image, w, h); - nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex), &glfw.ogl.null); - if (glfw.atlas.default_font) - nk_style_set_font(&glfw.ctx, &glfw.atlas.default_font->handle); + image = nk_font_atlas_bake(&glfw->atlas, &w, &h, NK_FONT_ATLAS_RGBA32); + nk_glfw3_device_upload_atlas(glfw, image, w, h); + nk_font_atlas_end(&glfw->atlas, nk_handle_id((int)glfw->ogl.font_tex), &glfw->ogl.null); + if (glfw->atlas.default_font) + nk_style_set_font(&glfw->ctx, &glfw->atlas.default_font->handle); } NK_API void -nk_glfw3_new_frame(void) +nk_glfw3_new_frame(struct nk_glfw* glfw) { int i; double x, y; - struct nk_context *ctx = &glfw.ctx; - struct GLFWwindow *win = glfw.win; + struct nk_context *ctx = &glfw->ctx; + struct GLFWwindow *win = glfw->win; - glfwGetWindowSize(win, &glfw.width, &glfw.height); - glfwGetFramebufferSize(win, &glfw.display_width, &glfw.display_height); - glfw.fb_scale.x = (float)glfw.display_width/(float)glfw.width; - glfw.fb_scale.y = (float)glfw.display_height/(float)glfw.height; + glfwGetWindowSize(win, &glfw->width, &glfw->height); + glfwGetFramebufferSize(win, &glfw->display_width, &glfw->display_height); + glfw->fb_scale.x = (float)glfw->display_width/(float)glfw->width; + glfw->fb_scale.y = (float)glfw->display_height/(float)glfw->height; nk_input_begin(ctx); - for (i = 0; i < glfw.text_len; ++i) - nk_input_unicode(ctx, glfw.text[i]); + for (i = 0; i < glfw->text_len; ++i) + nk_input_unicode(ctx, glfw->text[i]); #ifdef NK_GLFW_GL3_MOUSE_GRABBING /* optional grabbing behavior */ if (ctx->input.mouse.grab) - glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + glfwSetInputMode(glfw->win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); else if (ctx->input.mouse.ungrab) - glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + glfwSetInputMode(glfw->win, GLFW_CURSOR, GLFW_CURSOR_NORMAL); #endif nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS); @@ -465,7 +474,7 @@ nk_glfw3_new_frame(void) nk_input_motion(ctx, (int)x, (int)y); #ifdef NK_GLFW_GL3_MOUSE_GRABBING if (ctx->input.mouse.grabbed) { - glfwSetCursorPos(glfw.win, ctx->input.mouse.prev.x, ctx->input.mouse.prev.y); + glfwSetCursorPos(glfw->win, ctx->input.mouse.prev.x, ctx->input.mouse.prev.y); ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; } @@ -473,20 +482,20 @@ nk_glfw3_new_frame(void) nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS); nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS); nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS); - nk_input_button(ctx, NK_BUTTON_DOUBLE, (int)glfw.double_click_pos.x, (int)glfw.double_click_pos.y, glfw.is_double_click_down); - nk_input_scroll(ctx, glfw.scroll); - nk_input_end(&glfw.ctx); - glfw.text_len = 0; - glfw.scroll = nk_vec2(0,0); + nk_input_button(ctx, NK_BUTTON_DOUBLE, (int)glfw->double_click_pos.x, (int)glfw->double_click_pos.y, glfw->is_double_click_down); + nk_input_scroll(ctx, glfw->scroll); + nk_input_end(&glfw->ctx); + glfw->text_len = 0; + glfw->scroll = nk_vec2(0,0); } NK_API -void nk_glfw3_shutdown(void) +void nk_glfw3_shutdown(struct nk_glfw* glfw) { - nk_font_atlas_clear(&glfw.atlas); - nk_free(&glfw.ctx); - nk_glfw3_device_destroy(); - memset(&glfw, 0, sizeof(glfw)); + nk_font_atlas_clear(&glfw->atlas); + nk_free(&glfw->ctx); + nk_glfw3_device_destroy(glfw); + memset(glfw, 0, sizeof(struct nk_glfw)); } #endif