From b0acb1ef0f3e06afcaeaa87b643829ed77a7edb7 Mon Sep 17 00:00:00 2001 From: lessthen3 <1337minecrafter6969@gmail.com> Date: Sun, 6 Oct 2024 00:23:07 -0400 Subject: [PATCH 1/4] Added demo updated for SDL3 added new demo headers that are updated to SDL3 and have been confirmed to compile and run appropriately on my machine. --- demo/sdl_opengl2/nuklear_sdl3_gl2.h | 360 +++++++++++++++++++++ demo/sdl_opengl3/nuklear_sdl3_gl3.h | 469 ++++++++++++++++++++++++++++ 2 files changed, 829 insertions(+) create mode 100644 demo/sdl_opengl2/nuklear_sdl3_gl2.h create mode 100644 demo/sdl_opengl3/nuklear_sdl3_gl3.h diff --git a/demo/sdl_opengl2/nuklear_sdl3_gl2.h b/demo/sdl_opengl2/nuklear_sdl3_gl2.h new file mode 100644 index 000000000..945465169 --- /dev/null +++ b/demo/sdl_opengl2/nuklear_sdl3_gl2.h @@ -0,0 +1,360 @@ +/* + * Nuklear - 1.32.0 - public domain + * no warrenty implied; use at your own risk. + * authored from 2015-2017 by Micha Mettke + */ +/* + * ============================================================== + * + * API + * + * =============================================================== + */ +#ifndef NK_SDL_GL2_H_ +#define NK_SDL_GL2_H_ + +#include + +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 int nk_sdl_handle_event(SDL_Event *evt); +NK_API void nk_sdl_render(enum nk_anti_aliasing); +NK_API void nk_sdl_shutdown(void); +NK_API void nk_sdl_handle_grab(void); + +#endif +/* + * ============================================================== + * + * IMPLEMENTATION + * + * =============================================================== + */ +#ifdef NK_SDL3_GL2_IMPLEMENTATION +#include +#include + +struct nk_sdl_device { + struct nk_buffer cmds; + struct nk_draw_null_texture tex_null; + GLuint font_tex; +}; + +struct nk_sdl_vertex { + float position[2]; + float uv[2]; + nk_byte col[4]; +}; + +static struct nk_sdl { + SDL_Window *win; + struct nk_sdl_device ogl; + struct nk_context ctx; + struct nk_font_atlas atlas; + Uint64 time_of_last_frame; +} 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) +{ + /* setup global state */ + struct nk_sdl_device *dev = &sdl.ogl; + int width, height; + int display_width, display_height; + struct nk_vec2 scale; + + Uint64 now = SDL_GetTicks(); + sdl.ctx.delta_time_seconds = (float)(now - sdl.time_of_last_frame) / 1000; + sdl.time_of_last_frame = now; + + SDL_GetWindowSize(sdl.win, &width, &height); + SDL_GetWindowSizeInPixels(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_sdl_vertex); + size_t vp = offsetof(struct nk_sdl_vertex, position); + size_t vt = offsetof(struct nk_sdl_vertex, uv); + size_t vc = offsetof(struct nk_sdl_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; + static const struct nk_draw_vertex_layout_element vertex_layout[] = { + {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, position)}, + {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, uv)}, + {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_sdl_vertex, col)}, + {NK_VERTEX_LAYOUT_END} + }; + memset(&config, 0, sizeof(config)); + config.vertex_layout = vertex_layout; + config.vertex_size = sizeof(struct nk_sdl_vertex); + config.vertex_alignment = NK_ALIGNOF(struct nk_sdl_vertex); + config.tex_null = dev->tex_null; + config.circle_segment_count = 22; + config.curve_segment_count = 22; + config.arc_segment_count = 22; + config.global_alpha = 1.0f; + config.shape_AA = AA; + config.line_AA = AA; + + /* 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)((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_clear(&dev->cmds); + 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_clipboard_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_clipboard_copy(nk_handle usr, const char *text, int len) +{ + char *str = 0; + (void)usr; + if (!len) return; + str = (char*)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_clipboard_copy; + sdl.ctx.clip.paste = nk_sdl_clipboard_paste; + sdl.ctx.clip.userdata = nk_handle_ptr(0); + nk_buffer_init_default(&sdl.ogl.cmds); + sdl.time_of_last_frame = SDL_GetTicks(); + 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.tex_null); + if (sdl.atlas.default_font) + nk_style_set_font(&sdl.ctx, &sdl.atlas.default_font->handle); +} + +NK_API void +nk_sdl_handle_grab(void) +{ + struct nk_context *ctx = &sdl.ctx; + if (ctx->input.mouse.grab) { + SDL_SetWindowRelativeMouseMode(sdl.win, true); + } else if (ctx->input.mouse.ungrab) { + /* better support for older SDL by setting mode first; causes an extra mouse motion event */ + SDL_SetWindowRelativeMouseMode(sdl.win, false); + SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); + } else if (ctx->input.mouse.grabbed) { + ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; + ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; + } +} + +NK_API int +nk_sdl_handle_event(SDL_Event *evt) +{ + struct nk_context *ctx = &sdl.ctx; + + switch(evt->type) + { + case SDL_EVENT_KEY_UP: /* KEYUP & KEYDOWN share same routine */ + case SDL_EVENT_KEY_DOWN: + { + int down = evt->type == SDL_EVENT_KEY_DOWN; + const bool* state = SDL_GetKeyboardState(0); + switch(evt->key.key) + { + case SDLK_RSHIFT: /* RSHIFT & LSHIFT share same routine */ + case SDLK_LSHIFT: nk_input_key(ctx, NK_KEY_SHIFT, down); break; + case SDLK_DELETE: nk_input_key(ctx, NK_KEY_DEL, down); break; + case SDLK_RETURN: nk_input_key(ctx, NK_KEY_ENTER, down); break; + case SDLK_TAB: nk_input_key(ctx, NK_KEY_TAB, down); break; + case SDLK_BACKSPACE: nk_input_key(ctx, NK_KEY_BACKSPACE, down); break; + case SDLK_HOME: nk_input_key(ctx, NK_KEY_TEXT_START, down); + nk_input_key(ctx, NK_KEY_SCROLL_START, down); break; + case SDLK_END: nk_input_key(ctx, NK_KEY_TEXT_END, down); + nk_input_key(ctx, NK_KEY_SCROLL_END, down); break; + case SDLK_PAGEDOWN: nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down); break; + case SDLK_PAGEUP: nk_input_key(ctx, NK_KEY_SCROLL_UP, down); break; + case SDLK_Z: nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_R: nk_input_key(ctx, NK_KEY_TEXT_REDO, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_C: nk_input_key(ctx, NK_KEY_COPY, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_V: nk_input_key(ctx, NK_KEY_PASTE, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_X: nk_input_key(ctx, NK_KEY_CUT, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_B: nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_E: nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_UP: nk_input_key(ctx, NK_KEY_UP, down); break; + case SDLK_DOWN: nk_input_key(ctx, NK_KEY_DOWN, down); break; + case 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); + break; + case 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); + break; + } + } + return 1; + + case SDL_EVENT_MOUSE_BUTTON_UP: /* MOUSEBUTTONUP & MOUSEBUTTONDOWN share same routine */ + case SDL_EVENT_MOUSE_BUTTON_DOWN: + { + int down = evt->type == SDL_EVENT_MOUSE_BUTTON_DOWN; + const int x = evt->button.x, y = evt->button.y; + switch(evt->button.button) + { + case SDL_BUTTON_LEFT: + if (evt->button.clicks > 1) + nk_input_button(ctx, NK_BUTTON_DOUBLE, x, y, down); + nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down); break; + case SDL_BUTTON_MIDDLE: nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down); break; + case SDL_BUTTON_RIGHT: nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down); break; + } + } + return 1; + + case SDL_EVENT_MOUSE_MOTION: + if (ctx->input.mouse.grabbed) { + int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y; + nk_input_motion(ctx, x + evt->motion.xrel, y + evt->motion.yrel); + } + else nk_input_motion(ctx, evt->motion.x, evt->motion.y); + return 1; + + case SDL_EVENT_TEXT_INPUT: + { + nk_glyph glyph; + memcpy(glyph, evt->text.text, NK_UTF_SIZE); + nk_input_glyph(ctx, glyph); + } + return 1; + + case SDL_EVENT_MOUSE_WHEEL: + nk_input_scroll(ctx,nk_vec2((float)evt->wheel.x,(float)evt->wheel.y)); + return 1; + } + return 0; +} + +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)); +} + +#endif diff --git a/demo/sdl_opengl3/nuklear_sdl3_gl3.h b/demo/sdl_opengl3/nuklear_sdl3_gl3.h new file mode 100644 index 000000000..1c0bc35d9 --- /dev/null +++ b/demo/sdl_opengl3/nuklear_sdl3_gl3.h @@ -0,0 +1,469 @@ +/* + * Nuklear - 1.32.0 - public domain + * no warrenty implied; use at your own risk. + * authored from 2015-2016 by Micha Mettke + */ + /* + * ============================================================== + * + * API + * + * =============================================================== + */ +#ifndef NK_SDL_GL3_H_ +#define NK_SDL_GL3_H_ + +#include +#include + +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 int 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); +NK_API void nk_sdl_device_destroy(void); +NK_API void nk_sdl_device_create(void); +NK_API void nk_sdl_handle_grab(void); + +#endif + +/* + * ============================================================== + * + * IMPLEMENTATION + * + * =============================================================== + */ +#ifdef NK_SDL3_GL3_IMPLEMENTATION + +#include +#include +#include + +struct nk_sdl_device { + struct nk_buffer cmds; + struct nk_draw_null_texture tex_null; + GLuint vbo, vao, ebo; + GLuint prog; + GLuint vert_shdr; + GLuint frag_shdr; + GLint attrib_pos; + GLint attrib_uv; + GLint attrib_col; + GLint uniform_tex; + GLint uniform_proj; + GLuint font_tex; +}; + +struct nk_sdl_vertex { + float position[2]; + float uv[2]; + nk_byte col[4]; +}; + +static struct nk_sdl { + SDL_Window* win; + struct nk_sdl_device ogl; + struct nk_context ctx; + struct nk_font_atlas atlas; + Uint64 time_of_last_frame; +} sdl; + +#ifdef __APPLE__ +#define NK_SHADER_VERSION "#version 150\n" +#else +#define NK_SHADER_VERSION "#version 300 es\n" +#endif +NK_API void +nk_sdl_device_create(void) +{ + GLint status; + static const GLchar* vertex_shader = + NK_SHADER_VERSION + "uniform mat4 ProjMtx;\n" + "in vec2 Position;\n" + "in vec2 TexCoord;\n" + "in vec4 Color;\n" + "out vec2 Frag_UV;\n" + "out vec4 Frag_Color;\n" + "void main() {\n" + " Frag_UV = TexCoord;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n" + "}\n"; + static const GLchar* fragment_shader = + NK_SHADER_VERSION + "precision mediump float;\n" + "uniform sampler2D Texture;\n" + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "out vec4 Out_Color;\n" + "void main(){\n" + " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" + "}\n"; + + struct nk_sdl_device* dev = &sdl.ogl; + nk_buffer_init_default(&dev->cmds); + dev->prog = glCreateProgram(); + dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER); + dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(dev->vert_shdr, 1, &vertex_shader, 0); + glShaderSource(dev->frag_shdr, 1, &fragment_shader, 0); + glCompileShader(dev->vert_shdr); + glCompileShader(dev->frag_shdr); + glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status); + assert(status == GL_TRUE); + glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status); + assert(status == GL_TRUE); + glAttachShader(dev->prog, dev->vert_shdr); + glAttachShader(dev->prog, dev->frag_shdr); + glLinkProgram(dev->prog); + glGetProgramiv(dev->prog, GL_LINK_STATUS, &status); + assert(status == GL_TRUE); + + dev->uniform_tex = glGetUniformLocation(dev->prog, "Texture"); + dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx"); + dev->attrib_pos = glGetAttribLocation(dev->prog, "Position"); + dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord"); + dev->attrib_col = glGetAttribLocation(dev->prog, "Color"); + + { + /* buffer setup */ + GLsizei vs = sizeof(struct nk_sdl_vertex); + size_t vp = offsetof(struct nk_sdl_vertex, position); + size_t vt = offsetof(struct nk_sdl_vertex, uv); + size_t vc = offsetof(struct nk_sdl_vertex, col); + + glGenBuffers(1, &dev->vbo); + glGenBuffers(1, &dev->ebo); + glGenVertexArrays(1, &dev->vao); + + glBindVertexArray(dev->vao); + glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); + + glEnableVertexAttribArray((GLuint)dev->attrib_pos); + glEnableVertexAttribArray((GLuint)dev->attrib_uv); + glEnableVertexAttribArray((GLuint)dev->attrib_col); + + glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp); + glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt); + glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc); + } + + glBindTexture(GL_TEXTURE_2D, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +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_device_destroy(void) +{ + struct nk_sdl_device* dev = &sdl.ogl; + glDetachShader(dev->prog, dev->vert_shdr); + glDetachShader(dev->prog, dev->frag_shdr); + glDeleteShader(dev->vert_shdr); + glDeleteShader(dev->frag_shdr); + glDeleteProgram(dev->prog); + glDeleteTextures(1, &dev->font_tex); + glDeleteBuffers(1, &dev->vbo); + glDeleteBuffers(1, &dev->ebo); + nk_buffer_free(&dev->cmds); +} + +NK_API void +nk_sdl_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer) +{ + struct nk_sdl_device* dev = &sdl.ogl; + int width, height; + int display_width, display_height; + struct nk_vec2 scale; + GLfloat ortho[4][4] = { + { 2.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, -2.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + + Uint64 now = SDL_GetTicks(); + sdl.ctx.delta_time_seconds = (float)(now - sdl.time_of_last_frame) / 1000; + sdl.time_of_last_frame = now; + + SDL_GetWindowSize(sdl.win, &width, &height); + SDL_GetWindowSizeInPixels(sdl.win, &display_width, &display_height); + ortho[0][0] /= (GLfloat)width; + ortho[1][1] /= (GLfloat)height; + + scale.x = (float)display_width / (float)width; + scale.y = (float)display_height / (float)height; + + /* setup global state */ + glViewport(0, 0, display_width, display_height); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + /* setup program */ + glUseProgram(dev->prog); + glUniform1i(dev->uniform_tex, 0); + glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]); + { + /* convert from command queue into draw list and draw to screen */ + const struct nk_draw_command* cmd; + void* vertices, * elements; + const nk_draw_index* offset = NULL; + struct nk_buffer vbuf, ebuf; + + /* allocate vertex and element buffer */ + glBindVertexArray(dev->vao); + glBindBuffer(GL_ARRAY_BUFFER, dev->vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo); + + glBufferData(GL_ARRAY_BUFFER, max_vertex_buffer, NULL, GL_STREAM_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, max_element_buffer, NULL, GL_STREAM_DRAW); + + /* load vertices/elements directly into vertex/element buffer */ + vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + { + /* fill convert configuration */ + struct nk_convert_config config; + static const struct nk_draw_vertex_layout_element vertex_layout[] = { + {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, position)}, + {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, uv)}, + {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_sdl_vertex, col)}, + {NK_VERTEX_LAYOUT_END} + }; + memset(&config, 0, sizeof(config)); + config.vertex_layout = vertex_layout; + config.vertex_size = sizeof(struct nk_sdl_vertex); + config.vertex_alignment = NK_ALIGNOF(struct nk_sdl_vertex); + config.tex_null = dev->tex_null; + config.circle_segment_count = 22; + config.curve_segment_count = 22; + config.arc_segment_count = 22; + config.global_alpha = 1.0f; + config.shape_AA = AA; + config.line_AA = AA; + + /* setup buffers to load vertices and elements */ + nk_buffer_init_fixed(&vbuf, vertices, (nk_size)max_vertex_buffer); + nk_buffer_init_fixed(&ebuf, elements, (nk_size)max_element_buffer); + nk_convert(&sdl.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, &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)((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_clear(&dev->cmds); + } + + glUseProgram(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindVertexArray(0); + glDisable(GL_BLEND); + glDisable(GL_SCISSOR_TEST); +} + +static void +nk_sdl_clipboard_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_clipboard_copy(nk_handle usr, const char* text, int len) +{ + char* str = 0; + (void)usr; + if (!len) return; + str = (char*)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_clipboard_copy; + sdl.ctx.clip.paste = nk_sdl_clipboard_paste; + sdl.ctx.clip.userdata = nk_handle_ptr(0); + nk_sdl_device_create(); + sdl.time_of_last_frame = SDL_GetTicks(); + 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.tex_null); + if (sdl.atlas.default_font) + nk_style_set_font(&sdl.ctx, &sdl.atlas.default_font->handle); + +} + +NK_API void +nk_sdl_handle_grab(void) +{ + struct nk_context* ctx = &sdl.ctx; + if (ctx->input.mouse.grab) { + SDL_SetWindowRelativeMouseMode(sdl.win, true); + } + else if (ctx->input.mouse.ungrab) { + /* better support for older SDL by setting mode first; causes an extra mouse motion event */ + SDL_SetWindowRelativeMouseMode(sdl.win, false); + SDL_WarpMouseInWindow(sdl.win, (int)ctx->input.mouse.prev.x, (int)ctx->input.mouse.prev.y); + } + else if (ctx->input.mouse.grabbed) { + ctx->input.mouse.pos.x = ctx->input.mouse.prev.x; + ctx->input.mouse.pos.y = ctx->input.mouse.prev.y; + } +} + +NK_API int +nk_sdl_handle_event(SDL_Event* evt) +{ + struct nk_context* ctx = &sdl.ctx; + + switch (evt->type) + { + case SDL_EVENT_KEY_UP: /* KEYUP & KEYDOWN share same routine */ + case SDL_EVENT_KEY_DOWN: + { + int down = evt->type == SDL_EVENT_KEY_DOWN; + const bool* state = SDL_GetKeyboardState(0); + switch (evt->key.key) + { + case SDLK_RSHIFT: /* RSHIFT & LSHIFT share same routine */ + case SDLK_LSHIFT: nk_input_key(ctx, NK_KEY_SHIFT, down); break; + case SDLK_DELETE: nk_input_key(ctx, NK_KEY_DEL, down); break; + case SDLK_RETURN: nk_input_key(ctx, NK_KEY_ENTER, down); break; + case SDLK_TAB: nk_input_key(ctx, NK_KEY_TAB, down); break; + case SDLK_BACKSPACE: nk_input_key(ctx, NK_KEY_BACKSPACE, down); break; + case SDLK_HOME: nk_input_key(ctx, NK_KEY_TEXT_START, down); + nk_input_key(ctx, NK_KEY_SCROLL_START, down); break; + case SDLK_END: nk_input_key(ctx, NK_KEY_TEXT_END, down); + nk_input_key(ctx, NK_KEY_SCROLL_END, down); break; + case SDLK_PAGEDOWN: nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down); break; + case SDLK_PAGEUP: nk_input_key(ctx, NK_KEY_SCROLL_UP, down); break; + case SDLK_Z: nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_R: nk_input_key(ctx, NK_KEY_TEXT_REDO, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_C: nk_input_key(ctx, NK_KEY_COPY, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_V: nk_input_key(ctx, NK_KEY_PASTE, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_X: nk_input_key(ctx, NK_KEY_CUT, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_B: nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_E: nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && state[SDL_SCANCODE_LCTRL]); break; + case SDLK_UP: nk_input_key(ctx, NK_KEY_UP, down); break; + case SDLK_DOWN: nk_input_key(ctx, NK_KEY_DOWN, down); break; + case 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); + break; + case 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); + break; + } + } + return 1; + + case SDL_EVENT_MOUSE_BUTTON_UP: /* MOUSEBUTTONUP & MOUSEBUTTONDOWN share same routine */ + case SDL_EVENT_MOUSE_BUTTON_DOWN: + { + int down = evt->type == SDL_EVENT_MOUSE_BUTTON_DOWN; + const int x = evt->button.x, y = evt->button.y; + switch (evt->button.button) + { + case SDL_BUTTON_LEFT: + if (evt->button.clicks > 1) + nk_input_button(ctx, NK_BUTTON_DOUBLE, x, y, down); + nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down); break; + case SDL_BUTTON_MIDDLE: nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down); break; + case SDL_BUTTON_RIGHT: nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down); break; + } + } + return 1; + + case SDL_EVENT_MOUSE_MOTION: + if (ctx->input.mouse.grabbed) { + int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y; + nk_input_motion(ctx, x + evt->motion.xrel, y + evt->motion.yrel); + } + else nk_input_motion(ctx, evt->motion.x, evt->motion.y); + return 1; + + case SDL_EVENT_TEXT_INPUT: + { + nk_glyph glyph; + memcpy(glyph, evt->text.text, NK_UTF_SIZE); + nk_input_glyph(ctx, glyph); + } + return 1; + + case SDL_EVENT_MOUSE_WHEEL: + nk_input_scroll(ctx, nk_vec2((float)evt->wheel.x, (float)evt->wheel.y)); + return 1; + } + return 0; +} + +NK_API +void nk_sdl_shutdown(void) +{ + nk_font_atlas_clear(&sdl.atlas); + nk_free(&sdl.ctx); + nk_sdl_device_destroy(); + memset(&sdl, 0, sizeof(sdl)); +} + +#endif \ No newline at end of file From 6fd7ea6a908babca60e109031008dd0bf8145214 Mon Sep 17 00:00:00 2001 From: lessthen3 <1337minecrafter6969@gmail.com> Date: Wed, 9 Oct 2024 00:07:34 -0400 Subject: [PATCH 2/4] Update nuklear_sdl3_gl2.h added detection for L and R CTRL --- demo/sdl_opengl2/nuklear_sdl3_gl2.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/demo/sdl_opengl2/nuklear_sdl3_gl2.h b/demo/sdl_opengl2/nuklear_sdl3_gl2.h index 945465169..faac33050 100644 --- a/demo/sdl_opengl2/nuklear_sdl3_gl2.h +++ b/demo/sdl_opengl2/nuklear_sdl3_gl2.h @@ -273,6 +273,10 @@ nk_sdl_handle_event(SDL_Event *evt) { case SDLK_RSHIFT: /* RSHIFT & LSHIFT share same routine */ case SDLK_LSHIFT: nk_input_key(ctx, NK_KEY_SHIFT, down); break; + + case SDLK_RCTRL: + case SDLK_LCTRL: nk_input_key(ctx, NK_KEY_CTRL, down); break; + case SDLK_DELETE: nk_input_key(ctx, NK_KEY_DEL, down); break; case SDLK_RETURN: nk_input_key(ctx, NK_KEY_ENTER, down); break; case SDLK_TAB: nk_input_key(ctx, NK_KEY_TAB, down); break; From cab7cb810641505a077e6c8b6efac1cedb148a67 Mon Sep 17 00:00:00 2001 From: lessthen3 <1337minecrafter6969@gmail.com> Date: Wed, 9 Oct 2024 00:09:22 -0400 Subject: [PATCH 3/4] Update nuklear_sdl3_gl3.h added L and R CTRL support --- demo/sdl_opengl3/nuklear_sdl3_gl3.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/demo/sdl_opengl3/nuklear_sdl3_gl3.h b/demo/sdl_opengl3/nuklear_sdl3_gl3.h index 1c0bc35d9..47898d1d3 100644 --- a/demo/sdl_opengl3/nuklear_sdl3_gl3.h +++ b/demo/sdl_opengl3/nuklear_sdl3_gl3.h @@ -384,6 +384,10 @@ nk_sdl_handle_event(SDL_Event* evt) { case SDLK_RSHIFT: /* RSHIFT & LSHIFT share same routine */ case SDLK_LSHIFT: nk_input_key(ctx, NK_KEY_SHIFT, down); break; + + case SDLK_RCTRL: /* LCTRL & RCTRL share same routine */ + case SDLK_LCTRL: nk_input_key(ctx, NK_KEY_CTRL, down); break; + case SDLK_DELETE: nk_input_key(ctx, NK_KEY_DEL, down); break; case SDLK_RETURN: nk_input_key(ctx, NK_KEY_ENTER, down); break; case SDLK_TAB: nk_input_key(ctx, NK_KEY_TAB, down); break; @@ -466,4 +470,4 @@ void nk_sdl_shutdown(void) memset(&sdl, 0, sizeof(sdl)); } -#endif \ No newline at end of file +#endif From 71c2c81b9aac4b53872bc083f3cf20ac6ba91f0f Mon Sep 17 00:00:00 2001 From: lessthen3 <1337minecrafter6969@gmail.com> Date: Tue, 18 Feb 2025 07:42:19 -0500 Subject: [PATCH 4/4] implemented recommended changes -changed directory structure to be more in line with current style -implemented map buffer change for better emscripten support -changed header guards and define names to reflect SDL3 opposed to SDL2 --- demo/{sdl_opengl2 => sdl2_opengl2}/Makefile | 0 demo/{sdl_opengl2 => sdl2_opengl2}/main.c | 0 .../nuklear_sdl_gl2.h | 0 demo/{sdl_opengl3 => sdl2_opengl3}/Makefile | 0 demo/{sdl_opengl3 => sdl2_opengl3}/main.c | 0 .../nuklear_sdl_gl3.h | 0 demo/sdl3_opengl2/Makefile | 27 +++ demo/sdl3_opengl2/main.c | 202 +++++++++++++++++ .../nuklear_sdl3_gl2.h | 5 +- demo/sdl3_opengl3/Makefile | 27 +++ demo/sdl3_opengl3/main.c | 212 ++++++++++++++++++ .../nuklear_sdl3_gl3.h | 18 +- 12 files changed, 485 insertions(+), 6 deletions(-) rename demo/{sdl_opengl2 => sdl2_opengl2}/Makefile (100%) rename demo/{sdl_opengl2 => sdl2_opengl2}/main.c (100%) rename demo/{sdl_opengl2 => sdl2_opengl2}/nuklear_sdl_gl2.h (100%) rename demo/{sdl_opengl3 => sdl2_opengl3}/Makefile (100%) rename demo/{sdl_opengl3 => sdl2_opengl3}/main.c (100%) rename demo/{sdl_opengl3 => sdl2_opengl3}/nuklear_sdl_gl3.h (100%) create mode 100644 demo/sdl3_opengl2/Makefile create mode 100644 demo/sdl3_opengl2/main.c rename demo/{sdl_opengl2 => sdl3_opengl2}/nuklear_sdl3_gl2.h (99%) create mode 100644 demo/sdl3_opengl3/Makefile create mode 100644 demo/sdl3_opengl3/main.c rename demo/{sdl_opengl3 => sdl3_opengl3}/nuklear_sdl3_gl3.h (97%) diff --git a/demo/sdl_opengl2/Makefile b/demo/sdl2_opengl2/Makefile similarity index 100% rename from demo/sdl_opengl2/Makefile rename to demo/sdl2_opengl2/Makefile diff --git a/demo/sdl_opengl2/main.c b/demo/sdl2_opengl2/main.c similarity index 100% rename from demo/sdl_opengl2/main.c rename to demo/sdl2_opengl2/main.c diff --git a/demo/sdl_opengl2/nuklear_sdl_gl2.h b/demo/sdl2_opengl2/nuklear_sdl_gl2.h similarity index 100% rename from demo/sdl_opengl2/nuklear_sdl_gl2.h rename to demo/sdl2_opengl2/nuklear_sdl_gl2.h diff --git a/demo/sdl_opengl3/Makefile b/demo/sdl2_opengl3/Makefile similarity index 100% rename from demo/sdl_opengl3/Makefile rename to demo/sdl2_opengl3/Makefile diff --git a/demo/sdl_opengl3/main.c b/demo/sdl2_opengl3/main.c similarity index 100% rename from demo/sdl_opengl3/main.c rename to demo/sdl2_opengl3/main.c diff --git a/demo/sdl_opengl3/nuklear_sdl_gl3.h b/demo/sdl2_opengl3/nuklear_sdl_gl3.h similarity index 100% rename from demo/sdl_opengl3/nuklear_sdl_gl3.h rename to demo/sdl2_opengl3/nuklear_sdl_gl3.h diff --git a/demo/sdl3_opengl2/Makefile b/demo/sdl3_opengl2/Makefile new file mode 100644 index 000000000..02790ccf4 --- /dev/null +++ b/demo/sdl3_opengl2/Makefile @@ -0,0 +1,27 @@ +# Install +BIN = demo + +# Flags +CFLAGS += -std=c89 -Wall -Wextra -pedantic -O2 +CFLAGS += $(shell pkg-config sdl3 --cflags) +LDFLAGS += $(shell pkg-config sdl3 --libs) + +SRC = main.c +OBJ = $(SRC:.c=.o) + +ifeq ($(OS),Windows_NT) +BIN := $(BIN).exe +LIBS = -lmingw32 -lopengl32 -lm -lGLU32 +else + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Darwin) + LIBS = -framework OpenGL -lm + else + LIBS = -lGL -lm -lGLU + endif +endif + +$(BIN): + @mkdir -p bin + rm -f bin/$(BIN) $(OBJS) + $(CC) $(SRC) $(CFLAGS) -o bin/$(BIN) $(LIBS) diff --git a/demo/sdl3_opengl2/main.c b/demo/sdl3_opengl2/main.c new file mode 100644 index 000000000..9601a34c4 --- /dev/null +++ b/demo/sdl3_opengl2/main.c @@ -0,0 +1,202 @@ +/* nuklear - 1.32.0 - public domain */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define NK_INCLUDE_FIXED_TYPES +#define NK_INCLUDE_STANDARD_IO +#define NK_INCLUDE_STANDARD_VARARGS +#define NK_INCLUDE_DEFAULT_ALLOCATOR +#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT +#define NK_INCLUDE_FONT_BAKING +#define NK_INCLUDE_DEFAULT_FONT +#define NK_IMPLEMENTATION +#define NK_SDL3_GL2_IMPLEMENTATION +#include "../../nuklear.h" +#include "nuklear_sdl3_gl2.h" + +#define WINDOW_WIDTH 1200 +#define WINDOW_HEIGHT 800 + +/* =============================================================== + * + * 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 defines */ +/*#define INCLUDE_ALL */ +/*#define INCLUDE_STYLE */ +/*#define INCLUDE_CALCULATOR */ +/*#define INCLUDE_CANVAS */ +/*#define INCLUDE_OVERVIEW */ +/*#define INCLUDE_NODE_EDITOR */ + +#ifdef INCLUDE_ALL + #define INCLUDE_STYLE + #define INCLUDE_CALCULATOR + #define INCLUDE_CANVAS + #define INCLUDE_OVERVIEW + #define INCLUDE_NODE_EDITOR +#endif + +#ifdef INCLUDE_STYLE + #include "../../demo/common/style.c" +#endif +#ifdef INCLUDE_CALCULATOR + #include "../../demo/common/calculator.c" +#endif +#ifdef INCLUDE_CANVAS + #include "../../demo/common/canvas.c" +#endif +#ifdef INCLUDE_OVERVIEW + #include "../../demo/common/overview.c" +#endif +#ifdef INCLUDE_NODE_EDITOR + #include "../../demo/common/node_editor.c" +#endif + +/* =============================================================== + * + * DEMO + * + * ===============================================================*/ +int +main(int argc, char *argv[]) +{ + /* Platform */ + SDL_Window *win; + SDL_GLContext glContext; + int win_width, win_height; + int running = 1; + + /* GUI */ + struct nk_context *ctx; + struct nk_colorf bg; + + NK_UNUSED(argc); + NK_UNUSED(argv); + + /* SDL setup */ + SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0"); + 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|SDL_WINDOW_ALLOW_HIGHDPI); + 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 */ + /* Load Cursor: if you uncomment cursor loading please hide the cursor */ + {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_load_all_cursors(ctx, atlas->cursors);*/ + /*nk_style_set_font(ctx, &roboto->handle)*/;} + + bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f; + 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_sdl_handle_grab(); /* optional grabbing behavior */ + nk_input_end(ctx); + + /* GUI */ + if (nk_begin(ctx, "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")) + 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); + + 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, nk_rgb_cf(bg), nk_vec2(nk_widget_width(ctx),400))) { + nk_layout_row_dynamic(ctx, 120, 1); + bg = nk_color_picker(ctx, bg, NK_RGBA); + nk_layout_row_dynamic(ctx, 25, 1); + bg.r = nk_propertyf(ctx, "#R:", 0, bg.r, 1.0f, 0.01f,0.005f); + bg.g = nk_propertyf(ctx, "#G:", 0, bg.g, 1.0f, 0.01f,0.005f); + bg.b = nk_propertyf(ctx, "#B:", 0, bg.b, 1.0f, 0.01f,0.005f); + bg.a = nk_propertyf(ctx, "#A:", 0, bg.a, 1.0f, 0.01f,0.005f); + nk_combo_end(ctx); + } + } + nk_end(ctx); + + /* -------------- EXAMPLES ---------------- */ + #ifdef INCLUDE_CALCULATOR + calculator(ctx); + #endif + #ifdef INCLUDE_CANVAS + canvas(ctx); + #endif + #ifdef INCLUDE_OVERVIEW + overview(ctx); + #endif + #ifdef INCLUDE_NODE_EDITOR + node_editor(ctx); + #endif + /* ----------------------------------------- */ + + /* Draw */ + SDL_GetWindowSize(win, &win_width, &win_height); + glViewport(0, 0, win_width, win_height); + glClear(GL_COLOR_BUFFER_BIT); + glClearColor(bg.r, bg.g, bg.b, bg.a); + /* 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); + SDL_GL_SwapWindow(win); + } + +cleanup: + nk_sdl_shutdown(); + SDL_GL_DeleteContext(glContext); + SDL_DestroyWindow(win); + SDL_Quit(); + return 0; +} + diff --git a/demo/sdl_opengl2/nuklear_sdl3_gl2.h b/demo/sdl3_opengl2/nuklear_sdl3_gl2.h similarity index 99% rename from demo/sdl_opengl2/nuklear_sdl3_gl2.h rename to demo/sdl3_opengl2/nuklear_sdl3_gl2.h index 945465169..58b8b87f1 100644 --- a/demo/sdl_opengl2/nuklear_sdl3_gl2.h +++ b/demo/sdl3_opengl2/nuklear_sdl3_gl2.h @@ -10,10 +10,11 @@ * * =============================================================== */ -#ifndef NK_SDL_GL2_H_ -#define NK_SDL_GL2_H_ +#ifndef NK_SDL3_GL2_H_ +#define NK_SDL3_GL2_H_ #include +#include NK_API struct nk_context* nk_sdl_init(SDL_Window *win); NK_API void nk_sdl_font_stash_begin(struct nk_font_atlas **atlas); diff --git a/demo/sdl3_opengl3/Makefile b/demo/sdl3_opengl3/Makefile new file mode 100644 index 000000000..ba86b2a21 --- /dev/null +++ b/demo/sdl3_opengl3/Makefile @@ -0,0 +1,27 @@ +# Install +BIN = demo + +# Flags +CFLAGS += -std=c89 -Wall -Wextra -pedantic -O2 +CFLAGS += $(shell pkg-config sdl3 --cflags) +LDFLAGS += $(shell pkg-config sdl3 --libs) + +SRC = main.c +OBJ = $(SRC:.c=.o) + +ifeq ($(OS),Windows_NT) +BIN := $(BIN).exe +LIBS = -lmingw32 -lopengl32 -lm -lGLU32 -lGLEW32 +else + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Darwin) + LIBS = -framework OpenGL -lm -lGLEW + else + LIBS = -lGL -lm -lGLU -lGLEW + endif +endif + +$(BIN): + @mkdir -p bin + rm -f bin/$(BIN) $(OBJS) + $(CC) $(SRC) $(CFLAGS) -o bin/$(BIN) $(LIBS) diff --git a/demo/sdl3_opengl3/main.c b/demo/sdl3_opengl3/main.c new file mode 100644 index 000000000..2bc0cded2 --- /dev/null +++ b/demo/sdl3_opengl3/main.c @@ -0,0 +1,212 @@ +/* nuklear - 1.32.0 - public domain */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define NK_INCLUDE_FIXED_TYPES +#define NK_INCLUDE_STANDARD_IO +#define NK_INCLUDE_STANDARD_VARARGS +#define NK_INCLUDE_DEFAULT_ALLOCATOR +#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT +#define NK_INCLUDE_FONT_BAKING +#define NK_INCLUDE_DEFAULT_FONT +#define NK_IMPLEMENTATION +#define NK_SDL3_GL3_IMPLEMENTATION +#include "../../nuklear.h" +#include "nuklear_sdl3_gl3.h" + +#define WINDOW_WIDTH 1200 +#define WINDOW_HEIGHT 800 + +#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 defines */ +/*#define INCLUDE_ALL */ +/*#define INCLUDE_STYLE */ +/*#define INCLUDE_CALCULATOR */ +/*#define INCLUDE_CANVAS */ +/*#define INCLUDE_OVERVIEW */ +/*#define INCLUDE_NODE_EDITOR */ + +#ifdef INCLUDE_ALL + #define INCLUDE_STYLE + #define INCLUDE_CALCULATOR + #define INCLUDE_CANVAS + #define INCLUDE_OVERVIEW + #define INCLUDE_NODE_EDITOR +#endif + +#ifdef INCLUDE_STYLE + #include "../../demo/common/style.c" +#endif +#ifdef INCLUDE_CALCULATOR + #include "../../demo/common/calculator.c" +#endif +#ifdef INCLUDE_CANVAS + #include "../../demo/common/canvas.c" +#endif +#ifdef INCLUDE_OVERVIEW + #include "../../demo/common/overview.c" +#endif +#ifdef INCLUDE_NODE_EDITOR + #include "../../demo/common/node_editor.c" +#endif + +/* =============================================================== + * + * DEMO + * + * ===============================================================*/ +int main(int argc, char *argv[]) +{ + /* Platform */ + SDL_Window *win; + SDL_GLContext glContext; + int win_width, win_height; + int running = 1; + + /* GUI */ + struct nk_context *ctx; + struct nk_colorf bg; + + NK_UNUSED(argc); + NK_UNUSED(argv); + + /* SDL setup */ + SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0"); + SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_EVENTS); + SDL_GL_SetAttribute (SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); + SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + win = SDL_CreateWindow("Demo", + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_ALLOW_HIGHDPI); + glContext = SDL_GL_CreateContext(win); + SDL_GetWindowSize(win, &win_width, &win_height); + + /* OpenGL setup */ + glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); + glewExperimental = 1; + if (glewInit() != GLEW_OK) { + fprintf(stderr, "Failed to setup GLEW\n"); + exit(1); + } + + ctx = nk_sdl_init(win); + /* 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_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_load_all_cursors(ctx, atlas->cursors);*/ + /*nk_style_set_font(ctx, &roboto->handle);*/} + + bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f; + 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_sdl_handle_grab(); /* optional grabbing behavior */ + nk_input_end(ctx); + + /* GUI */ + if (nk_begin(ctx, "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")) + printf("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, 22, 1); + nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); + + 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, nk_rgb_cf(bg), nk_vec2(nk_widget_width(ctx),400))) { + nk_layout_row_dynamic(ctx, 120, 1); + bg = nk_color_picker(ctx, bg, NK_RGBA); + nk_layout_row_dynamic(ctx, 25, 1); + bg.r = nk_propertyf(ctx, "#R:", 0, bg.r, 1.0f, 0.01f,0.005f); + bg.g = nk_propertyf(ctx, "#G:", 0, bg.g, 1.0f, 0.01f,0.005f); + bg.b = nk_propertyf(ctx, "#B:", 0, bg.b, 1.0f, 0.01f,0.005f); + bg.a = nk_propertyf(ctx, "#A:", 0, bg.a, 1.0f, 0.01f,0.005f); + nk_combo_end(ctx); + } + } + nk_end(ctx); + + /* -------------- EXAMPLES ---------------- */ + #ifdef INCLUDE_CALCULATOR + calculator(ctx); + #endif + #ifdef INCLUDE_CANVAS + canvas(ctx); + #endif + #ifdef INCLUDE_OVERVIEW + overview(ctx); + #endif + #ifdef INCLUDE_NODE_EDITOR + node_editor(ctx); + #endif + /* ----------------------------------------- */ + + /* Draw */ + SDL_GetWindowSize(win, &win_width, &win_height); + glViewport(0, 0, win_width, win_height); + glClear(GL_COLOR_BUFFER_BIT); + glClearColor(bg.r, bg.g, bg.b, bg.a); + /* 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; +} + diff --git a/demo/sdl_opengl3/nuklear_sdl3_gl3.h b/demo/sdl3_opengl3/nuklear_sdl3_gl3.h similarity index 97% rename from demo/sdl_opengl3/nuklear_sdl3_gl3.h rename to demo/sdl3_opengl3/nuklear_sdl3_gl3.h index 1c0bc35d9..f3621e0c6 100644 --- a/demo/sdl_opengl3/nuklear_sdl3_gl3.h +++ b/demo/sdl3_opengl3/nuklear_sdl3_gl3.h @@ -10,8 +10,8 @@ * * =============================================================== */ -#ifndef NK_SDL_GL3_H_ -#define NK_SDL_GL3_H_ +#ifndef NK_SDL3_GL3_H_ +#define NK_SDL3_GL3_H_ #include #include @@ -241,8 +241,18 @@ nk_sdl_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_b glBufferData(GL_ELEMENT_ARRAY_BUFFER, max_element_buffer, NULL, GL_STREAM_DRAW); /* load vertices/elements directly into vertex/element buffer */ - vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + vertices = + glMapBufferRange( + GL_ARRAY_BUFFER, + 0, + max_vertex_buffer, + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + elements = + glMapBufferRange( + GL_ELEMENT_ARRAY_BUFFER, + 0, + max_element_buffer, + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); { /* fill convert configuration */ struct nk_convert_config config;