Просмотр исходного кода

Added additional SDL/GLFW OpenGL 2.2 demo

vurtun 9 лет назад
Родитель
Сommit
389176ef4b

+ 25 - 0
demo/glfw_opengl2/Makefile

@@ -0,0 +1,25 @@
+# Install
+BIN = demo
+
+# Flags
+CFLAGS = -std=c99 -pedantic -O2
+
+SRC = main.c
+OBJ = $(SRC:.c=.o)
+
+ifeq ($(OS),Windows_NT)
+BIN := $(BIN).exe
+LIBS = -lglfw3 -lopengl32 -lm -lGLU32
+else
+	UNAME_S := $(shell uname -s)
+	ifeq ($(UNAME_S),Darwin)
+		LIBS = -lglfw3 -framework OpenGL -lm
+	else
+    LIBS = -lglfw -lGL -lm -lGLU
+	endif
+endif
+
+$(BIN):
+	@mkdir -p bin
+	rm -f bin/$(BIN) $(OBJS)
+	$(CC) $(SRC) $(CFLAGS) -o bin/$(BIN) $(LIBS)

+ 163 - 0
demo/glfw_opengl2/main.c

@@ -0,0 +1,163 @@
+/* nuklear - v1.00 - public domain */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+#include <math.h>
+
+#include <GLFW/glfw3.h>
+
+/* these defines are both needed for the header
+ * and source file. So if you split them remember
+ * to copy them as well. */
+#define NK_INCLUDE_FIXED_TYPES
+#define NK_INCLUDE_STANDARD_IO
+#define NK_INCLUDE_DEFAULT_ALLOCATOR
+#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+#define NK_INCLUDE_FONT_BAKING
+#define NK_INCLUDE_DEFAULT_FONT
+#include "nuklear_glfw.h"
+#include "nuklear_glfw.c"
+
+#define WINDOW_WIDTH 1200
+#define WINDOW_HEIGHT 800
+
+#define MAX_VERTEX_BUFFER 512 * 1024
+#define MAX_ELEMENT_BUFFER 128 * 1024
+
+#define UNUSED(a) (void)a
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) < (b) ? (b) : (a))
+#define LEN(a) (sizeof(a)/sizeof(a)[0])
+
+/* ===============================================================
+ *
+ *                          EXAMPLE
+ *
+ * ===============================================================*/
+/* This are some code examples to provide a small overview of what can be
+ * done with this library. To try out an example uncomment the include
+ * and the corresponding function. */
+/*#include "../style.c"*/
+/*#include "../calculator.c"*/
+/*#include "../overview.c"*/
+/*#include "../node_editor.c"*/
+
+/* ===============================================================
+ *
+ *                          DEMO
+ *
+ * ===============================================================*/
+static void error_callback(int e, const char *d)
+{printf("Error %d: %s\n", e, d);}
+
+int main(void)
+{
+    /* Platform */
+    static GLFWwindow *win;
+    int width = 0, height = 0;
+    struct nk_context *ctx;
+    struct nk_color background;
+
+    /* GLFW */
+    glfwSetErrorCallback(error_callback);
+    if (!glfwInit()) {
+        fprintf(stdout, "[GFLW] failed to init!\n");
+        exit(1);
+    }
+    win = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Demo", NULL, NULL);
+    glfwMakeContextCurrent(win);
+    glfwGetWindowSize(win, &width, &height);
+
+    /* GUI */
+    ctx = nk_glfw3_init(win, NK_GLFW3_INSTALL_CALLBACKS);
+    /* Load Fonts: if none of these are loaded a default font will be used  */
+    {struct nk_font_atlas *atlas;
+    nk_glfw3_font_stash_begin(&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_style_set_font(ctx, &droid->handle);*/}
+
+    /* style.c */
+    /*set_style(ctx, THEME_WHITE);*/
+    /*set_style(ctx, THEME_RED);*/
+    /*set_style(ctx, THEME_BLUE);*/
+    /*set_style(ctx, THEME_DARK);*/
+
+    background = nk_rgb(28,48,62);
+    while (!glfwWindowShouldClose(win))
+    {
+        /* Input */
+        glfwPollEvents();
+        nk_glfw3_new_frame();
+
+        /* GUI */
+        {struct nk_panel layout;
+        if (nk_begin(ctx, &layout, "Demo", nk_rect(50, 50, 230, 250),
+            NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
+            NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
+        {
+            enum {EASY, HARD};
+            static int op = EASY;
+            static int property = 20;
+            nk_layout_row_static(ctx, 30, 80, 1);
+            if (nk_button_label(ctx, "button", NK_BUTTON_DEFAULT))
+                fprintf(stdout, "button pressed\n");
+
+            nk_layout_row_dynamic(ctx, 30, 2);
+            if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
+            if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;
+
+            nk_layout_row_dynamic(ctx, 25, 1);
+            nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
+
+            {struct nk_panel combo;
+            nk_layout_row_dynamic(ctx, 20, 1);
+            nk_label(ctx, "background:", NK_TEXT_LEFT);
+            nk_layout_row_dynamic(ctx, 25, 1);
+            if (nk_combo_begin_color(ctx, &combo, background, 400)) {
+                nk_layout_row_dynamic(ctx, 120, 1);
+                background = nk_color_picker(ctx, background, NK_RGBA);
+                nk_layout_row_dynamic(ctx, 25, 1);
+                background.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, background.r, 255, 1,1);
+                background.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, background.g, 255, 1,1);
+                background.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, background.b, 255, 1,1);
+                background.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, background.a, 255, 1,1);
+                nk_combo_end(ctx);
+            }}
+        }
+        nk_end(ctx);}
+
+        /* -------------- EXAMPLES ---------------- */
+        /*calculator(ctx);*/
+        /*overview(ctx);*/
+        /*node_editor(ctx);*/
+        /* ----------------------------------------- */
+
+        /* Draw */
+        {float bg[4];
+        nk_color_fv(bg, background);
+        glfwGetWindowSize(win, &width, &height);
+        glViewport(0, 0, width, height);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glClearColor(bg[0], bg[1], bg[2], bg[3]);
+        /* IMPORTANT: `nk_sdl_render` modifies some global OpenGL state
+         * with blending, scissor, face culling and depth test and defaults everything
+         * back into a default state. Make sure to either save and restore or
+         * reset your own state after drawing rendering the UI. */
+        nk_glfw3_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_BUFFER, MAX_ELEMENT_BUFFER);
+        glfwSwapBuffers(win);}
+    }
+    nk_glfw3_shutdown();
+    glfwTerminate();
+    return 0;
+}
+

