twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

nuklear_glfw_gl2.h (14077B)


      1 /*
      2  * Nuklear - v1.32.0 - public domain
      3  * no warrenty implied; use at your own risk.
      4  * authored from 2015-2017 by Micha Mettke
      5  */
      6 /*
      7  * ==============================================================
      8  *
      9  *                              API
     10  *
     11  * ===============================================================
     12  */
     13 #ifndef NK_GLFW_GL2_H_
     14 #define NK_GLFW_GL2_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 NK_API struct nk_context*   nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state);
     23 NK_API void                 nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas);
     24 NK_API void                 nk_glfw3_font_stash_end(void);
     25 
     26 NK_API void                 nk_glfw3_new_frame(void);
     27 NK_API void                 nk_glfw3_render(enum nk_anti_aliasing);
     28 NK_API void                 nk_glfw3_shutdown(void);
     29 
     30 NK_API void                 nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
     31 NK_API void                 nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff);
     32 
     33 #endif
     34 
     35 /*
     36  * ==============================================================
     37  *
     38  *                          IMPLEMENTATION
     39  *
     40  * ===============================================================
     41  */
     42 #ifdef NK_GLFW_GL2_IMPLEMENTATION
     43 
     44 #ifndef NK_GLFW_TEXT_MAX
     45 #define NK_GLFW_TEXT_MAX 256
     46 #endif
     47 #ifndef NK_GLFW_DOUBLE_CLICK_LO
     48 #define NK_GLFW_DOUBLE_CLICK_LO 0.02
     49 #endif
     50 #ifndef NK_GLFW_DOUBLE_CLICK_HI
     51 #define NK_GLFW_DOUBLE_CLICK_HI 0.2
     52 #endif
     53 
     54 struct nk_glfw_device {
     55     struct nk_buffer cmds;
     56     struct nk_draw_null_texture null;
     57     GLuint font_tex;
     58 };
     59 
     60 struct nk_glfw_vertex {
     61     float position[2];
     62     float uv[2];
     63     nk_byte col[4];
     64 };
     65 
     66 static struct nk_glfw {
     67     GLFWwindow *win;
     68     int width, height;
     69     int display_width, display_height;
     70     struct nk_glfw_device ogl;
     71     struct nk_context ctx;
     72     struct nk_font_atlas atlas;
     73     struct nk_vec2 fb_scale;
     74     unsigned int text[NK_GLFW_TEXT_MAX];
     75     int text_len;
     76     struct nk_vec2 scroll;
     77     double last_button_click;
     78     int is_double_click_down;
     79     struct nk_vec2 double_click_pos;
     80 } glfw;
     81 
     82 NK_INTERN void
     83 nk_glfw3_device_upload_atlas(const void *image, int width, int height)
     84 {
     85     struct nk_glfw_device *dev = &glfw.ogl;
     86     glGenTextures(1, &dev->font_tex);
     87     glBindTexture(GL_TEXTURE_2D, dev->font_tex);
     88     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     89     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     90     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0,
     91                 GL_RGBA, GL_UNSIGNED_BYTE, image);
     92 }
     93 
     94 NK_API void
     95 nk_glfw3_render(enum nk_anti_aliasing AA)
     96 {
     97     /* setup global state */
     98     struct nk_glfw_device *dev = &glfw.ogl;
     99     glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT|GL_TRANSFORM_BIT);
    100     glDisable(GL_CULL_FACE);
    101     glDisable(GL_DEPTH_TEST);
    102     glEnable(GL_SCISSOR_TEST);
    103     glEnable(GL_BLEND);
    104     glEnable(GL_TEXTURE_2D);
    105     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    106 
    107     /* setup viewport/project */
    108     glViewport(0,0,(GLsizei)glfw.display_width,(GLsizei)glfw.display_height);
    109     glMatrixMode(GL_PROJECTION);
    110     glPushMatrix();
    111     glLoadIdentity();
    112     glOrtho(0.0f, glfw.width, glfw.height, 0.0f, -1.0f, 1.0f);
    113     glMatrixMode(GL_MODELVIEW);
    114     glPushMatrix();
    115     glLoadIdentity();
    116 
    117     glEnableClientState(GL_VERTEX_ARRAY);
    118     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    119     glEnableClientState(GL_COLOR_ARRAY);
    120     {
    121         GLsizei vs = sizeof(struct nk_glfw_vertex);
    122         size_t vp = offsetof(struct nk_glfw_vertex, position);
    123         size_t vt = offsetof(struct nk_glfw_vertex, uv);
    124         size_t vc = offsetof(struct nk_glfw_vertex, col);
    125 
    126         /* convert from command queue into draw list and draw to screen */
    127         const struct nk_draw_command *cmd;
    128         const nk_draw_index *offset = NULL;
    129         struct nk_buffer vbuf, ebuf;
    130 
    131         /* fill convert configuration */
    132         struct nk_convert_config config;
    133         static const struct nk_draw_vertex_layout_element vertex_layout[] = {
    134             {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)},
    135             {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)},
    136             {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)},
    137             {NK_VERTEX_LAYOUT_END}
    138         };
    139         NK_MEMSET(&config, 0, sizeof(config));
    140         config.vertex_layout = vertex_layout;
    141         config.vertex_size = sizeof(struct nk_glfw_vertex);
    142         config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex);
    143         config.null = dev->null;
    144         config.circle_segment_count = 22;
    145         config.curve_segment_count = 22;
    146         config.arc_segment_count = 22;
    147         config.global_alpha = 1.0f;
    148         config.shape_AA = AA;
    149         config.line_AA = AA;
    150 
    151         /* convert shapes into vertexes */
    152         nk_buffer_init_default(&vbuf);
    153         nk_buffer_init_default(&ebuf);
    154         nk_convert(&glfw.ctx, &dev->cmds, &vbuf, &ebuf, &config);
    155 
    156         /* setup vertex buffer pointer */
    157         {const void *vertices = nk_buffer_memory_const(&vbuf);
    158         glVertexPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vp));
    159         glTexCoordPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vt));
    160         glColorPointer(4, GL_UNSIGNED_BYTE, vs, (const void*)((const nk_byte*)vertices + vc));}
    161 
    162         /* iterate over and execute each draw command */
    163         offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf);
    164         nk_draw_foreach(cmd, &glfw.ctx, &dev->cmds)
    165         {
    166             if (!cmd->elem_count) continue;
    167             glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
    168             glScissor(
    169                 (GLint)(cmd->clip_rect.x * glfw.fb_scale.x),
    170                 (GLint)((glfw.height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * glfw.fb_scale.y),
    171                 (GLint)(cmd->clip_rect.w * glfw.fb_scale.x),
    172                 (GLint)(cmd->clip_rect.h * glfw.fb_scale.y));
    173             glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
    174             offset += cmd->elem_count;
    175         }
    176         nk_clear(&glfw.ctx);
    177         nk_buffer_free(&vbuf);
    178         nk_buffer_free(&ebuf);
    179     }
    180 
    181     /* default OpenGL state */
    182     glDisableClientState(GL_VERTEX_ARRAY);
    183     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    184     glDisableClientState(GL_COLOR_ARRAY);
    185 
    186     glDisable(GL_CULL_FACE);
    187     glDisable(GL_DEPTH_TEST);
    188     glDisable(GL_SCISSOR_TEST);
    189     glDisable(GL_BLEND);
    190     glDisable(GL_TEXTURE_2D);
    191 
    192     glBindTexture(GL_TEXTURE_2D, 0);
    193     glMatrixMode(GL_MODELVIEW);
    194     glPopMatrix();
    195     glMatrixMode(GL_PROJECTION);
    196     glPopMatrix();
    197     glPopAttrib();
    198 }
    199 
    200 NK_API void
    201 nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint)
    202 {
    203     (void)win;
    204     if (glfw.text_len < NK_GLFW_TEXT_MAX)
    205         glfw.text[glfw.text_len++] = codepoint;
    206 }
    207 
    208 NK_API void
    209 nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff)
    210 {
    211     (void)win; (void)xoff;
    212     glfw.scroll.x += (float)xoff;
    213     glfw.scroll.y += (float)yoff;
    214 }
    215 
    216 NK_API void
    217 nk_glfw3_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
    218 {
    219     double x, y;
    220     if (button != GLFW_MOUSE_BUTTON_LEFT) return;
    221     glfwGetCursorPos(window, &x, &y);
    222     if (action == GLFW_PRESS)  {
    223         double dt = glfwGetTime() - glfw.last_button_click;
    224         if (dt > NK_GLFW_DOUBLE_CLICK_LO && dt < NK_GLFW_DOUBLE_CLICK_HI) {
    225             glfw.is_double_click_down = nk_true;
    226             glfw.double_click_pos = nk_vec2((float)x, (float)y);
    227         }
    228         glfw.last_button_click = glfwGetTime();
    229     } else glfw.is_double_click_down = nk_false;
    230 }
    231 
    232 NK_INTERN void
    233 nk_glfw3_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
    234 {
    235     const char *text = glfwGetClipboardString(glfw.win);
    236     if (text) nk_textedit_paste(edit, text, nk_strlen(text));
    237     (void)usr;
    238 }
    239 
    240 NK_INTERN void
    241 nk_glfw3_clipbard_copy(nk_handle usr, const char *text, int len)
    242 {
    243     char *str = 0;
    244     (void)usr;
    245     if (!len) return;
    246     str = (char*)malloc((size_t)len+1);
    247     if (!str) return;
    248     NK_MEMCPY(str, text, (size_t)len);
    249     str[len] = '\0';
    250     glfwSetClipboardString(glfw.win, str);
    251     free(str);
    252 }
    253 
    254 NK_API struct nk_context*
    255 nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state)
    256 {
    257     glfw.win = win;
    258     if (init_state == NK_GLFW3_INSTALL_CALLBACKS) {
    259         glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
    260         glfwSetCharCallback(win, nk_glfw3_char_callback);
    261         glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
    262     }
    263     nk_init_default(&glfw.ctx, 0);
    264     glfw.ctx.clip.copy = nk_glfw3_clipbard_copy;
    265     glfw.ctx.clip.paste = nk_glfw3_clipbard_paste;
    266     glfw.ctx.clip.userdata = nk_handle_ptr(0);
    267     nk_buffer_init_default(&glfw.ogl.cmds);
    268 
    269     glfw.is_double_click_down = nk_false;
    270     glfw.double_click_pos = nk_vec2(0, 0);
    271 
    272     return &glfw.ctx;
    273 }
    274 
    275 NK_API void
    276 nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas)
    277 {
    278     nk_font_atlas_init_default(&glfw.atlas);
    279     nk_font_atlas_begin(&glfw.atlas);
    280     *atlas = &glfw.atlas;
    281 }
    282 
    283 NK_API void
    284 nk_glfw3_font_stash_end(void)
    285 {
    286     const void *image; int w, h;
    287     image = nk_font_atlas_bake(&glfw.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
    288     nk_glfw3_device_upload_atlas(image, w, h);
    289     nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex), &glfw.ogl.null);
    290     if (glfw.atlas.default_font)
    291         nk_style_set_font(&glfw.ctx, &glfw.atlas.default_font->handle);
    292 }
    293 
    294 NK_API void
    295 nk_glfw3_new_frame(void)
    296 {
    297     int i;
    298     double x, y;
    299     struct nk_context *ctx = &glfw.ctx;
    300     struct GLFWwindow *win = glfw.win;
    301 
    302     glfwGetWindowSize(win, &glfw.width, &glfw.height);
    303     glfwGetFramebufferSize(win, &glfw.display_width, &glfw.display_height);
    304     glfw.fb_scale.x = (float)glfw.display_width/(float)glfw.width;
    305     glfw.fb_scale.y = (float)glfw.display_height/(float)glfw.height;
    306 
    307     nk_input_begin(ctx);
    308     for (i = 0; i < glfw.text_len; ++i)
    309         nk_input_unicode(ctx, glfw.text[i]);
    310 
    311     /* optional grabbing behavior */
    312     if (ctx->input.mouse.grab)
    313         glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
    314     else if (ctx->input.mouse.ungrab)
    315         glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
    316 
    317     nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS);
    318     nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS);
    319     nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS);
    320     nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS);
    321     nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS);
    322     nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS);
    323     nk_input_key(ctx, NK_KEY_TEXT_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
    324     nk_input_key(ctx, NK_KEY_TEXT_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
    325     nk_input_key(ctx, NK_KEY_SCROLL_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
    326     nk_input_key(ctx, NK_KEY_SCROLL_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
    327     nk_input_key(ctx, NK_KEY_SCROLL_DOWN, glfwGetKey(win, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS);
    328     nk_input_key(ctx, NK_KEY_SCROLL_UP, glfwGetKey(win, GLFW_KEY_PAGE_UP) == GLFW_PRESS);
    329     nk_input_key(ctx, NK_KEY_SHIFT, glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS||
    330                                     glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS);
    331 
    332     if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
    333         glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) {
    334         nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
    335         nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_V) == GLFW_PRESS);
    336         nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
    337         nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS);
    338         nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS);
    339         nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
    340         nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
    341         nk_input_key(ctx, NK_KEY_TEXT_LINE_START, glfwGetKey(win, GLFW_KEY_B) == GLFW_PRESS);
    342         nk_input_key(ctx, NK_KEY_TEXT_LINE_END, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS);
    343     } else {
    344         nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
    345         nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
    346         nk_input_key(ctx, NK_KEY_COPY, 0);
    347         nk_input_key(ctx, NK_KEY_PASTE, 0);
    348         nk_input_key(ctx, NK_KEY_CUT, 0);
    349         nk_input_key(ctx, NK_KEY_SHIFT, 0);
    350     }
    351 
    352     glfwGetCursorPos(win, &x, &y);
    353     nk_input_motion(ctx, (int)x, (int)y);
    354     if (ctx->input.mouse.grabbed) {
    355         glfwSetCursorPos(glfw.win, (double)ctx->input.mouse.prev.x, (double)ctx->input.mouse.prev.y);
    356         ctx->input.mouse.pos.x = ctx->input.mouse.prev.x;
    357         ctx->input.mouse.pos.y = ctx->input.mouse.prev.y;
    358     }
    359 
    360     nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
    361     nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS);
    362     nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS);
    363     nk_input_button(ctx, NK_BUTTON_DOUBLE, (int)glfw.double_click_pos.x, (int)glfw.double_click_pos.y, glfw.is_double_click_down);
    364     nk_input_scroll(ctx, glfw.scroll);
    365     nk_input_end(&glfw.ctx);
    366     glfw.text_len = 0;
    367     glfw.scroll = nk_vec2(0,0);
    368 }
    369 
    370 NK_API
    371 void nk_glfw3_shutdown(void)
    372 {
    373     struct nk_glfw_device *dev = &glfw.ogl;
    374     nk_font_atlas_clear(&glfw.atlas);
    375     nk_free(&glfw.ctx);
    376     glDeleteTextures(1, &dev->font_tex);
    377     nk_buffer_free(&dev->cmds);
    378     NK_MEMSET(&glfw, 0, sizeof(glfw));
    379 }
    380 
    381 #endif