1 /*
2 * Nuklear - 1.32.0 - public domain
3 * no warrenty implied; use at your own risk.
4 * authored from 2015-2016 by Micha Mettke
5 */
6 /*
7 * ==============================================================
8 *
9 * API
10 *
11 * ===============================================================
12 */
13 #ifndef NK_GLFW_GL3_H_
14 #define NK_GLFW_GL3_H_
15
16 #include <GLFW/glfw3.h>
17
18 enum nk_glfw_init_state{
19 NK_GLFW3_DEFAULT=0,
20 NK_GLFW3_INSTALL_CALLBACKS
21 };
22
23 NK_API struct nk_context* nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state);
24 NK_API void nk_glfw3_shutdown(void);
25 NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas);
26 NK_API void nk_glfw3_font_stash_end(void);
27 NK_API void nk_glfw3_new_frame(void);
28 NK_API void nk_glfw3_render(enum nk_anti_aliasing, int max_vertex_buffer, int max_element_buffer);
29
30 NK_API void nk_glfw3_device_destroy(void);
31 NK_API void nk_glfw3_device_create(void);
32
33 NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
34 NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff);
35 NK_API void nk_glfw3_mouse_button_callback(GLFWwindow *win, int button, int action, int mods);
36
37 #endif
38 /*
39 * ==============================================================
40 *
41 * IMPLEMENTATION
42 *
43 * ===============================================================
44 */
45 #ifdef NK_GLFW_GL3_IMPLEMENTATION
46
47 #ifndef NK_GLFW_TEXT_MAX
48 #define NK_GLFW_TEXT_MAX 256
49 #endif
50 #ifndef NK_GLFW_DOUBLE_CLICK_LO
51 #define NK_GLFW_DOUBLE_CLICK_LO 0.02
52 #endif
53 #ifndef NK_GLFW_DOUBLE_CLICK_HI
54 #define NK_GLFW_DOUBLE_CLICK_HI 0.2
55 #endif
56
57 struct nk_glfw_device {
58 struct nk_buffer cmds;
59 struct nk_draw_null_texture null;
60 GLuint vbo, vao, ebo;
61 GLuint prog;
62 GLuint vert_shdr;
63 GLuint frag_shdr;
64 GLint attrib_pos;
65 GLint attrib_uv;
66 GLint attrib_col;
67 GLint uniform_tex;
68 GLint uniform_proj;
69 GLuint font_tex;
70 };
71
72 struct nk_glfw_vertex {
73 float position[2];
74 float uv[2];
75 nk_byte col[4];
76 };
77
78 static struct nk_glfw {
79 GLFWwindow *win;
80 int width, height;
81 int display_width, display_height;
82 struct nk_glfw_device ogl;
83 struct nk_context ctx;
84 struct nk_font_atlas atlas;
85 struct nk_vec2 fb_scale;
86 unsigned int text[NK_GLFW_TEXT_MAX];
87 int text_len;
88 struct nk_vec2 scroll;
89 double last_button_click;
90 int is_double_click_down;
91 struct nk_vec2 double_click_pos;
92 } glfw;
93
94 #ifdef __APPLE__
95 #define NK_SHADER_VERSION "#version 150\n"
96 #else
97 #define NK_SHADER_VERSION "#version 300 es\n"
98 #endif
99
100 NK_API void
nk_glfw3_device_create(void)101 nk_glfw3_device_create(void)
102 {
103 GLint status;
104 static const GLchar *vertex_shader =
105 NK_SHADER_VERSION
106 "uniform mat4 ProjMtx;\n"
107 "in vec2 Position;\n"
108 "in vec2 TexCoord;\n"
109 "in vec4 Color;\n"
110 "out vec2 Frag_UV;\n"
111 "out vec4 Frag_Color;\n"
112 "void main() {\n"
113 " Frag_UV = TexCoord;\n"
114 " Frag_Color = Color;\n"
115 " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n"
116 "}\n";
117 static const GLchar *fragment_shader =
118 NK_SHADER_VERSION
119 "precision mediump float;\n"
120 "uniform sampler2D Texture;\n"
121 "in vec2 Frag_UV;\n"
122 "in vec4 Frag_Color;\n"
123 "out vec4 Out_Color;\n"
124 "void main(){\n"
125 " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
126 "}\n";
127
128 struct nk_glfw_device *dev = &glfw.ogl;
129 nk_buffer_init_default(&dev->cmds);
130 dev->prog = glCreateProgram();
131 dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER);
132 dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER);
133 glShaderSource(dev->vert_shdr, 1, &vertex_shader, 0);
134 glShaderSource(dev->frag_shdr, 1, &fragment_shader, 0);
135 glCompileShader(dev->vert_shdr);
136 glCompileShader(dev->frag_shdr);
137 glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status);
138 assert(status == GL_TRUE);
139 glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status);
140 assert(status == GL_TRUE);
141 glAttachShader(dev->prog, dev->vert_shdr);
142 glAttachShader(dev->prog, dev->frag_shdr);
143 glLinkProgram(dev->prog);
144 glGetProgramiv(dev->prog, GL_LINK_STATUS, &status);
145 assert(status == GL_TRUE);
146
147 dev->uniform_tex = glGetUniformLocation(dev->prog, "Texture");
148 dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx");
149 dev->attrib_pos = glGetAttribLocation(dev->prog, "Position");
150 dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord");
151 dev->attrib_col = glGetAttribLocation(dev->prog, "Color");
152
153 {
154 /* buffer setup */
155 GLsizei vs = sizeof(struct nk_glfw_vertex);
156 size_t vp = offsetof(struct nk_glfw_vertex, position);
157 size_t vt = offsetof(struct nk_glfw_vertex, uv);
158 size_t vc = offsetof(struct nk_glfw_vertex, col);
159
160 glGenBuffers(1, &dev->vbo);
161 glGenBuffers(1, &dev->ebo);
162 glGenVertexArrays(1, &dev->vao);
163
164 glBindVertexArray(dev->vao);
165 glBindBuffer(GL_ARRAY_BUFFER, dev->vbo);
166 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo);
167
168 glEnableVertexAttribArray((GLuint)dev->attrib_pos);
169 glEnableVertexAttribArray((GLuint)dev->attrib_uv);
170 glEnableVertexAttribArray((GLuint)dev->attrib_col);
171
172 glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp);
173 glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt);
174 glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc);
175 }
176
177 glBindTexture(GL_TEXTURE_2D, 0);
178 glBindBuffer(GL_ARRAY_BUFFER, 0);
179 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
180 glBindVertexArray(0);
181 }
182
183 NK_INTERN void
nk_glfw3_device_upload_atlas(const void * image,int width,int height)184 nk_glfw3_device_upload_atlas(const void *image, int width, int height)
185 {
186 struct nk_glfw_device *dev = &glfw.ogl;
187 glGenTextures(1, &dev->font_tex);
188 glBindTexture(GL_TEXTURE_2D, dev->font_tex);
189 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
190 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
191 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0,
192 GL_RGBA, GL_UNSIGNED_BYTE, image);
193 }
194
195 NK_API void
nk_glfw3_device_destroy(void)196 nk_glfw3_device_destroy(void)
197 {
198 struct nk_glfw_device *dev = &glfw.ogl;
199 glDetachShader(dev->prog, dev->vert_shdr);
200 glDetachShader(dev->prog, dev->frag_shdr);
201 glDeleteShader(dev->vert_shdr);
202 glDeleteShader(dev->frag_shdr);
203 glDeleteProgram(dev->prog);
204 glDeleteTextures(1, &dev->font_tex);
205 glDeleteBuffers(1, &dev->vbo);
206 glDeleteBuffers(1, &dev->ebo);
207 nk_buffer_free(&dev->cmds);
208 }
209
210 NK_API void
nk_glfw3_render(enum nk_anti_aliasing AA,int max_vertex_buffer,int max_element_buffer)211 nk_glfw3_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer)
212 {
213 struct nk_glfw_device *dev = &glfw.ogl;
214 struct nk_buffer vbuf, ebuf;
215 GLfloat ortho[4][4] = {
216 {2.0f, 0.0f, 0.0f, 0.0f},
217 {0.0f,-2.0f, 0.0f, 0.0f},
218 {0.0f, 0.0f,-1.0f, 0.0f},
219 {-1.0f,1.0f, 0.0f, 1.0f},
220 };
221 ortho[0][0] /= (GLfloat)glfw.width;
222 ortho[1][1] /= (GLfloat)glfw.height;
223
224 /* setup global state */
225 glEnable(GL_BLEND);
226 glBlendEquation(GL_FUNC_ADD);
227 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
228 glDisable(GL_CULL_FACE);
229 glDisable(GL_DEPTH_TEST);
230 glEnable(GL_SCISSOR_TEST);
231 glActiveTexture(GL_TEXTURE0);
232
233 /* setup program */
234 glUseProgram(dev->prog);
235 glUniform1i(dev->uniform_tex, 0);
236 glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]);
237 glViewport(0,0,(GLsizei)glfw.display_width,(GLsizei)glfw.display_height);
238 {
239 /* convert from command queue into draw list and draw to screen */
240 const struct nk_draw_command *cmd;
241 void *vertices, *elements;
242 const nk_draw_index *offset = NULL;
243
244 /* allocate vertex and element buffer */
245 glBindVertexArray(dev->vao);
246 glBindBuffer(GL_ARRAY_BUFFER, dev->vbo);
247 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo);
248
249 glBufferData(GL_ARRAY_BUFFER, max_vertex_buffer, NULL, GL_STREAM_DRAW);
250 glBufferData(GL_ELEMENT_ARRAY_BUFFER, max_element_buffer, NULL, GL_STREAM_DRAW);
251
252 /* load draw vertices & elements directly into vertex + element buffer */
253 vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
254 elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
255 {
256 /* fill convert configuration */
257 struct nk_convert_config config;
258 static const struct nk_draw_vertex_layout_element vertex_layout[] = {
259 {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)},
260 {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)},
261 {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)},
262 {NK_VERTEX_LAYOUT_END}
263 };
264 NK_MEMSET(&config, 0, sizeof(config));
265 config.vertex_layout = vertex_layout;
266 config.vertex_size = sizeof(struct nk_glfw_vertex);
267 config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex);
268 config.null = dev->null;
269 config.circle_segment_count = 22;
270 config.curve_segment_count = 22;
271 config.arc_segment_count = 22;
272 config.global_alpha = 1.0f;
273 config.shape_AA = AA;
274 config.line_AA = AA;
275
276 /* setup buffers to load vertices and elements */
277 nk_buffer_init_fixed(&vbuf, vertices, (size_t)max_vertex_buffer);
278 nk_buffer_init_fixed(&ebuf, elements, (size_t)max_element_buffer);
279 nk_convert(&glfw.ctx, &dev->cmds, &vbuf, &ebuf, &config);
280 }
281 glUnmapBuffer(GL_ARRAY_BUFFER);
282 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
283
284 /* iterate over and execute each draw command */
285 nk_draw_foreach(cmd, &glfw.ctx, &dev->cmds)
286 {
287 if (!cmd->elem_count) continue;
288 glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
289 glScissor(
290 (GLint)(cmd->clip_rect.x * glfw.fb_scale.x),
291 (GLint)((glfw.height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * glfw.fb_scale.y),
292 (GLint)(cmd->clip_rect.w * glfw.fb_scale.x),
293 (GLint)(cmd->clip_rect.h * glfw.fb_scale.y));
294 glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
295 offset += cmd->elem_count;
296 }
297 nk_clear(&glfw.ctx);
298 }
299
300 /* default OpenGL state */
301 glUseProgram(0);
302 glBindBuffer(GL_ARRAY_BUFFER, 0);
303 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
304 glBindVertexArray(0);
305 glDisable(GL_BLEND);
306 glDisable(GL_SCISSOR_TEST);
307 }
308
309 NK_API void
nk_glfw3_char_callback(GLFWwindow * win,unsigned int codepoint)310 nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint)
311 {
312 (void)win;
313 if (glfw.text_len < NK_GLFW_TEXT_MAX)
314 glfw.text[glfw.text_len++] = codepoint;
315 }
316
317 NK_API void
nk_gflw3_scroll_callback(GLFWwindow * win,double xoff,double yoff)318 nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff)
319 {
320 (void)win; (void)xoff;
321 glfw.scroll.x += (float)xoff;
322 glfw.scroll.y += (float)yoff;
323 }
324
325 NK_API void
nk_glfw3_mouse_button_callback(GLFWwindow * window,int button,int action,int mods)326 nk_glfw3_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
327 {
328 double x, y;
329 if (button != GLFW_MOUSE_BUTTON_LEFT) return;
330 glfwGetCursorPos(window, &x, &y);
331 if (action == GLFW_PRESS) {
332 double dt = glfwGetTime() - glfw.last_button_click;
333 if (dt > NK_GLFW_DOUBLE_CLICK_LO && dt < NK_GLFW_DOUBLE_CLICK_HI) {
334 glfw.is_double_click_down = nk_true;
335 glfw.double_click_pos = nk_vec2((float)x, (float)y);
336 }
337 glfw.last_button_click = glfwGetTime();
338 } else glfw.is_double_click_down = nk_false;
339 }
340
341 NK_INTERN void
nk_glfw3_clipbard_paste(nk_handle usr,struct nk_text_edit * edit)342 nk_glfw3_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
343 {
344 const char *text = glfwGetClipboardString(glfw.win);
345 if (text) nk_textedit_paste(edit, text, nk_strlen(text));
346 (void)usr;
347 }
348
349 NK_INTERN void
nk_glfw3_clipbard_copy(nk_handle usr,const char * text,int len)350 nk_glfw3_clipbard_copy(nk_handle usr, const char *text, int len)
351 {
352 char *str = 0;
353 (void)usr;
354 if (!len) return;
355 str = (char*)malloc((size_t)len+1);
356 if (!str) return;
357 memcpy(str, text, (size_t)len);
358 str[len] = '\0';
359 glfwSetClipboardString(glfw.win, str);
360 free(str);
361 }
362
363 NK_API struct nk_context*
nk_glfw3_init(GLFWwindow * win,enum nk_glfw_init_state init_state)364 nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state)
365 {
366 glfw.win = win;
367 if (init_state == NK_GLFW3_INSTALL_CALLBACKS) {
368 glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
369 glfwSetCharCallback(win, nk_glfw3_char_callback);
370 glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
371 }
372 nk_init_default(&glfw.ctx, 0);
373 glfw.ctx.clip.copy = nk_glfw3_clipbard_copy;
374 glfw.ctx.clip.paste = nk_glfw3_clipbard_paste;
375 glfw.ctx.clip.userdata = nk_handle_ptr(0);
376 glfw.last_button_click = 0;
377 nk_glfw3_device_create();
378
379 glfw.is_double_click_down = nk_false;
380 glfw.double_click_pos = nk_vec2(0, 0);
381
382 return &glfw.ctx;
383 }
384
385 NK_API void
nk_glfw3_font_stash_begin(struct nk_font_atlas ** atlas)386 nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas)
387 {
388 nk_font_atlas_init_default(&glfw.atlas);
389 nk_font_atlas_begin(&glfw.atlas);
390 *atlas = &glfw.atlas;
391 }
392
393 NK_API void
nk_glfw3_font_stash_end(void)394 nk_glfw3_font_stash_end(void)
395 {
396 const void *image; int w, h;
397 image = nk_font_atlas_bake(&glfw.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
398 nk_glfw3_device_upload_atlas(image, w, h);
399 nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex), &glfw.ogl.null);
400 if (glfw.atlas.default_font)
401 nk_style_set_font(&glfw.ctx, &glfw.atlas.default_font->handle);
402 }
403
404 NK_API void
nk_glfw3_new_frame(void)405 nk_glfw3_new_frame(void)
406 {
407 int i;
408 double x, y;
409 struct nk_context *ctx = &glfw.ctx;
410 struct GLFWwindow *win = glfw.win;
411
412 glfwGetWindowSize(win, &glfw.width, &glfw.height);
413 glfwGetFramebufferSize(win, &glfw.display_width, &glfw.display_height);
414 glfw.fb_scale.x = (float)glfw.display_width/(float)glfw.width;
415 glfw.fb_scale.y = (float)glfw.display_height/(float)glfw.height;
416
417 nk_input_begin(ctx);
418 for (i = 0; i < glfw.text_len; ++i)
419 nk_input_unicode(ctx, glfw.text[i]);
420
421 #ifdef NK_GLFW_GL3_MOUSE_GRABBING
422 /* optional grabbing behavior */
423 if (ctx->input.mouse.grab)
424 glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
425 else if (ctx->input.mouse.ungrab)
426 glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
427 #endif
428
429 nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS);
430 nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS);
431 nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS);
432 nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS);
433 nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS);
434 nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS);
435 nk_input_key(ctx, NK_KEY_TEXT_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
436 nk_input_key(ctx, NK_KEY_TEXT_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
437 nk_input_key(ctx, NK_KEY_SCROLL_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
438 nk_input_key(ctx, NK_KEY_SCROLL_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
439 nk_input_key(ctx, NK_KEY_SCROLL_DOWN, glfwGetKey(win, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS);
440 nk_input_key(ctx, NK_KEY_SCROLL_UP, glfwGetKey(win, GLFW_KEY_PAGE_UP) == GLFW_PRESS);
441 nk_input_key(ctx, NK_KEY_SHIFT, glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS||
442 glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS);
443
444 if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
445 glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) {
446 nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
447 nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_V) == GLFW_PRESS);
448 nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
449 nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS);
450 nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS);
451 nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
452 nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
453 nk_input_key(ctx, NK_KEY_TEXT_LINE_START, glfwGetKey(win, GLFW_KEY_B) == GLFW_PRESS);
454 nk_input_key(ctx, NK_KEY_TEXT_LINE_END, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS);
455 } else {
456 nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
457 nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
458 nk_input_key(ctx, NK_KEY_COPY, 0);
459 nk_input_key(ctx, NK_KEY_PASTE, 0);
460 nk_input_key(ctx, NK_KEY_CUT, 0);
461 nk_input_key(ctx, NK_KEY_SHIFT, 0);
462 }
463
464 glfwGetCursorPos(win, &x, &y);
465 nk_input_motion(ctx, (int)x, (int)y);
466 #ifdef NK_GLFW_GL3_MOUSE_GRABBING
467 if (ctx->input.mouse.grabbed) {
468 glfwSetCursorPos(glfw.win, ctx->input.mouse.prev.x, ctx->input.mouse.prev.y);
469 ctx->input.mouse.pos.x = ctx->input.mouse.prev.x;
470 ctx->input.mouse.pos.y = ctx->input.mouse.prev.y;
471 }
472 #endif
473 nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
474 nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS);
475 nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS);
476 nk_input_button(ctx, NK_BUTTON_DOUBLE, (int)glfw.double_click_pos.x, (int)glfw.double_click_pos.y, glfw.is_double_click_down);
477 nk_input_scroll(ctx, glfw.scroll);
478 nk_input_end(&glfw.ctx);
479 glfw.text_len = 0;
480 glfw.scroll = nk_vec2(0,0);
481 }
482
483 NK_API
nk_glfw3_shutdown(void)484 void nk_glfw3_shutdown(void)
485 {
486 nk_font_atlas_clear(&glfw.atlas);
487 nk_free(&glfw.ctx);
488 nk_glfw3_device_destroy();
489 memset(&glfw, 0, sizeof(glfw));
490 }
491
492 #endif
493