+ 287 - 0
demo/glfw_opengl2/nuklear_glfw.c

@@ -0,0 +1,287 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+#include <math.h>
+#include <time.h>
+#include <limits.h>
+
+#define NK_IMPLEMENTATION
+#include "nuklear_glfw.h"
+#include "../../nuklear.h"
+
+#define NK_GLFW_TEXT_MAX 256
+struct nk_glfw_device {
+    struct nk_buffer cmds;
+    struct nk_draw_null_texture null;
+    GLuint font_tex;
+};
+
+static struct nk_glfw {
+    GLFWwindow *win;
+    int width, height;
+    int display_width, display_height;
+    struct nk_glfw_device ogl;
+    struct nk_context ctx;
+    struct nk_font_atlas atlas;
+    struct nk_vec2 fb_scale;
+    unsigned int text[NK_GLFW_TEXT_MAX];
+    int text_len;
+    float scroll;
+} glfw;
+
+NK_INTERN void
+nk_glfw3_device_upload_atlas(const void *image, int width, int height)
+{
+    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);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0,
+                GL_RGBA, GL_UNSIGNED_BYTE, image);
+}
+
+NK_API void
+nk_glfw3_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer)
+{
+    /* setup global state */
+    struct nk_glfw_device *dev = &glfw.ogl;
+    glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT|GL_TRANSFORM_BIT);
+    glDisable(GL_CULL_FACE);
+    glDisable(GL_DEPTH_TEST);
+    glEnable(GL_SCISSOR_TEST);
+    glEnable(GL_BLEND);
+    glEnable(GL_TEXTURE_2D);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+    /* setup viewport/project */
+    glViewport(0,0,(GLsizei)glfw.display_width,(GLsizei)glfw.display_height);
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+    glOrtho(0.0f, glfw.width, glfw.height, 0.0f, -1.0f, 1.0f);
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glEnableClientState(GL_COLOR_ARRAY);
+    {
+        GLsizei vs = sizeof(struct nk_draw_vertex);
+        size_t vp = offsetof(struct nk_draw_vertex, position);
+        size_t vt = offsetof(struct nk_draw_vertex, uv);
+        size_t vc = offsetof(struct nk_draw_vertex, col);
+
+        /* convert from command queue into draw list and draw to screen */
+        const struct nk_draw_command *cmd;
+        const nk_draw_index *offset = NULL;
+        struct nk_buffer vbuf, ebuf;
+
+        /* fill converting configuration */
+        struct nk_convert_config config;
+        memset(&config, 0, sizeof(config));
+        config.global_alpha = 1.0f;
+        config.shape_AA = AA;
+        config.line_AA = AA;
+        config.circle_segment_count = 22;
+        config.curve_segment_count = 22;
+        config.arc_segment_count = 22;
+        config.null = dev->null;
+
+        /* convert shapes into vertexes */
+        nk_buffer_init_default(&vbuf);
+        nk_buffer_init_default(&ebuf);
+        nk_convert(&glfw.ctx, &dev->cmds, &vbuf, &ebuf, &config);
+
+        /* setup vertex buffer pointer */
+        {const void *vertices = nk_buffer_memory_const(&vbuf);
+        glVertexPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vp));
+        glTexCoordPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vt));
+        glColorPointer(4, GL_UNSIGNED_BYTE, vs, (const void*)((const nk_byte*)vertices + vc));}
+
+        /* iterate over and execute each draw command */
+        offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf);
+        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.display_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_buffer_free(&vbuf);
+        nk_buffer_free(&ebuf);
+    }
+
+    /* default OpenGL state */
+    glDisableClientState(GL_VERTEX_ARRAY);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDisableClientState(GL_COLOR_ARRAY);
+
+    glDisable(GL_CULL_FACE);
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_SCISSOR_TEST);
+    glDisable(GL_BLEND);
+    glDisable(GL_TEXTURE_2D);
+
+    glBindTexture(GL_TEXTURE_2D, 0);
+    glMatrixMode(GL_MODELVIEW);
+    glPopMatrix();
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glPopAttrib();
+}
+
+NK_API void
+nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint)
+{
+    (void)win;
+    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)
+{
+    (void)win; (void)xoff;
+    glfw.scroll += (float)yoff;
+}
+
+static void
+nk_glfw3_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
+{
+    const char *text = glfwGetClipboardString(glfw.win);
+    if (text) nk_textedit_paste(edit, text, nk_strlen(text));
+    (void)usr;
+}
+
+static void
+nk_glfw3_clipbard_copy(nk_handle usr, const char *text, int len)
+{
+    char *str = 0;
+    (void)usr;
+    if (!len) return;
+    str = malloc((size_t)len+1);
+    if (!str) return;
+    memcpy(str, text, (size_t)len);
+    str[len] = '\0';
+    glfwSetClipboardString(glfw.win, str);
+    free(str);
+}
+
+NK_API struct nk_context*
+nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state)
+{
+    glfw.win = win;
+    if (init_state == NK_GLFW3_INSTALL_CALLBACKS) {
+        glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
+        glfwSetCharCallback(win, nk_glfw3_char_callback);
+    }
+
+    nk_init_default(&glfw.ctx, 0);
+    glfw.ctx.clip.copy = nk_glfw3_clipbard_copy;
+    glfw.ctx.clip.paste = nk_glfw3_clipbard_paste;
+    glfw.ctx.clip.userdata = nk_handle_ptr(0);
+    nk_buffer_init_default(&glfw.ogl.cmds);
+    return &glfw.ctx;
+}
+
+NK_API void
+nk_glfw3_font_stash_begin(struct nk_font_atlas **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)
+{
+    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);
+}
+
+NK_API void
+nk_glfw3_new_frame(void)
+{
+    int i;
+    double x, y;
+    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;
+
+    nk_input_begin(ctx);
+    for (i = 0; i < glfw.text_len; ++i)
+        nk_input_unicode(ctx, glfw.text[i]);
+
+    nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS);
+    nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS);
+    nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS);
+    nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS);
+    nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS);
+    nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS);
+    nk_input_key(ctx, NK_KEY_TEXT_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
+    nk_input_key(ctx, NK_KEY_TEXT_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
+    nk_input_key(ctx, NK_KEY_SHIFT, glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS||
+                                    glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS);
+
+    if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
+        glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL)) {
+        nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
+        nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_P) == GLFW_PRESS);
+        nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
+        nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS);
+        nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS);
+        nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
+        nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
+        nk_input_key(ctx, NK_KEY_TEXT_LINE_START, glfwGetKey(win, GLFW_KEY_B) == GLFW_PRESS);
+        nk_input_key(ctx, NK_KEY_TEXT_LINE_END, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS);
+    } else {
+        nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
+        nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
+        nk_input_key(ctx, NK_KEY_COPY, 0);
+        nk_input_key(ctx, NK_KEY_PASTE, 0);
+        nk_input_key(ctx, NK_KEY_CUT, 0);
+        nk_input_key(ctx, NK_KEY_SHIFT, 0);
+    }
+
+    glfwGetCursorPos(win, &x, &y);
+    nk_input_motion(ctx, (int)x, (int)y);
+    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_scroll(ctx, glfw.scroll);
+    nk_input_end(&glfw.ctx);
+    glfw.text_len = 0;
+    glfw.scroll = 0;
+}
+
+NK_API
+void nk_glfw3_shutdown(void)
+{
+    struct nk_glfw_device *dev = &glfw.ogl;
+    nk_font_atlas_clear(&glfw.atlas);
+    nk_free(&glfw.ctx);
+    glDeleteTextures(1, &dev->font_tex);
+    nk_buffer_free(&dev->cmds);
+    memset(&glfw, 0, sizeof(glfw));
+}
+

+ 20 - 0
demo/glfw_opengl2/nuklear_glfw.h

@@ -0,0 +1,20 @@
+#ifndef NK_GLFW_H_
+#define NK_GLFW_H_
+
+#include "../../nuklear.h"
+
+#include <GLFW/glfw3.h>
+
+enum nk_glfw_init_state{NK_GLFW3_DEFAULT=0, NK_GLFW3_INSTALL_CALLBACKS};
+NK_API struct nk_context *nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state);
+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);
+NK_API void nk_glfw3_shutdown(void);
+
+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);
+
+#endif

+ 4 - 3
demo/glfw_opengl3/main.c

@@ -164,9 +164,10 @@ int main(void)
         glClear(GL_COLOR_BUFFER_BIT);
         glClearColor(bg[0], bg[1], bg[2], bg[3]);
         /* IMPORTANT: `nk_sdl_render` modifies some global OpenGL state
-         * with blending, scissor, face culling and depth test and defaults everything
-         * back into a default state. Make sure to either save and restore or
-         * reset your own state after drawing rendering the UI. */
+         * with blending, scissor, face culling, depth test and viewport and
+         * 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);
         glfwSwapBuffers(win);}
     }

+ 2 - 1
demo/glfw_opengl3/nuklear_glfw.c

@@ -230,7 +230,7 @@ nk_glfw3_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element
             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)((glfw.display_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);
@@ -386,5 +386,6 @@ void nk_glfw3_shutdown(void)
     nk_font_atlas_clear(&glfw.atlas);
     nk_free(&glfw.ctx);
     nk_glfw3_device_destroy();
+    memset(&glfw, 0, sizeof(glfw));
 }
 

+ 25 - 0
demo/sdl_opengl2/Makefile

@@ -0,0 +1,25 @@
+# Install
+BIN = demo
+
+# Flags
+CFLAGS = -std=c99 -pedantic -O2
+
+SRC = main.c
+OBJ = $(SRC:.c=.o)
+
+ifeq ($(OS),Windows_NT)
+BIN := $(BIN).exe
+LIBS = -lmingw32 -lSDL2main -lSDL2 -lopengl32 -lm -lGLU32
+else
+	UNAME_S := $(shell uname -s)
+	ifeq ($(UNAME_S),Darwin)
+		LIBS = -lSDL2 -framework OpenGL -lm
+	else
+		LIBS = -lSDL2 -lGL -lm -lGLU
+	endif
+endif
+
+$(BIN):
+	@mkdir -p bin
+	rm -f bin/$(BIN) $(OBJS)
+	$(CC) $(SRC) $(CFLAGS) -o bin/$(BIN) $(LIBS)

+ 173 - 0
demo/sdl_opengl2/main.c

@@ -0,0 +1,173 @@
+/* nuklear - v1.00 - public domain */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+#include <math.h>
+
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_opengl.h>
+
+/* these defines are both needed for the header
+ * and source file. So if you split them remember
+ * to copy them as well. */
+#define NK_INCLUDE_FIXED_TYPES
+#define NK_INCLUDE_STANDARD_IO
+#define NK_INCLUDE_DEFAULT_ALLOCATOR
+#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+#define NK_INCLUDE_FONT_BAKING
+#define NK_INCLUDE_DEFAULT_FONT
+#include "nuklear_sdl.h"
+#include "nuklear_sdl.c"
+
+#define WINDOW_WIDTH 800
+#define WINDOW_HEIGHT 600
+
+#define MAX_VERTEX_MEMORY 512 * 1024
+#define MAX_ELEMENT_MEMORY 128 * 1024
+
+/* ===============================================================
+ *
+ *                          EXAMPLE
+ *
+ * ===============================================================*/
+/* This are some code examples to provide a small overview of what can be
+ * done with this library. To try out an example uncomment the include
+ * and the corresponding function. */
+/*#include "../style.c"*/
+/*#include "../calculator.c"*/
+/*#include "../overview.c"*/
+/*#include "../node_editor.c"*/
+
+/* ===============================================================
+ *
+ *                          DEMO
+ *
+ * ===============================================================*/
+int
+main(int argc, char* argv[])
+{
+    /* Platform */
+    SDL_Window *win;
+    SDL_GLContext glContext;
+    struct nk_color background;
+    int win_width, win_height;
+    int running = 1;
+
+    /* GUI */
+    struct nk_context *ctx;
+
+    /* SDL setup */
+    SDL_Init(SDL_INIT_VIDEO);
+    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
+    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
+    win = SDL_CreateWindow("Demo",
+        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
+        WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN);
+    glContext = SDL_GL_CreateContext(win);
+    SDL_GetWindowSize(win, &win_width, &win_height);
+
+    /* GUI */
+    ctx = nk_sdl_init(win);
+    /* Load Fonts: if none of these are loaded a default font will be used  */
+    {struct nk_font_atlas *atlas;
+    nk_sdl_font_stash_begin(&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", 16, 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_sdl_font_stash_end();
+    /*nk_style_set_font(ctx, &roboto->handle)*/;}
+
+    /* style.c */
+    /*set_style(ctx, THEME_WHITE);*/
+    /*set_style(ctx, THEME_RED);*/
+    /*set_style(ctx, THEME_BLUE);*/
+    /*set_style(ctx, THEME_DARK);*/
+
+    background = nk_rgb(28,48,62);
+    while (running)
+    {
+        /* Input */
+        SDL_Event evt;
+        nk_input_begin(ctx);
+        while (SDL_PollEvent(&evt)) {
+            if (evt.type == SDL_QUIT) goto cleanup;
+            nk_sdl_handle_event(&evt);
+        }
+        nk_input_end(ctx);
+
+        /* GUI */
+        {struct nk_panel layout;
+        if (nk_begin(ctx, &layout, "Demo", nk_rect(50, 50, 210, 250),
+            NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
+            NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
+        {
+            enum {EASY, HARD};
+            static int op = EASY;
+            static int property = 20;
+
+            nk_layout_row_static(ctx, 30, 80, 1);
+            if (nk_button_label(ctx, "button", NK_BUTTON_DEFAULT))
+                fprintf(stdout, "button pressed\n");
+            nk_layout_row_dynamic(ctx, 30, 2);
+            if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
+            if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;
+            nk_layout_row_dynamic(ctx, 25, 1);
+            nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
+
+            {struct nk_panel combo;
+            nk_layout_row_dynamic(ctx, 20, 1);
+            nk_label(ctx, "background:", NK_TEXT_LEFT);
+            nk_layout_row_dynamic(ctx, 25, 1);
+            if (nk_combo_begin_color(ctx, &combo, background, 400)) {
+                nk_layout_row_dynamic(ctx, 120, 1);
+                background = nk_color_picker(ctx, background, NK_RGBA);
+                nk_layout_row_dynamic(ctx, 25, 1);
+                background.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, background.r, 255, 1,1);
+                background.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, background.g, 255, 1,1);
+                background.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, background.b, 255, 1,1);
+                background.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, background.a, 255, 1,1);
+                nk_combo_end(ctx);
+            }}
+        }
+        nk_end(ctx);}
+
+        /* -------------- EXAMPLES ---------------- */
+        /*calculator(ctx);*/
+        /*overview(ctx);*/
+        /*node_editor(ctx);*/
+        /* ----------------------------------------- */
+
+        /* Draw */
+        {float bg[4];
+        nk_color_fv(bg, background);
+        SDL_GetWindowSize(win, &win_width, &win_height);
+        glViewport(0, 0, win_width, win_height);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glClearColor(bg[0], bg[1], bg[2], bg[3]);
+        /* IMPORTANT: `nk_sdl_render` modifies some global OpenGL state
+         * with blending, scissor, face culling, depth test and viewport and
+         * 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_sdl_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_MEMORY, MAX_ELEMENT_MEMORY);
+        SDL_GL_SwapWindow(win);}
+    }
+
+cleanup:
+    nk_sdl_shutdown();
+    SDL_GL_DeleteContext(glContext);
+    SDL_DestroyWindow(win);
+    SDL_Quit();
+    return 0;
+}
+

+ 269 - 0
demo/sdl_opengl2/nuklear_sdl.c

@@ -0,0 +1,269 @@
+#include <string.h>
+#include <SDL2/SDL.h>
+
+#include "nuklear_sdl.h"
+#define NK_IMPLEMENTATION
+#include "../../nuklear.h"
+
+struct nk_sdl_device {
+    struct nk_buffer cmds;
+    struct nk_draw_null_texture null;
+    GLuint font_tex;
+};
+
+static struct nk_sdl {
+    SDL_Window *win;
+    struct nk_sdl_device ogl;
+    struct nk_context ctx;
+    struct nk_font_atlas atlas;
+} sdl;
+
+NK_INTERN void
+nk_sdl_device_upload_atlas(const void *image, int width, int height)
+{
+    struct nk_sdl_device *dev = &sdl.ogl;
+    glGenTextures(1, &dev->font_tex);
+    glBindTexture(GL_TEXTURE_2D, dev->font_tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0,
+                GL_RGBA, GL_UNSIGNED_BYTE, image);
+}
+
+NK_API void
+nk_sdl_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer)
+{
+    /* setup global state */
+    struct nk_sdl_device *dev = &sdl.ogl;
+    int width, height;
+    int display_width, display_height;
+    struct nk_vec2 scale;
+
+    SDL_GetWindowSize(sdl.win, &width, &height);
+    SDL_GL_GetDrawableSize(sdl.win, &display_width, &display_height);
+    scale.x = (float)display_width/(float)width;
+    scale.y = (float)display_height/(float)height;
+
+    glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT|GL_TRANSFORM_BIT);
+    glDisable(GL_CULL_FACE);
+    glDisable(GL_DEPTH_TEST);
+    glEnable(GL_SCISSOR_TEST);
+    glEnable(GL_BLEND);
+    glEnable(GL_TEXTURE_2D);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+    /* setup viewport/project */
+    glViewport(0,0,(GLsizei)display_width,(GLsizei)display_height);
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+    glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f);
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glEnableClientState(GL_COLOR_ARRAY);
+    {
+        GLsizei vs = sizeof(struct nk_draw_vertex);
+        size_t vp = offsetof(struct nk_draw_vertex, position);
+        size_t vt = offsetof(struct nk_draw_vertex, uv);
+        size_t vc = offsetof(struct nk_draw_vertex, col);
+
+        /* convert from command queue into draw list and draw to screen */
+        const struct nk_draw_command *cmd;
+        const nk_draw_index *offset = NULL;
+        struct nk_buffer vbuf, ebuf;
+
+        /* fill converting configuration */
+        struct nk_convert_config config;
+        memset(&config, 0, sizeof(config));
+        config.global_alpha = 1.0f;
+        config.shape_AA = AA;
+        config.line_AA = AA;
+        config.circle_segment_count = 22;
+        config.curve_segment_count = 22;
+        config.arc_segment_count = 22;
+        config.null = dev->null;
+
+        /* convert shapes into vertexes */
+        nk_buffer_init_default(&vbuf);
+        nk_buffer_init_default(&ebuf);
+        nk_convert(&sdl.ctx, &dev->cmds, &vbuf, &ebuf, &config);
+
+        /* setup vertex buffer pointer */
+        {const void *vertices = nk_buffer_memory_const(&vbuf);
+        glVertexPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vp));
+        glTexCoordPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vt));
+        glColorPointer(4, GL_UNSIGNED_BYTE, vs, (const void*)((const nk_byte*)vertices + vc));}
+
+        /* iterate over and execute each draw command */
+        offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf);
+        nk_draw_foreach(cmd, &sdl.ctx, &dev->cmds)
+        {
+            if (!cmd->elem_count) continue;
+            glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
+            glScissor(
+                (GLint)(cmd->clip_rect.x * scale.x),
+                (GLint)((display_height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * scale.y),
+                (GLint)(cmd->clip_rect.w * scale.x),
+                (GLint)(cmd->clip_rect.h * scale.y));
+            glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
+            offset += cmd->elem_count;
+        }
+        nk_clear(&sdl.ctx);
+        nk_buffer_free(&vbuf);
+        nk_buffer_free(&ebuf);
+    }
+
+    /* default OpenGL state */
+    glDisableClientState(GL_VERTEX_ARRAY);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDisableClientState(GL_COLOR_ARRAY);
+
+    glDisable(GL_CULL_FACE);
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_SCISSOR_TEST);
+    glDisable(GL_BLEND);
+    glDisable(GL_TEXTURE_2D);
+
+    glBindTexture(GL_TEXTURE_2D, 0);
+    glMatrixMode(GL_MODELVIEW);
+    glPopMatrix();
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glPopAttrib();
+}
+
+static void
+nk_sdl_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
+{
+    const char *text = SDL_GetClipboardText();
+    if (text) nk_textedit_paste(edit, text, nk_strlen(text));
+    (void)usr;
+}
+
+static void
+nk_sdl_clipbard_copy(nk_handle usr, const char *text, int len)
+{
+    char *str = 0;
+    (void)usr;
+    if (!len) return;
+    str = malloc((size_t)len+1);
+    if (!str) return;
+    memcpy(str, text, (size_t)len);
+    str[len] = '\0';
+    SDL_SetClipboardText(str);
+    free(str);
+}
+
+NK_API struct nk_context*
+nk_sdl_init(SDL_Window *win)
+{
+    sdl.win = win;
+    nk_init_default(&sdl.ctx, 0);
+    sdl.ctx.clip.copy = nk_sdl_clipbard_copy;
+    sdl.ctx.clip.paste = nk_sdl_clipbard_paste;
+    sdl.ctx.clip.userdata = nk_handle_ptr(0);
+    nk_buffer_init_default(&sdl.ogl.cmds);
+    return &sdl.ctx;
+}
+
+NK_API void
+nk_sdl_font_stash_begin(struct nk_font_atlas **atlas)
+{
+    nk_font_atlas_init_default(&sdl.atlas);
+    nk_font_atlas_begin(&sdl.atlas);
+    *atlas = &sdl.atlas;
+}
+
+NK_API void
+nk_sdl_font_stash_end(void)
+{
+    const void *image; int w, h;
+    image = nk_font_atlas_bake(&sdl.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
+    nk_sdl_device_upload_atlas(image, w, h);
+    nk_font_atlas_end(&sdl.atlas, nk_handle_id((int)sdl.ogl.font_tex), &sdl.ogl.null);
+    if (sdl.atlas.default_font)
+        nk_style_set_font(&sdl.ctx, &sdl.atlas.default_font->handle);
+}
+
+NK_API void
+nk_sdl_handle_event(SDL_Event *evt)
+{
+    struct nk_context *ctx = &sdl.ctx;
+    if (evt->type == SDL_KEYUP || evt->type == SDL_KEYDOWN) {
+        /* key events */
+        int down = evt->type == SDL_KEYDOWN;
+        const Uint8* state = SDL_GetKeyboardState(0);
+        SDL_Keycode sym = evt->key.keysym.sym;
+        if (sym == SDLK_RSHIFT || sym == SDLK_LSHIFT)
+            nk_input_key(ctx, NK_KEY_SHIFT, down);
+        else if (sym == SDLK_DELETE)
+            nk_input_key(ctx, NK_KEY_DEL, down);
+        else if (sym == SDLK_RETURN)
+            nk_input_key(ctx, NK_KEY_ENTER, down);
+        else if (sym == SDLK_TAB)
+            nk_input_key(ctx, NK_KEY_TAB, down);
+        else if (sym == SDLK_BACKSPACE)
+            nk_input_key(ctx, NK_KEY_BACKSPACE, down);
+        else if (sym == SDLK_HOME)
+            nk_input_key(ctx, NK_KEY_TEXT_START, down);
+        else if (sym == SDLK_END)
+            nk_input_key(ctx, NK_KEY_TEXT_END, down);
+        else if (sym == SDLK_z)
+            nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && state[SDL_SCANCODE_LCTRL]);
+        else if (sym == SDLK_r)
+            nk_input_key(ctx, NK_KEY_TEXT_REDO, down && state[SDL_SCANCODE_LCTRL]);
+        else if (sym == SDLK_c)
+            nk_input_key(ctx, NK_KEY_COPY, down && state[SDL_SCANCODE_LCTRL]);
+        else if (sym == SDLK_v)
+            nk_input_key(ctx, NK_KEY_PASTE, down && state[SDL_SCANCODE_LCTRL]);
+        else if (sym == SDLK_x)
+            nk_input_key(ctx, NK_KEY_CUT, down && state[SDL_SCANCODE_LCTRL]);
+        else if (sym == SDLK_b)
+            nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && state[SDL_SCANCODE_LCTRL]);
+        else if (sym == SDLK_e)
+            nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && state[SDL_SCANCODE_LCTRL]);
+        else if (sym == SDLK_LEFT) {
+            if (state[SDL_SCANCODE_LCTRL])
+                nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down);
+            else nk_input_key(ctx, NK_KEY_LEFT, down);
+        } else if (sym == SDLK_RIGHT) {
+            if (state[SDL_SCANCODE_LCTRL])
+                nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down);
+            else nk_input_key(ctx, NK_KEY_RIGHT, down);
+        }
+    } else if (evt->type == SDL_MOUSEBUTTONDOWN || evt->type == SDL_MOUSEBUTTONUP) {
+        /* mouse button */
+        int down = evt->type == SDL_MOUSEBUTTONDOWN;
+        const int x = evt->button.x, y = evt->button.y;
+        if (evt->button.button == SDL_BUTTON_LEFT)
+            nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down);
+        if (evt->button.button == SDL_BUTTON_MIDDLE)
+            nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down);
+        if (evt->button.button == SDL_BUTTON_RIGHT)
+            nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down);
+    } else if (evt->type == SDL_MOUSEMOTION) {
+        nk_input_motion(ctx, evt->motion.x, evt->motion.y);
+    } else if (evt->type == SDL_TEXTINPUT) {
+        nk_glyph glyph;
+        memcpy(glyph, evt->text.text, NK_UTF_SIZE);
+        nk_input_glyph(ctx, glyph);
+    } else if (evt->type == SDL_MOUSEWHEEL) {
+        nk_input_scroll(ctx,(float)evt->wheel.y);
+    }
+}
+
+NK_API
+void nk_sdl_shutdown(void)
+{
+    struct nk_sdl_device *dev = &sdl.ogl;
+    nk_font_atlas_clear(&sdl.atlas);
+    nk_free(&sdl.ctx);
+    glDeleteTextures(1, &dev->font_tex);
+    nk_buffer_free(&dev->cmds);
+    memset(&sdl, 0, sizeof(sdl));
+}
+

+ 15 - 0
demo/sdl_opengl2/nuklear_sdl.h

@@ -0,0 +1,15 @@
+#ifndef NK_SDL_H_
+#define NK_SDL_H_
+
+#include "../../nuklear.h"
+
+#include <SDL2/SDL.h>
+
+NK_API struct nk_context *nk_sdl_init(SDL_Window *win);
+NK_API void nk_sdl_font_stash_begin(struct nk_font_atlas **atlas);
+NK_API void nk_sdl_font_stash_end(void);
+NK_API void nk_sdl_handle_event(SDL_Event *evt);
+NK_API void nk_sdl_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer);
+NK_API void nk_sdl_shutdown(void);
+
+#endif

+ 2 - 1
demo/sdl_opengl3/nuklear_sdl.c

@@ -221,7 +221,7 @@ nk_sdl_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_b
             glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
             glScissor(
                 (GLint)(cmd->clip_rect.x * scale.x),
-                (GLint)((height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * scale.y),
+                (GLint)((display_height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * scale.y),
                 (GLint)(cmd->clip_rect.w * scale.x),
                 (GLint)(cmd->clip_rect.h * scale.y));
 
@@ -366,5 +366,6 @@ void nk_sdl_shutdown(void)
     nk_font_atlas_clear(&sdl.atlas);
     nk_free(&sdl.ctx);
     nk_sdl_device_destroy();
+    memset(&sdl, 0, sizeof(sdl));
 }
 

+ 1 - 0
demo/x11/nuklear_xlib.c

@@ -523,6 +523,7 @@ nk_xlib_shutdown(void)
 {
     nk_xsurf_del(xlib.surf);
     nk_free(&xlib.ctx);
+    memset(&xlib, 0, sizeof(xlib));
 }
 
 NK_API void