From f9f00dc55599059df7d9aecd9e775fdc8206a180 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Sun, 15 Dec 2024 18:23:30 -0500 Subject: [PATCH 01/18] Add SDL3 --- demo/sdl3_renderer/.gitignore | 2 + demo/sdl3_renderer/CMakeLists.txt | 33 ++ demo/sdl3_renderer/cmake/FindSDL3.cmake | 8 + demo/sdl3_renderer/main.c | 71 +++++ demo/sdl3_renderer/nuklear_sdl3_renderer.h | 355 +++++++++++++++++++++ 5 files changed, 469 insertions(+) create mode 100644 demo/sdl3_renderer/.gitignore create mode 100644 demo/sdl3_renderer/CMakeLists.txt create mode 100644 demo/sdl3_renderer/cmake/FindSDL3.cmake create mode 100644 demo/sdl3_renderer/main.c create mode 100644 demo/sdl3_renderer/nuklear_sdl3_renderer.h diff --git a/demo/sdl3_renderer/.gitignore b/demo/sdl3_renderer/.gitignore new file mode 100644 index 000000000..db3341788 --- /dev/null +++ b/demo/sdl3_renderer/.gitignore @@ -0,0 +1,2 @@ +SDL +build diff --git a/demo/sdl3_renderer/CMakeLists.txt b/demo/sdl3_renderer/CMakeLists.txt new file mode 100644 index 000000000..8294652f8 --- /dev/null +++ b/demo/sdl3_renderer/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.16) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$") +set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE INTERNAL "") + +# CMAKE Modules +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +project(nuklear_sdl3_renderer) + +set(EXECUTABLE_NAME ${PROJECT_NAME}) + +# The SDL java code is hardcoded to load libmain.so on android, so we need to change EXECUTABLE_NAME +if (ANDROID) + set(EXECUTABLE_NAME main) + add_library(${EXECUTABLE_NAME} SHARED) +else() + add_executable(${EXECUTABLE_NAME}) +endif() + +# Add your sources to the target +target_sources(${EXECUTABLE_NAME} PRIVATE main.c) + +find_package(SDL3 REQUIRED) + +target_link_libraries(${EXECUTABLE_NAME} PUBLIC SDL3::SDL3) + +# Nuklear Include Directory +target_include_directories(${EXECUTABLE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# on Visual Studio, set our app as the default project +set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT "${EXECUTABLE_NAME}") diff --git a/demo/sdl3_renderer/cmake/FindSDL3.cmake b/demo/sdl3_renderer/cmake/FindSDL3.cmake new file mode 100644 index 000000000..54a3bde71 --- /dev/null +++ b/demo/sdl3_renderer/cmake/FindSDL3.cmake @@ -0,0 +1,8 @@ +include(FetchContent) +FetchContent_Declare( + SDL3 + GIT_REPOSITORY https://github.com/libsdl-org/SDL.git + GIT_TAG eb3fc06 + #GIT_SHALLOW 1 +) +FetchContent_MakeAvailable(SDL3) diff --git a/demo/sdl3_renderer/main.c b/demo/sdl3_renderer/main.c new file mode 100644 index 000000000..8c0154886 --- /dev/null +++ b/demo/sdl3_renderer/main.c @@ -0,0 +1,71 @@ +#define SDL_MAIN_USE_CALLBACKS +#include +#include + +#define NK_SDL_RENDERER_IMPLEMENTATION +#include "nuklear_sdl3_renderer.h" + +typedef struct AppContext { + SDL_Window* window; + SDL_Renderer* renderer; +} AppContext; + +SDL_AppResult SDL_Fail(){ + SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "Error %s", SDL_GetError()); + return SDL_APP_FAILURE; +} + +SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) { + return SDL_Fail(); + } + + AppContext* appContext = (AppContext*)SDL_malloc(sizeof(AppContext)); + if (appContext == NULL) { + return SDL_Fail(); + } + + if (!SDL_CreateWindowAndRenderer("Nuklear: SDL3 Renderer", 1200, 800, SDL_WINDOW_RESIZABLE, &appContext->window, &appContext->renderer)) { + SDL_free(appContext); + return SDL_Fail(); + } + + *appstate = appContext; + + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event* event) { + AppContext* app = (AppContext*)appstate; + + switch (event->type) { + case SDL_EVENT_QUIT: + return SDL_APP_SUCCESS; + } + + nk_sdl_handle_event(event); + + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppIterate(void *appstate) { + AppContext* app = (AppContext*)appstate; + + SDL_SetRenderDrawColor(app->renderer, 255, 0, 255, SDL_ALPHA_OPAQUE); + SDL_RenderClear(app->renderer); + SDL_RenderPresent(app->renderer); + + return SDL_APP_CONTINUE; +} + +void SDL_AppQuit(void* appstate, SDL_AppResult result) { + AppContext* app = (AppContext*)appstate; + + if (app) { + SDL_DestroyRenderer(app->renderer); + SDL_DestroyWindow(app->window); + SDL_free(app); + } + + SDL_Quit(); +} diff --git a/demo/sdl3_renderer/nuklear_sdl3_renderer.h b/demo/sdl3_renderer/nuklear_sdl3_renderer.h new file mode 100644 index 000000000..4e26e38a0 --- /dev/null +++ b/demo/sdl3_renderer/nuklear_sdl3_renderer.h @@ -0,0 +1,355 @@ +/* + * ============================================================== + * + * API + * + * =============================================================== + */ +#ifndef NK_SDL3_RENDERER_H_ +#define NK_SDL3_RENDERER_H_ + +#ifndef NK_SDL3_RENDERER_SDL_H +#define NK_SDL3_RENDERER_SDL_H +#endif +#include NK_SDL3_RENDERER_SDL_H + +#define NK_SIZE_TYPE size_t + +#ifndef NUKLEAR_H +#define NUKLEAR_H "nuklear.h" +#endif +#include NUKLEAR_H + +NK_API struct nk_context* nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer); +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 /* NK_SDL_RENDERER_H_ */ + +/* + * ============================================================== + * + * IMPLEMENTATION + * + * =============================================================== + */ +#ifdef NK_SDL_RENDERER_IMPLEMENTATION + +/* Nuklear SDL3 Renderer defines some macros for Nuklear SDL use */ +#define NK_MEMCPY SDL_memcpy +#define NK_IMPLEMENTATION + +#include + +#if SDL_MAJOR_VERSION < 3 +#error "nuklear_sdl3_renderer requires at least SDL 3.0.0" +#endif + +struct nk_sdl_device { + struct nk_buffer cmds; + struct nk_draw_null_texture tex_null; + SDL_Texture *font_tex; +}; + +struct nk_sdl_vertex { + float position[2]; + float uv[2]; + nk_byte col[4]; +}; + +struct nk_sdl { + SDL_Window *win; + SDL_Renderer *renderer; + struct nk_sdl_device ogl; + struct nk_context ctx; + struct nk_font_atlas atlas; + Uint64 time_of_last_frame; +} nk_sdl; + +NK_INTERN void +nk_sdl_device_upload_atlas(const void *image, int width, int height) +{ + struct nk_sdl_device *dev = &sdl.ogl; + + SDL_Texture *g_SDLFontTexture = SDL_CreateTexture(sdl.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); + if (g_SDLFontTexture == NULL) { + SDL_Log("error creating texture"); + return; + } + SDL_UpdateTexture(g_SDLFontTexture, NULL, image, 4 * width); + SDL_SetTextureBlendMode(g_SDLFontTexture, SDL_BLENDMODE_BLEND); + dev->font_tex = g_SDLFontTexture; +} + +NK_API void +nk_sdl_render(enum nk_anti_aliasing AA) +{ + /* setup global state */ + struct nk_sdl_device *dev = &sdl.ogl; + + { + SDL_Rect saved_clip; + SDL_bool clipping_enabled; + int 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} + }; + + Uint64 now = SDL_GetTicks64(); + sdl.ctx.delta_time_seconds = (float)(now - sdl.time_of_last_frame) / 1000; + sdl.time_of_last_frame = now; + + NK_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); + + /* iterate over and execute each draw command */ + offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf); + + clipping_enabled = SDL_RenderIsClipEnabled(sdl.renderer); + SDL_RenderGetClipRect(sdl.renderer, &saved_clip); + + nk_draw_foreach(cmd, &sdl.ctx, &dev->cmds) + { + if (!cmd->elem_count) continue; + + { + SDL_Rect r; + r.x = cmd->clip_rect.x; + r.y = cmd->clip_rect.y; + r.w = cmd->clip_rect.w; + r.h = cmd->clip_rect.h; + SDL_RenderSetClipRect(sdl.renderer, &r); + } + + { + const void *vertices = nk_buffer_memory_const(&vbuf); + + SDL_RenderGeometryRaw(sdl.renderer, + (SDL_Texture *)cmd->texture.ptr, + (const float*)((const nk_byte*)vertices + vp), vs, + (const SDL_Color*)((const nk_byte*)vertices + vc), vs, + (const float*)((const nk_byte*)vertices + vt), vs, + (vbuf.needed / vs), + (void *) offset, cmd->elem_count, 2); + + offset += cmd->elem_count; + } + } + + SDL_RenderSetClipRect(sdl.renderer, &saved_clip); + if (!clipping_enabled) { + SDL_RenderSetClipRect(sdl.renderer, NULL); + } + + nk_clear(&sdl.ctx); + nk_buffer_clear(&dev->cmds); + nk_buffer_free(&vbuf); + nk_buffer_free(&ebuf); + } +} + +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*)SDL_malloc((size_t)len+1); + if (!str) return; + SDL_memcpy(str, text, (size_t)len); + str[len] = '\0'; + SDL_SetClipboardText(str); + SDL_free(str); +} + +NK_API struct nk_context* +nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer) +{ + sdl.win = win; + sdl.renderer = renderer; + sdl.time_of_last_frame = SDL_GetTicks64(); + 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); + 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_ptr(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_SetRelativeMouseMode(SDL_TRUE); + } else if (ctx->input.mouse.ungrab) { + /* better support for older SDL by setting mode first; causes an extra mouse motion event */ + SDL_SetRelativeMouseMode(SDL_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: + case SDL_EVENT_KEY_DOWN: + { + int down = evt->type == SDL_KEYDOWN; + const Uint8* state = SDL_GetKeyboardState(0); + switch(evt->key.keysym.sym) + { + 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: + case SDL_EVENT_MOUSE_BUTTON_DOWN: + { + int down = evt->type == SDL_MOUSEBUTTONDOWN; + 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; + SDL_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(struct nk_sdl* sdl) +{ + struct nk_sdl_device *dev = &sdl->ogl; + nk_font_atlas_clear(&sdl->atlas); + SDL_free(&sdl->ctx); + SDL_DestroyTexture(dev->font_tex); + /* glDeleteTextures(1, &dev->font_tex); */ + nk_buffer_free(&dev->cmds); + NK_MEMSET(sdl, 0, sizeof(sdl)); +} + +#endif /* NK_SDL_RENDERER_IMPLEMENTATION */ From aecd78a204c76e9e133fe39a9e01f23b0cd2909d Mon Sep 17 00:00:00 2001 From: ryan zmuda Date: Thu, 6 Feb 2025 18:07:28 -0500 Subject: [PATCH 02/18] feat: sdl3_renderer backend --- demo/sdl3_renderer/CMakeLists.txt | 3 +- demo/sdl3_renderer/cmake/FindSDL3.cmake | 6 +- demo/sdl3_renderer/main.c | 178 ++++++++++++++++++++- demo/sdl3_renderer/nuklear_sdl3_renderer.h | 115 +++++-------- 4 files changed, 219 insertions(+), 83 deletions(-) diff --git a/demo/sdl3_renderer/CMakeLists.txt b/demo/sdl3_renderer/CMakeLists.txt index 8294652f8..75b6effbd 100644 --- a/demo/sdl3_renderer/CMakeLists.txt +++ b/demo/sdl3_renderer/CMakeLists.txt @@ -24,7 +24,8 @@ target_sources(${EXECUTABLE_NAME} PRIVATE main.c) find_package(SDL3 REQUIRED) -target_link_libraries(${EXECUTABLE_NAME} PUBLIC SDL3::SDL3) +# TODO: remove libm and fallback on Nuklear floor() +target_link_libraries(${EXECUTABLE_NAME} PUBLIC SDL3::SDL3 m) # Nuklear Include Directory target_include_directories(${EXECUTABLE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../..) diff --git a/demo/sdl3_renderer/cmake/FindSDL3.cmake b/demo/sdl3_renderer/cmake/FindSDL3.cmake index 54a3bde71..d6d8f9a27 100644 --- a/demo/sdl3_renderer/cmake/FindSDL3.cmake +++ b/demo/sdl3_renderer/cmake/FindSDL3.cmake @@ -1,8 +1,8 @@ include(FetchContent) FetchContent_Declare( SDL3 - GIT_REPOSITORY https://github.com/libsdl-org/SDL.git - GIT_TAG eb3fc06 - #GIT_SHALLOW 1 + GIT_REPOSITORY https://github.com/libsdl-org/SDL.git + GIT_TAG release-3.2.2 + GIT_SHALLOW TRUE ) FetchContent_MakeAvailable(SDL3) diff --git a/demo/sdl3_renderer/main.c b/demo/sdl3_renderer/main.c index 8c0154886..dbfa7a4e3 100644 --- a/demo/sdl3_renderer/main.c +++ b/demo/sdl3_renderer/main.c @@ -1,15 +1,88 @@ +/* nuklear - public domain */ +#include +#include /* offsetof TODO: sdl2_renderer didn't need this header? */ + #define SDL_MAIN_USE_CALLBACKS #include #include -#define NK_SDL_RENDERER_IMPLEMENTATION +#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_RENDERER_IMPLEMENTATION +#define NK_INCLUDE_STANDARD_BOOL +#include "nuklear.h" #include "nuklear_sdl3_renderer.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_CONFIGURATOR */ +/*#define INCLUDE_NODE_EDITOR */ + +#define INCLUDE_ALL + +#ifdef INCLUDE_ALL + #define INCLUDE_STYLE + #define INCLUDE_CALCULATOR + #define INCLUDE_CANVAS + #define INCLUDE_OVERVIEW + /* #define INCLUDE_CONFIGURATOR */ + #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_CONFIGURATOR + #include "../../demo/common/style_configurator.c" +#endif +*/ +#ifdef INCLUDE_NODE_EDITOR + #include "../../demo/common/node_editor.c" +#endif + +/* =============================================================== + * + * DEMO + * + * ===============================================================*/ + typedef struct AppContext { SDL_Window* window; SDL_Renderer* renderer; } AppContext; +struct nk_context * ctx; +struct nk_colorf bg; + SDL_AppResult SDL_Fail(){ SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "Error %s", SDL_GetError()); return SDL_APP_FAILURE; @@ -25,13 +98,57 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { return SDL_Fail(); } - if (!SDL_CreateWindowAndRenderer("Nuklear: SDL3 Renderer", 1200, 800, SDL_WINDOW_RESIZABLE, &appContext->window, &appContext->renderer)) { + if (!SDL_CreateWindowAndRenderer("Nuklear: SDL3 Renderer", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &appContext->window, &appContext->renderer)) { SDL_free(appContext); return SDL_Fail(); } + SDL_StartTextInput(appContext->window); + + bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f; + *appstate = appContext; + float font_scale = 1; + + { + int render_w, render_h; + int window_w, window_h; + float scale_x, scale_y; + SDL_GetCurrentRenderOutputSize(appContext->renderer, &render_w, &render_h); + SDL_GetWindowSize(appContext->window, &window_w, &window_h); + scale_x = (float)(render_w) / (float)(window_w); + scale_y = (float)(render_h) / (float)(window_h); + SDL_SetRenderScale(appContext->renderer, scale_x, scale_y); + font_scale = scale_y; + } + + ctx = nk_sdl_init(appContext->window, appContext->renderer); + + { + struct nk_font_atlas *atlas; + struct nk_font_config config = nk_font_config(0); + struct nk_font *font; + + /* set up the font atlas and add desired font; note that font sizes are + * multiplied by font_scale to produce better results at higher DPIs */ + nk_sdl_font_stash_begin(&atlas); + font = nk_font_atlas_add_default(atlas, 13 * font_scale, &config); + /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14 * font_scale, &config);*/ + /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 16 * font_scale, &config);*/ + /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13 * font_scale, &config);*/ + /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12 * font_scale, &config);*/ + /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10 * font_scale, &config);*/ + /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13 * font_scale, &config);*/ + nk_sdl_font_stash_end(); + + /* this hack makes the font appear to be scaled down to the desired + * size and is only necessary when font_scale > 1 */ + font->handle.height /= font_scale; + /*nk_style_load_all_cursors(ctx, atlas->cursors);*/ + nk_style_set_font(ctx, &font->handle); + } + return SDL_APP_CONTINUE; } @@ -49,12 +166,69 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event* event) { } SDL_AppResult SDL_AppIterate(void *appstate) { + nk_input_end(ctx); AppContext* app = (AppContext*)appstate; + /* 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, 25, 1); + nk_property_int(ctx, "Compression:", 0, &property, 1000, 1, 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_CONFIGURATOR + style_configurator(ctx, color_table); + #endif + #ifdef INCLUDE_NODE_EDITOR + node_editor(ctx); + #endif + /* ----------------------------------------- */ + SDL_SetRenderDrawColor(app->renderer, 255, 0, 255, SDL_ALPHA_OPAQUE); SDL_RenderClear(app->renderer); + + nk_sdl_render(NK_ANTI_ALIASING_ON); + SDL_RenderPresent(app->renderer); + nk_input_begin(ctx); return SDL_APP_CONTINUE; } diff --git a/demo/sdl3_renderer/nuklear_sdl3_renderer.h b/demo/sdl3_renderer/nuklear_sdl3_renderer.h index 4e26e38a0..12950af69 100644 --- a/demo/sdl3_renderer/nuklear_sdl3_renderer.h +++ b/demo/sdl3_renderer/nuklear_sdl3_renderer.h @@ -1,3 +1,6 @@ +/* + * Nuklear - 4.9.4 - public domain + */ /* * ============================================================== * @@ -8,25 +11,16 @@ #ifndef NK_SDL3_RENDERER_H_ #define NK_SDL3_RENDERER_H_ -#ifndef NK_SDL3_RENDERER_SDL_H -#define NK_SDL3_RENDERER_SDL_H -#endif -#include NK_SDL3_RENDERER_SDL_H - -#define NK_SIZE_TYPE size_t - -#ifndef NUKLEAR_H -#define NUKLEAR_H "nuklear.h" -#endif -#include NUKLEAR_H - NK_API struct nk_context* nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer); 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); + +#if SDL_MAJOR_VERSION < 3 +#error "nuklear_sdl3_renderer requires at least SDL 3.0.0" +#endif #endif /* NK_SDL_RENDERER_H_ */ @@ -37,17 +31,7 @@ NK_API void nk_sdl_handle_grab(void); * * =============================================================== */ -#ifdef NK_SDL_RENDERER_IMPLEMENTATION - -/* Nuklear SDL3 Renderer defines some macros for Nuklear SDL use */ -#define NK_MEMCPY SDL_memcpy -#define NK_IMPLEMENTATION - -#include - -#if SDL_MAJOR_VERSION < 3 -#error "nuklear_sdl3_renderer requires at least SDL 3.0.0" -#endif +#ifdef NK_SDL3_RENDERER_IMPLEMENTATION struct nk_sdl_device { struct nk_buffer cmds; @@ -58,17 +42,16 @@ struct nk_sdl_device { struct nk_sdl_vertex { float position[2]; float uv[2]; - nk_byte col[4]; + float col[4]; }; -struct nk_sdl { +static struct nk_sdl { SDL_Window *win; SDL_Renderer *renderer; struct nk_sdl_device ogl; struct nk_context ctx; struct nk_font_atlas atlas; - Uint64 time_of_last_frame; -} nk_sdl; +} sdl; NK_INTERN void nk_sdl_device_upload_atlas(const void *image, int width, int height) @@ -93,7 +76,7 @@ nk_sdl_render(enum nk_anti_aliasing AA) { SDL_Rect saved_clip; - SDL_bool clipping_enabled; + bool clipping_enabled; int vs = sizeof(struct nk_sdl_vertex); size_t vp = offsetof(struct nk_sdl_vertex, position); size_t vt = offsetof(struct nk_sdl_vertex, uv); @@ -107,16 +90,11 @@ nk_sdl_render(enum nk_anti_aliasing AA) /* 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_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_R32G32B32A32_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, col)}, {NK_VERTEX_LAYOUT_END} }; - - Uint64 now = SDL_GetTicks64(); - sdl.ctx.delta_time_seconds = (float)(now - sdl.time_of_last_frame) / 1000; - sdl.time_of_last_frame = now; - NK_MEMSET(&config, 0, sizeof(config)); config.vertex_layout = vertex_layout; config.vertex_size = sizeof(struct nk_sdl_vertex); @@ -137,8 +115,8 @@ nk_sdl_render(enum nk_anti_aliasing AA) /* iterate over and execute each draw command */ offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf); - clipping_enabled = SDL_RenderIsClipEnabled(sdl.renderer); - SDL_RenderGetClipRect(sdl.renderer, &saved_clip); + clipping_enabled = SDL_RenderClipEnabled(sdl.renderer); + SDL_GetRenderClipRect(sdl.renderer, &saved_clip); nk_draw_foreach(cmd, &sdl.ctx, &dev->cmds) { @@ -150,7 +128,7 @@ nk_sdl_render(enum nk_anti_aliasing AA) r.y = cmd->clip_rect.y; r.w = cmd->clip_rect.w; r.h = cmd->clip_rect.h; - SDL_RenderSetClipRect(sdl.renderer, &r); + SDL_SetRenderClipRect(sdl.renderer, &r); } { @@ -159,7 +137,7 @@ nk_sdl_render(enum nk_anti_aliasing AA) SDL_RenderGeometryRaw(sdl.renderer, (SDL_Texture *)cmd->texture.ptr, (const float*)((const nk_byte*)vertices + vp), vs, - (const SDL_Color*)((const nk_byte*)vertices + vc), vs, + (const SDL_FColor*)((const nk_byte*)vertices + vc), vs, (const float*)((const nk_byte*)vertices + vt), vs, (vbuf.needed / vs), (void *) offset, cmd->elem_count, 2); @@ -168,9 +146,9 @@ nk_sdl_render(enum nk_anti_aliasing AA) } } - SDL_RenderSetClipRect(sdl.renderer, &saved_clip); + SDL_SetRenderClipRect(sdl.renderer, &saved_clip); if (!clipping_enabled) { - SDL_RenderSetClipRect(sdl.renderer, NULL); + SDL_SetRenderClipRect(sdl.renderer, NULL); } nk_clear(&sdl.ctx); @@ -194,12 +172,12 @@ nk_sdl_clipboard_copy(nk_handle usr, const char *text, int len) char *str = 0; (void)usr; if (!len) return; - str = (char*)SDL_malloc((size_t)len+1); + str = (char*)malloc((size_t)len+1); if (!str) return; - SDL_memcpy(str, text, (size_t)len); + memcpy(str, text, (size_t)len); str[len] = '\0'; SDL_SetClipboardText(str); - SDL_free(str); + free(str); } NK_API struct nk_context* @@ -207,7 +185,6 @@ nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer) { sdl.win = win; sdl.renderer = renderer; - sdl.time_of_last_frame = SDL_GetTicks64(); nk_init_default(&sdl.ctx, 0); sdl.ctx.clip.copy = nk_sdl_clipboard_copy; sdl.ctx.clip.paste = nk_sdl_clipboard_paste; @@ -235,22 +212,6 @@ nk_sdl_font_stash_end(void) 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_SetRelativeMouseMode(SDL_TRUE); - } else if (ctx->input.mouse.ungrab) { - /* better support for older SDL by setting mode first; causes an extra mouse motion event */ - SDL_SetRelativeMouseMode(SDL_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) { @@ -258,12 +219,12 @@ nk_sdl_handle_event(SDL_Event *evt) switch(evt->type) { - case SDL_EVENT_KEY_UP: + case SDL_EVENT_KEY_UP: /* KEYUP & KEYDOWN share same routine */ case SDL_EVENT_KEY_DOWN: { - int down = evt->type == SDL_KEYDOWN; - const Uint8* state = SDL_GetKeyboardState(0); - switch(evt->key.keysym.sym) + 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; @@ -297,13 +258,13 @@ nk_sdl_handle_event(SDL_Event *evt) else nk_input_key(ctx, NK_KEY_RIGHT, down); break; } + return 1; } - return 1; - case SDL_EVENT_MOUSE_BUTTON_UP: + case SDL_EVENT_MOUSE_BUTTON_UP: /* MOUSEBUTTONUP & MOUSEBUTTONDOWN share same routine */ case SDL_EVENT_MOUSE_BUTTON_DOWN: { - int down = evt->type == SDL_MOUSEBUTTONDOWN; + int down = evt->button.down; const int x = evt->button.x, y = evt->button.y; switch(evt->button.button) { @@ -328,7 +289,7 @@ nk_sdl_handle_event(SDL_Event *evt) case SDL_EVENT_TEXT_INPUT: { nk_glyph glyph; - SDL_memcpy(glyph, evt->text.text, NK_UTF_SIZE); + memcpy(glyph, evt->text.text, NK_UTF_SIZE); nk_input_glyph(ctx, glyph); } return 1; @@ -341,15 +302,15 @@ nk_sdl_handle_event(SDL_Event *evt) } NK_API -void nk_sdl_shutdown(struct nk_sdl* sdl) +void nk_sdl_shutdown(void) { - struct nk_sdl_device *dev = &sdl->ogl; - nk_font_atlas_clear(&sdl->atlas); - SDL_free(&sdl->ctx); + struct nk_sdl_device *dev = &sdl.ogl; + nk_font_atlas_clear(&sdl.atlas); + nk_free(&sdl.ctx); SDL_DestroyTexture(dev->font_tex); /* glDeleteTextures(1, &dev->font_tex); */ nk_buffer_free(&dev->cmds); - NK_MEMSET(sdl, 0, sizeof(sdl)); + memset(&sdl, 0, sizeof(sdl)); } -#endif /* NK_SDL_RENDERER_IMPLEMENTATION */ +#endif /* NK_SDL3_RENDERER_IMPLEMENTATION */ From 079d3b681d24da4b75e4d772e6486bcaaf73cdca Mon Sep 17 00:00:00 2001 From: ryan zmuda Date: Thu, 6 Feb 2025 18:46:28 -0500 Subject: [PATCH 03/18] sdl_gpu skeleton --- demo/sdl_gpu/.gitignore | 1 + demo/sdl_gpu/CMakeLists.txt | 34 ++++ demo/sdl_gpu/cmake/FindSDL3.cmake | 8 + demo/sdl_gpu/main.c | 245 +++++++++++++++++++++++ demo/sdl_gpu/nuklear_sdl_gpu.h | 316 ++++++++++++++++++++++++++++++ 5 files changed, 604 insertions(+) create mode 100644 demo/sdl_gpu/.gitignore create mode 100644 demo/sdl_gpu/CMakeLists.txt create mode 100644 demo/sdl_gpu/cmake/FindSDL3.cmake create mode 100644 demo/sdl_gpu/main.c create mode 100644 demo/sdl_gpu/nuklear_sdl_gpu.h diff --git a/demo/sdl_gpu/.gitignore b/demo/sdl_gpu/.gitignore new file mode 100644 index 000000000..378eac25d --- /dev/null +++ b/demo/sdl_gpu/.gitignore @@ -0,0 +1 @@ +build diff --git a/demo/sdl_gpu/CMakeLists.txt b/demo/sdl_gpu/CMakeLists.txt new file mode 100644 index 000000000..6e331fe4a --- /dev/null +++ b/demo/sdl_gpu/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.16) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$") +set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE INTERNAL "") + +# CMAKE Modules +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +project(nuklear_sdl_gpu) + +set(EXECUTABLE_NAME ${PROJECT_NAME}) + +# The SDL java code is hardcoded to load libmain.so on android, so we need to change EXECUTABLE_NAME +if (ANDROID) + set(EXECUTABLE_NAME main) + add_library(${EXECUTABLE_NAME} SHARED) +else() + add_executable(${EXECUTABLE_NAME}) +endif() + +# Add your sources to the target +target_sources(${EXECUTABLE_NAME} PRIVATE main.c) + +find_package(SDL3 REQUIRED) + +# TODO: remove libm and fallback on Nuklear floor() +target_link_libraries(${EXECUTABLE_NAME} PUBLIC SDL3::SDL3 m) + +# Nuklear Include Directory +target_include_directories(${EXECUTABLE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# on Visual Studio, set our app as the default project +set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT "${EXECUTABLE_NAME}") diff --git a/demo/sdl_gpu/cmake/FindSDL3.cmake b/demo/sdl_gpu/cmake/FindSDL3.cmake new file mode 100644 index 000000000..d6d8f9a27 --- /dev/null +++ b/demo/sdl_gpu/cmake/FindSDL3.cmake @@ -0,0 +1,8 @@ +include(FetchContent) +FetchContent_Declare( + SDL3 + GIT_REPOSITORY https://github.com/libsdl-org/SDL.git + GIT_TAG release-3.2.2 + GIT_SHALLOW TRUE +) +FetchContent_MakeAvailable(SDL3) diff --git a/demo/sdl_gpu/main.c b/demo/sdl_gpu/main.c new file mode 100644 index 000000000..6a307efb9 --- /dev/null +++ b/demo/sdl_gpu/main.c @@ -0,0 +1,245 @@ +/* nuklear - public domain */ +#include +#include /* offsetof TODO: sdl2_renderer didn't need this header? */ + +#define SDL_MAIN_USE_CALLBACKS +#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_SDL_GPU_IMPLEMENTATION +#define NK_INCLUDE_STANDARD_BOOL +#include "nuklear.h" +#include "nuklear_sdl_gpu.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_CONFIGURATOR */ +/*#define INCLUDE_NODE_EDITOR */ + +#define INCLUDE_ALL + +#ifdef INCLUDE_ALL + #define INCLUDE_STYLE + #define INCLUDE_CALCULATOR + #define INCLUDE_CANVAS + #define INCLUDE_OVERVIEW + /* #define INCLUDE_CONFIGURATOR */ + #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_CONFIGURATOR + #include "../../demo/common/style_configurator.c" +#endif +*/ +#ifdef INCLUDE_NODE_EDITOR + #include "../../demo/common/node_editor.c" +#endif + +/* =============================================================== + * + * DEMO + * + * ===============================================================*/ + +typedef struct AppContext { + SDL_Window* window; + SDL_Renderer* renderer; +} AppContext; + +struct nk_context * ctx; +struct nk_colorf bg; + +SDL_AppResult SDL_Fail(){ + SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "Error %s", SDL_GetError()); + return SDL_APP_FAILURE; +} + +SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) { + return SDL_Fail(); + } + + AppContext* appContext = (AppContext*)SDL_malloc(sizeof(AppContext)); + if (appContext == NULL) { + return SDL_Fail(); + } + + if (!SDL_CreateWindowAndRenderer("Nuklear: SDL3 GPU", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &appContext->window, &appContext->renderer)) { + SDL_free(appContext); + return SDL_Fail(); + } + + SDL_StartTextInput(appContext->window); + + bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f; + + *appstate = appContext; + + float font_scale = 1; + + { + int render_w, render_h; + int window_w, window_h; + float scale_x, scale_y; + SDL_GetCurrentRenderOutputSize(appContext->renderer, &render_w, &render_h); + SDL_GetWindowSize(appContext->window, &window_w, &window_h); + scale_x = (float)(render_w) / (float)(window_w); + scale_y = (float)(render_h) / (float)(window_h); + SDL_SetRenderScale(appContext->renderer, scale_x, scale_y); + font_scale = scale_y; + } + + ctx = nk_sdl_init(appContext->window, appContext->renderer); + + { + struct nk_font_atlas *atlas; + struct nk_font_config config = nk_font_config(0); + struct nk_font *font; + + /* set up the font atlas and add desired font; note that font sizes are + * multiplied by font_scale to produce better results at higher DPIs */ + nk_sdl_font_stash_begin(&atlas); + font = nk_font_atlas_add_default(atlas, 13 * font_scale, &config); + /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14 * font_scale, &config);*/ + /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 16 * font_scale, &config);*/ + /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13 * font_scale, &config);*/ + /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12 * font_scale, &config);*/ + /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10 * font_scale, &config);*/ + /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13 * font_scale, &config);*/ + nk_sdl_font_stash_end(); + + /* this hack makes the font appear to be scaled down to the desired + * size and is only necessary when font_scale > 1 */ + font->handle.height /= font_scale; + /*nk_style_load_all_cursors(ctx, atlas->cursors);*/ + nk_style_set_font(ctx, &font->handle); + } + + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event* event) { + AppContext* app = (AppContext*)appstate; + + switch (event->type) { + case SDL_EVENT_QUIT: + return SDL_APP_SUCCESS; + } + + nk_sdl_handle_event(event); + + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppIterate(void *appstate) { + nk_input_end(ctx); + AppContext* app = (AppContext*)appstate; + + /* 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, 25, 1); + nk_property_int(ctx, "Compression:", 0, &property, 1000, 1, 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_CONFIGURATOR + style_configurator(ctx, color_table); + #endif + #ifdef INCLUDE_NODE_EDITOR + node_editor(ctx); + #endif + /* ----------------------------------------- */ + + SDL_SetRenderDrawColor(app->renderer, 255, 0, 255, SDL_ALPHA_OPAQUE); + SDL_RenderClear(app->renderer); + + nk_sdl_render(NK_ANTI_ALIASING_ON); + + SDL_RenderPresent(app->renderer); + + nk_input_begin(ctx); + return SDL_APP_CONTINUE; +} + +void SDL_AppQuit(void* appstate, SDL_AppResult result) { + AppContext* app = (AppContext*)appstate; + + if (app) { + SDL_DestroyRenderer(app->renderer); + SDL_DestroyWindow(app->window); + SDL_free(app); + } + + SDL_Quit(); +} diff --git a/demo/sdl_gpu/nuklear_sdl_gpu.h b/demo/sdl_gpu/nuklear_sdl_gpu.h new file mode 100644 index 000000000..df347a580 --- /dev/null +++ b/demo/sdl_gpu/nuklear_sdl_gpu.h @@ -0,0 +1,316 @@ +/* + * Nuklear - 4.9.4 - public domain + */ +/* + * ============================================================== + * + * API + * + * =============================================================== + */ +#ifndef NK_SDL_GPU_H_ +#define NK_SDL_GPU_H_ + +NK_API struct nk_context* nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer); +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); + +#if SDL_MAJOR_VERSION < 3 +#error "nuklear_sdl_gpu requires at least SDL 3.0.0" +#endif + +#endif /* NK_SDL_GPU_H_ */ + +/* + * ============================================================== + * + * IMPLEMENTATION + * + * =============================================================== + */ +#ifdef NK_SDL_GPU_IMPLEMENTATION + +struct nk_sdl_device { + struct nk_buffer cmds; + struct nk_draw_null_texture tex_null; + SDL_Texture *font_tex; +}; + +struct nk_sdl_vertex { + float position[2]; + float uv[2]; + float col[4]; +}; + +static struct nk_sdl { + SDL_Window *win; + SDL_Renderer *renderer; + 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; + + SDL_Texture *g_SDLFontTexture = SDL_CreateTexture(sdl.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); + if (g_SDLFontTexture == NULL) { + SDL_Log("error creating texture"); + return; + } + SDL_UpdateTexture(g_SDLFontTexture, NULL, image, 4 * width); + SDL_SetTextureBlendMode(g_SDLFontTexture, SDL_BLENDMODE_BLEND); + dev->font_tex = g_SDLFontTexture; +} + +NK_API void +nk_sdl_render(enum nk_anti_aliasing AA) +{ + /* setup global state */ + struct nk_sdl_device *dev = &sdl.ogl; + + { + SDL_Rect saved_clip; + bool clipping_enabled; + int 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_R32G32B32A32_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, col)}, + {NK_VERTEX_LAYOUT_END} + }; + NK_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); + + /* iterate over and execute each draw command */ + offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf); + + clipping_enabled = SDL_RenderClipEnabled(sdl.renderer); + SDL_GetRenderClipRect(sdl.renderer, &saved_clip); + + nk_draw_foreach(cmd, &sdl.ctx, &dev->cmds) + { + if (!cmd->elem_count) continue; + + { + SDL_Rect r; + r.x = cmd->clip_rect.x; + r.y = cmd->clip_rect.y; + r.w = cmd->clip_rect.w; + r.h = cmd->clip_rect.h; + SDL_SetRenderClipRect(sdl.renderer, &r); + } + + { + const void *vertices = nk_buffer_memory_const(&vbuf); + + SDL_RenderGeometryRaw(sdl.renderer, + (SDL_Texture *)cmd->texture.ptr, + (const float*)((const nk_byte*)vertices + vp), vs, + (const SDL_FColor*)((const nk_byte*)vertices + vc), vs, + (const float*)((const nk_byte*)vertices + vt), vs, + (vbuf.needed / vs), + (void *) offset, cmd->elem_count, 2); + + offset += cmd->elem_count; + } + } + + SDL_SetRenderClipRect(sdl.renderer, &saved_clip); + if (!clipping_enabled) { + SDL_SetRenderClipRect(sdl.renderer, NULL); + } + + nk_clear(&sdl.ctx); + nk_buffer_clear(&dev->cmds); + nk_buffer_free(&vbuf); + nk_buffer_free(&ebuf); + } +} + +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_Renderer *renderer) +{ + sdl.win = win; + sdl.renderer = renderer; + 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); + 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_ptr(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 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->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); + SDL_DestroyTexture(dev->font_tex); + /* glDeleteTextures(1, &dev->font_tex); */ + nk_buffer_free(&dev->cmds); + memset(&sdl, 0, sizeof(sdl)); +} + +#endif /* NK_SDL_GPU_IMPLEMENTATION */ From e050f90339f0d437d0f59f055824aae0554f6e9f Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Thu, 20 Feb 2025 15:29:49 -0500 Subject: [PATCH 04/18] Update SDL3 --- .gitignore | 2 +- demo/sdl3/CMakeLists.txt | 43 +++ demo/{sdl_gpu => sdl3}/cmake/FindSDL3.cmake | 2 +- .../main.c => sdl3/nuklear_sdl3_renderer.c} | 46 +-- .../nuklear_sdl3_renderer.h | 159 +++++---- demo/sdl3_renderer/.gitignore | 2 - demo/sdl3_renderer/CMakeLists.txt | 34 -- demo/sdl3_renderer/cmake/FindSDL3.cmake | 8 - demo/sdl_gpu/.gitignore | 1 - demo/sdl_gpu/CMakeLists.txt | 34 -- demo/sdl_gpu/main.c | 245 -------------- demo/sdl_gpu/nuklear_sdl_gpu.h | 316 ------------------ nuklear.h | 23 +- src/nuklear_buffer.c | 23 +- 14 files changed, 210 insertions(+), 728 deletions(-) create mode 100644 demo/sdl3/CMakeLists.txt rename demo/{sdl_gpu => sdl3}/cmake/FindSDL3.cmake (83%) rename demo/{sdl3_renderer/main.c => sdl3/nuklear_sdl3_renderer.c} (85%) rename demo/{sdl3_renderer => sdl3}/nuklear_sdl3_renderer.h (69%) delete mode 100644 demo/sdl3_renderer/.gitignore delete mode 100644 demo/sdl3_renderer/CMakeLists.txt delete mode 100644 demo/sdl3_renderer/cmake/FindSDL3.cmake delete mode 100644 demo/sdl_gpu/.gitignore delete mode 100644 demo/sdl_gpu/CMakeLists.txt delete mode 100644 demo/sdl_gpu/main.c delete mode 100644 demo/sdl_gpu/nuklear_sdl_gpu.h diff --git a/.gitignore b/.gitignore index 0e8ab097b..7fcedeb5d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ demo/*/*.obj demo/*/bin/* example/bin/* docs/xml -docs/build docs/src doc/doc* doc/* @@ -11,3 +10,4 @@ doc/* *.swo *.swp /private/ +build diff --git a/demo/sdl3/CMakeLists.txt b/demo/sdl3/CMakeLists.txt new file mode 100644 index 000000000..b4cb02085 --- /dev/null +++ b/demo/sdl3/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.16) +project(nuklear_sdl3 + DESCRIPTION "nuklear_sdl3: Nuklear Immediate Mode GUI for SDL3" + HOMEPAGE_URL "https://github.com/Immediate-Mode-UI/Nuklear/" + LANGUAGES C +) + +# nuklear +add_library(nuklear INTERFACE) +target_include_directories(nuklear INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# nuklear_sdl3 +add_library(nuklear_sdl3 INTERFACE) +target_include_directories(nuklear_sdl3 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + +# Options +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + set(NUKLEAR_SDL3_IS_MAIN TRUE) +else() + set(NUKLEAR_SDL3_IS_MAIN FALSE) +endif() +option(NUKLEAR_SDL3_EXAMPLES "Examples" ${NUKLEAR_SDL3_IS_MAIN}) + +if (NUKLEAR_SDL3_EXAMPLES) + # CMAKE Modules + set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + + find_package(SDL3 REQUIRED) + + # nuklear_sdl3_renderer + add_executable(nuklear_sdl3_renderer + nuklear_sdl3_renderer.c + ) + target_link_libraries(nuklear_sdl3_renderer PUBLIC + nuklear + nuklear_sdl3 + SDL3::SDL3 + m # TODO: Remove the math dependency and use nk_floor() + ) + + # on Visual Studio, set our app as the default project + set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT "nuklear_sdl3_renderer") +endif() diff --git a/demo/sdl_gpu/cmake/FindSDL3.cmake b/demo/sdl3/cmake/FindSDL3.cmake similarity index 83% rename from demo/sdl_gpu/cmake/FindSDL3.cmake rename to demo/sdl3/cmake/FindSDL3.cmake index d6d8f9a27..0dc55273f 100644 --- a/demo/sdl_gpu/cmake/FindSDL3.cmake +++ b/demo/sdl3/cmake/FindSDL3.cmake @@ -2,7 +2,7 @@ include(FetchContent) FetchContent_Declare( SDL3 GIT_REPOSITORY https://github.com/libsdl-org/SDL.git - GIT_TAG release-3.2.2 + GIT_TAG release-3.2.4 GIT_SHALLOW TRUE ) FetchContent_MakeAvailable(SDL3) diff --git a/demo/sdl3_renderer/main.c b/demo/sdl3/nuklear_sdl3_renderer.c similarity index 85% rename from demo/sdl3_renderer/main.c rename to demo/sdl3/nuklear_sdl3_renderer.c index dbfa7a4e3..8cf096ced 100644 --- a/demo/sdl3_renderer/main.c +++ b/demo/sdl3/nuklear_sdl3_renderer.c @@ -16,6 +16,9 @@ #define NK_IMPLEMENTATION #define NK_SDL3_RENDERER_IMPLEMENTATION #define NK_INCLUDE_STANDARD_BOOL +#define NK_INCLUDE_COMMAND_USERDATA +#define NK_MFREE(userdata, ptr) SDL_free(ptr) +#define NK_MALLOC(userdata, old, size) SDL_malloc(size) #include "nuklear.h" #include "nuklear_sdl3_renderer.h" @@ -37,7 +40,7 @@ /*#define INCLUDE_CONFIGURATOR */ /*#define INCLUDE_NODE_EDITOR */ -#define INCLUDE_ALL +/*#define INCLUDE_ALL*/ #ifdef INCLUDE_ALL #define INCLUDE_STYLE @@ -60,11 +63,9 @@ #ifdef INCLUDE_OVERVIEW #include "../../demo/common/overview.c" #endif -/* #ifdef INCLUDE_CONFIGURATOR #include "../../demo/common/style_configurator.c" #endif -*/ #ifdef INCLUDE_NODE_EDITOR #include "../../demo/common/node_editor.c" #endif @@ -78,11 +79,10 @@ typedef struct AppContext { SDL_Window* window; SDL_Renderer* renderer; + struct nk_context * ctx; + struct nk_colorf bg; } AppContext; -struct nk_context * ctx; -struct nk_colorf bg; - SDL_AppResult SDL_Fail(){ SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "Error %s", SDL_GetError()); return SDL_APP_FAILURE; @@ -105,7 +105,10 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { SDL_StartTextInput(appContext->window); - bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f; + appContext->bg.r = 0.10f; + appContext->bg.g = 0.18f; + appContext->bg.b = 0.24f; + appContext->bg.a = 1.0f; *appstate = appContext; @@ -123,7 +126,8 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { font_scale = scale_y; } - ctx = nk_sdl_init(appContext->window, appContext->renderer); + struct nk_context* ctx = nk_sdl_init(appContext->window, appContext->renderer); + appContext->ctx = ctx; { struct nk_font_atlas *atlas; @@ -132,7 +136,7 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { /* set up the font atlas and add desired font; note that font sizes are * multiplied by font_scale to produce better results at higher DPIs */ - nk_sdl_font_stash_begin(&atlas); + atlas = nk_sdl_font_stash_begin(ctx); font = nk_font_atlas_add_default(atlas, 13 * font_scale, &config); /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14 * font_scale, &config);*/ /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 16 * font_scale, &config);*/ @@ -140,7 +144,7 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12 * font_scale, &config);*/ /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10 * font_scale, &config);*/ /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13 * font_scale, &config);*/ - nk_sdl_font_stash_end(); + nk_sdl_font_stash_end(ctx); /* this hack makes the font appear to be scaled down to the desired * size and is only necessary when font_scale > 1 */ @@ -160,14 +164,15 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event* event) { return SDL_APP_SUCCESS; } - nk_sdl_handle_event(event); + nk_sdl_handle_event(app->ctx, event); return SDL_APP_CONTINUE; } SDL_AppResult SDL_AppIterate(void *appstate) { - nk_input_end(ctx); AppContext* app = (AppContext*)appstate; + struct nk_context* ctx = app->ctx; + nk_input_end(ctx); /* GUI */ if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250), @@ -190,14 +195,14 @@ SDL_AppResult SDL_AppIterate(void *appstate) { 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))) { + if (nk_combo_begin_color(ctx, nk_rgb_cf(app->bg), nk_vec2(nk_widget_width(ctx),400))) { nk_layout_row_dynamic(ctx, 120, 1); - bg = nk_color_picker(ctx, bg, NK_RGBA); + app->bg = nk_color_picker(ctx, app->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); + app->bg.r = nk_propertyf(ctx, "#R:", 0, app->bg.r, 1.0f, 0.01f,0.005f); + app->bg.g = nk_propertyf(ctx, "#G:", 0, app->bg.g, 1.0f, 0.01f,0.005f); + app->bg.b = nk_propertyf(ctx, "#B:", 0, app->bg.b, 1.0f, 0.01f,0.005f); + app->bg.a = nk_propertyf(ctx, "#A:", 0, app->bg.a, 1.0f, 0.01f,0.005f); nk_combo_end(ctx); } } @@ -208,7 +213,7 @@ SDL_AppResult SDL_AppIterate(void *appstate) { calculator(ctx); #endif #ifdef INCLUDE_CANVAS - canvas(ctx); + canvas(ctx); #endif #ifdef INCLUDE_OVERVIEW overview(ctx); @@ -224,7 +229,7 @@ SDL_AppResult SDL_AppIterate(void *appstate) { SDL_SetRenderDrawColor(app->renderer, 255, 0, 255, SDL_ALPHA_OPAQUE); SDL_RenderClear(app->renderer); - nk_sdl_render(NK_ANTI_ALIASING_ON); + nk_sdl_render(ctx, NK_ANTI_ALIASING_ON); SDL_RenderPresent(app->renderer); @@ -236,6 +241,7 @@ void SDL_AppQuit(void* appstate, SDL_AppResult result) { AppContext* app = (AppContext*)appstate; if (app) { + nk_sdl_shutdown(app->ctx); SDL_DestroyRenderer(app->renderer); SDL_DestroyWindow(app->window); SDL_free(app); diff --git a/demo/sdl3_renderer/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h similarity index 69% rename from demo/sdl3_renderer/nuklear_sdl3_renderer.h rename to demo/sdl3/nuklear_sdl3_renderer.h index 12950af69..68e28882a 100644 --- a/demo/sdl3_renderer/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -8,21 +8,24 @@ * * =============================================================== */ + #ifndef NK_SDL3_RENDERER_H_ #define NK_SDL3_RENDERER_H_ -NK_API struct nk_context* nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer); -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); - #if SDL_MAJOR_VERSION < 3 #error "nuklear_sdl3_renderer requires at least SDL 3.0.0" #endif -#endif /* NK_SDL_RENDERER_H_ */ +NK_API struct nk_context* nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer); +NK_API struct nk_font_atlas* nk_sdl_font_stash_begin(struct nk_context* ctx); +NK_API void nk_sdl_font_stash_end(struct nk_context* ctx); +NK_API int nk_sdl_handle_event(struct nk_context* ctx, SDL_Event *evt); +NK_API void nk_sdl_render(struct nk_context* ctx, enum nk_anti_aliasing); +NK_API void nk_sdl_shutdown(struct nk_context* ctx); +NK_API nk_handle nk_sdl_userdata(struct nk_context* ctx); +NK_API void nk_sdl_set_userdata(struct nk_context* ctx, nk_handle userdata); + +#endif /* NK_SDL3_RENDERER_H_ */ /* * ============================================================== @@ -33,6 +36,10 @@ NK_API void nk_sdl_shutdown(void); */ #ifdef NK_SDL3_RENDERER_IMPLEMENTATION +#ifndef NK_INCLUDE_COMMAND_USERDATA +#error "nuklear_sdl3 requires the NK_INCLUDE_COMMAND_USERDATA define" +#endif + struct nk_sdl_device { struct nk_buffer cmds; struct nk_draw_null_texture tex_null; @@ -45,34 +52,44 @@ struct nk_sdl_vertex { float col[4]; }; -static struct nk_sdl { +struct nk_sdl { SDL_Window *win; SDL_Renderer *renderer; struct nk_sdl_device ogl; struct nk_context ctx; struct nk_font_atlas atlas; -} sdl; + nk_handle userdata; +}; + +NK_API nk_handle nk_sdl_userdata(struct nk_context* ctx) { + struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; + return sdl->userdata; +} + +NK_API void nk_sdl_set_userdata(struct nk_context* ctx, nk_handle userdata) { + struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; + sdl->userdata = userdata; +} NK_INTERN void -nk_sdl_device_upload_atlas(const void *image, int width, int height) +nk_sdl_device_upload_atlas(struct nk_context* ctx, const void *image, int width, int height) { - struct nk_sdl_device *dev = &sdl.ogl; - - SDL_Texture *g_SDLFontTexture = SDL_CreateTexture(sdl.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); + struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; + SDL_Texture *g_SDLFontTexture = SDL_CreateTexture(sdl->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); if (g_SDLFontTexture == NULL) { SDL_Log("error creating texture"); return; } SDL_UpdateTexture(g_SDLFontTexture, NULL, image, 4 * width); SDL_SetTextureBlendMode(g_SDLFontTexture, SDL_BLENDMODE_BLEND); - dev->font_tex = g_SDLFontTexture; + sdl->ogl.font_tex = g_SDLFontTexture; } NK_API void -nk_sdl_render(enum nk_anti_aliasing AA) +nk_sdl_render(struct nk_context* ctx, enum nk_anti_aliasing AA) { /* setup global state */ - struct nk_sdl_device *dev = &sdl.ogl; + struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; { SDL_Rect saved_clip; @@ -99,7 +116,7 @@ nk_sdl_render(enum nk_anti_aliasing AA) 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.tex_null = sdl->ogl.tex_null; config.circle_segment_count = 22; config.curve_segment_count = 22; config.arc_segment_count = 22; @@ -110,15 +127,15 @@ nk_sdl_render(enum nk_anti_aliasing AA) /* convert shapes into vertexes */ nk_buffer_init_default(&vbuf); nk_buffer_init_default(&ebuf); - nk_convert(&sdl.ctx, &dev->cmds, &vbuf, &ebuf, &config); + nk_convert(&sdl->ctx, &sdl->ogl.cmds, &vbuf, &ebuf, &config); /* iterate over and execute each draw command */ offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf); - clipping_enabled = SDL_RenderClipEnabled(sdl.renderer); - SDL_GetRenderClipRect(sdl.renderer, &saved_clip); + clipping_enabled = SDL_RenderClipEnabled(sdl->renderer); + SDL_GetRenderClipRect(sdl->renderer, &saved_clip); - nk_draw_foreach(cmd, &sdl.ctx, &dev->cmds) + nk_draw_foreach(cmd, &sdl->ctx, &sdl->ogl.cmds) { if (!cmd->elem_count) continue; @@ -128,13 +145,13 @@ nk_sdl_render(enum nk_anti_aliasing AA) r.y = cmd->clip_rect.y; r.w = cmd->clip_rect.w; r.h = cmd->clip_rect.h; - SDL_SetRenderClipRect(sdl.renderer, &r); + SDL_SetRenderClipRect(sdl->renderer, &r); } { const void *vertices = nk_buffer_memory_const(&vbuf); - SDL_RenderGeometryRaw(sdl.renderer, + SDL_RenderGeometryRaw(sdl->renderer, (SDL_Texture *)cmd->texture.ptr, (const float*)((const nk_byte*)vertices + vp), vs, (const SDL_FColor*)((const nk_byte*)vertices + vc), vs, @@ -146,13 +163,13 @@ nk_sdl_render(enum nk_anti_aliasing AA) } } - SDL_SetRenderClipRect(sdl.renderer, &saved_clip); + SDL_SetRenderClipRect(sdl->renderer, &saved_clip); if (!clipping_enabled) { - SDL_SetRenderClipRect(sdl.renderer, NULL); + SDL_SetRenderClipRect(sdl->renderer, NULL); } - nk_clear(&sdl.ctx); - nk_buffer_clear(&dev->cmds); + nk_clear(&sdl->ctx); + nk_buffer_clear(&sdl->ogl.cmds); nk_buffer_free(&vbuf); nk_buffer_free(&ebuf); } @@ -162,7 +179,10 @@ 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)); + if (text) { + nk_textedit_paste(edit, text, nk_strlen(text)); + SDL_free((void *)text); + } (void)usr; } @@ -172,50 +192,58 @@ 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); + str = (char*)SDL_malloc((size_t)len+1); if (!str) return; - memcpy(str, text, (size_t)len); + SDL_memcpy(str, text, (size_t)len); str[len] = '\0'; SDL_SetClipboardText(str); - free(str); + SDL_free((void*)str); } NK_API struct nk_context* nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer) { - sdl.win = win; - sdl.renderer = renderer; - 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); - return &sdl.ctx; + struct nk_sdl* sdl = SDL_malloc(sizeof(struct nk_sdl)); + NK_ASSERT(sdl); + sdl->win = win; + sdl->renderer = renderer; + nk_init_default(&sdl->ctx, 0); + sdl->ctx.userdata = nk_handle_ptr((void*)sdl); + 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); + return &sdl->ctx; } -NK_API void -nk_sdl_font_stash_begin(struct nk_font_atlas **atlas) +NK_API struct nk_font_atlas* +nk_sdl_font_stash_begin(struct nk_context* ctx) { - nk_font_atlas_init_default(&sdl.atlas); - nk_font_atlas_begin(&sdl.atlas); - *atlas = &sdl.atlas; + struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; + nk_font_atlas_init_default(&sdl->atlas); + nk_font_atlas_begin(&sdl->atlas); + return &sdl->atlas; } NK_API void -nk_sdl_font_stash_end(void) +nk_sdl_font_stash_end(struct nk_context* ctx) { + struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; 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_ptr(sdl.ogl.font_tex), &sdl.ogl.tex_null); - if (sdl.atlas.default_font) - nk_style_set_font(&sdl.ctx, &sdl.atlas.default_font->handle); + image = nk_font_atlas_bake(&sdl->atlas, &w, &h, NK_FONT_ATLAS_RGBA32); + nk_sdl_device_upload_atlas(&sdl->ctx, image, w, h); + nk_font_atlas_end(&sdl->atlas, nk_handle_ptr(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 int -nk_sdl_handle_event(SDL_Event *evt) +nk_sdl_handle_event(struct nk_context* ctx, SDL_Event *evt) { - struct nk_context *ctx = &sdl.ctx; + if (ctx == NULL) { + return 0; + } switch(evt->type) { @@ -289,7 +317,7 @@ nk_sdl_handle_event(SDL_Event *evt) case SDL_EVENT_TEXT_INPUT: { nk_glyph glyph; - memcpy(glyph, evt->text.text, NK_UTF_SIZE); + SDL_memcpy(glyph, evt->text.text, NK_UTF_SIZE); nk_input_glyph(ctx, glyph); } return 1; @@ -302,15 +330,22 @@ nk_sdl_handle_event(SDL_Event *evt) } NK_API -void nk_sdl_shutdown(void) +void nk_sdl_shutdown(struct nk_context* ctx) { - struct nk_sdl_device *dev = &sdl.ogl; - nk_font_atlas_clear(&sdl.atlas); - nk_free(&sdl.ctx); - SDL_DestroyTexture(dev->font_tex); - /* glDeleteTextures(1, &dev->font_tex); */ - nk_buffer_free(&dev->cmds); - memset(&sdl, 0, sizeof(sdl)); + struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; + + nk_font_atlas_clear(&sdl->atlas); + nk_buffer_free(&sdl->ogl.cmds); + + if (sdl->ogl.font_tex != NULL) { + SDL_DestroyTexture(sdl->ogl.font_tex); + sdl->ogl.font_tex = NULL; + } + + ctx->userdata = nk_handle_ptr(0); + SDL_free(sdl); + nk_free(ctx); + /* TODO: Need to call SDL_free(ctx)? */ } #endif /* NK_SDL3_RENDERER_IMPLEMENTATION */ diff --git a/demo/sdl3_renderer/.gitignore b/demo/sdl3_renderer/.gitignore deleted file mode 100644 index db3341788..000000000 --- a/demo/sdl3_renderer/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -SDL -build diff --git a/demo/sdl3_renderer/CMakeLists.txt b/demo/sdl3_renderer/CMakeLists.txt deleted file mode 100644 index 75b6effbd..000000000 --- a/demo/sdl3_renderer/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$") -set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE INTERNAL "") - -# CMAKE Modules -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - -project(nuklear_sdl3_renderer) - -set(EXECUTABLE_NAME ${PROJECT_NAME}) - -# The SDL java code is hardcoded to load libmain.so on android, so we need to change EXECUTABLE_NAME -if (ANDROID) - set(EXECUTABLE_NAME main) - add_library(${EXECUTABLE_NAME} SHARED) -else() - add_executable(${EXECUTABLE_NAME}) -endif() - -# Add your sources to the target -target_sources(${EXECUTABLE_NAME} PRIVATE main.c) - -find_package(SDL3 REQUIRED) - -# TODO: remove libm and fallback on Nuklear floor() -target_link_libraries(${EXECUTABLE_NAME} PUBLIC SDL3::SDL3 m) - -# Nuklear Include Directory -target_include_directories(${EXECUTABLE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../..) - -# on Visual Studio, set our app as the default project -set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT "${EXECUTABLE_NAME}") diff --git a/demo/sdl3_renderer/cmake/FindSDL3.cmake b/demo/sdl3_renderer/cmake/FindSDL3.cmake deleted file mode 100644 index d6d8f9a27..000000000 --- a/demo/sdl3_renderer/cmake/FindSDL3.cmake +++ /dev/null @@ -1,8 +0,0 @@ -include(FetchContent) -FetchContent_Declare( - SDL3 - GIT_REPOSITORY https://github.com/libsdl-org/SDL.git - GIT_TAG release-3.2.2 - GIT_SHALLOW TRUE -) -FetchContent_MakeAvailable(SDL3) diff --git a/demo/sdl_gpu/.gitignore b/demo/sdl_gpu/.gitignore deleted file mode 100644 index 378eac25d..000000000 --- a/demo/sdl_gpu/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build diff --git a/demo/sdl_gpu/CMakeLists.txt b/demo/sdl_gpu/CMakeLists.txt deleted file mode 100644 index 6e331fe4a..000000000 --- a/demo/sdl_gpu/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$") -set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE INTERNAL "") - -# CMAKE Modules -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - -project(nuklear_sdl_gpu) - -set(EXECUTABLE_NAME ${PROJECT_NAME}) - -# The SDL java code is hardcoded to load libmain.so on android, so we need to change EXECUTABLE_NAME -if (ANDROID) - set(EXECUTABLE_NAME main) - add_library(${EXECUTABLE_NAME} SHARED) -else() - add_executable(${EXECUTABLE_NAME}) -endif() - -# Add your sources to the target -target_sources(${EXECUTABLE_NAME} PRIVATE main.c) - -find_package(SDL3 REQUIRED) - -# TODO: remove libm and fallback on Nuklear floor() -target_link_libraries(${EXECUTABLE_NAME} PUBLIC SDL3::SDL3 m) - -# Nuklear Include Directory -target_include_directories(${EXECUTABLE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../..) - -# on Visual Studio, set our app as the default project -set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT "${EXECUTABLE_NAME}") diff --git a/demo/sdl_gpu/main.c b/demo/sdl_gpu/main.c deleted file mode 100644 index 6a307efb9..000000000 --- a/demo/sdl_gpu/main.c +++ /dev/null @@ -1,245 +0,0 @@ -/* nuklear - public domain */ -#include -#include /* offsetof TODO: sdl2_renderer didn't need this header? */ - -#define SDL_MAIN_USE_CALLBACKS -#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_SDL_GPU_IMPLEMENTATION -#define NK_INCLUDE_STANDARD_BOOL -#include "nuklear.h" -#include "nuklear_sdl_gpu.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_CONFIGURATOR */ -/*#define INCLUDE_NODE_EDITOR */ - -#define INCLUDE_ALL - -#ifdef INCLUDE_ALL - #define INCLUDE_STYLE - #define INCLUDE_CALCULATOR - #define INCLUDE_CANVAS - #define INCLUDE_OVERVIEW - /* #define INCLUDE_CONFIGURATOR */ - #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_CONFIGURATOR - #include "../../demo/common/style_configurator.c" -#endif -*/ -#ifdef INCLUDE_NODE_EDITOR - #include "../../demo/common/node_editor.c" -#endif - -/* =============================================================== - * - * DEMO - * - * ===============================================================*/ - -typedef struct AppContext { - SDL_Window* window; - SDL_Renderer* renderer; -} AppContext; - -struct nk_context * ctx; -struct nk_colorf bg; - -SDL_AppResult SDL_Fail(){ - SDL_LogError(SDL_LOG_CATEGORY_CUSTOM, "Error %s", SDL_GetError()); - return SDL_APP_FAILURE; -} - -SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { - if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) { - return SDL_Fail(); - } - - AppContext* appContext = (AppContext*)SDL_malloc(sizeof(AppContext)); - if (appContext == NULL) { - return SDL_Fail(); - } - - if (!SDL_CreateWindowAndRenderer("Nuklear: SDL3 GPU", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &appContext->window, &appContext->renderer)) { - SDL_free(appContext); - return SDL_Fail(); - } - - SDL_StartTextInput(appContext->window); - - bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f; - - *appstate = appContext; - - float font_scale = 1; - - { - int render_w, render_h; - int window_w, window_h; - float scale_x, scale_y; - SDL_GetCurrentRenderOutputSize(appContext->renderer, &render_w, &render_h); - SDL_GetWindowSize(appContext->window, &window_w, &window_h); - scale_x = (float)(render_w) / (float)(window_w); - scale_y = (float)(render_h) / (float)(window_h); - SDL_SetRenderScale(appContext->renderer, scale_x, scale_y); - font_scale = scale_y; - } - - ctx = nk_sdl_init(appContext->window, appContext->renderer); - - { - struct nk_font_atlas *atlas; - struct nk_font_config config = nk_font_config(0); - struct nk_font *font; - - /* set up the font atlas and add desired font; note that font sizes are - * multiplied by font_scale to produce better results at higher DPIs */ - nk_sdl_font_stash_begin(&atlas); - font = nk_font_atlas_add_default(atlas, 13 * font_scale, &config); - /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14 * font_scale, &config);*/ - /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 16 * font_scale, &config);*/ - /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13 * font_scale, &config);*/ - /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12 * font_scale, &config);*/ - /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10 * font_scale, &config);*/ - /*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13 * font_scale, &config);*/ - nk_sdl_font_stash_end(); - - /* this hack makes the font appear to be scaled down to the desired - * size and is only necessary when font_scale > 1 */ - font->handle.height /= font_scale; - /*nk_style_load_all_cursors(ctx, atlas->cursors);*/ - nk_style_set_font(ctx, &font->handle); - } - - return SDL_APP_CONTINUE; -} - -SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event* event) { - AppContext* app = (AppContext*)appstate; - - switch (event->type) { - case SDL_EVENT_QUIT: - return SDL_APP_SUCCESS; - } - - nk_sdl_handle_event(event); - - return SDL_APP_CONTINUE; -} - -SDL_AppResult SDL_AppIterate(void *appstate) { - nk_input_end(ctx); - AppContext* app = (AppContext*)appstate; - - /* 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, 25, 1); - nk_property_int(ctx, "Compression:", 0, &property, 1000, 1, 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_CONFIGURATOR - style_configurator(ctx, color_table); - #endif - #ifdef INCLUDE_NODE_EDITOR - node_editor(ctx); - #endif - /* ----------------------------------------- */ - - SDL_SetRenderDrawColor(app->renderer, 255, 0, 255, SDL_ALPHA_OPAQUE); - SDL_RenderClear(app->renderer); - - nk_sdl_render(NK_ANTI_ALIASING_ON); - - SDL_RenderPresent(app->renderer); - - nk_input_begin(ctx); - return SDL_APP_CONTINUE; -} - -void SDL_AppQuit(void* appstate, SDL_AppResult result) { - AppContext* app = (AppContext*)appstate; - - if (app) { - SDL_DestroyRenderer(app->renderer); - SDL_DestroyWindow(app->window); - SDL_free(app); - } - - SDL_Quit(); -} diff --git a/demo/sdl_gpu/nuklear_sdl_gpu.h b/demo/sdl_gpu/nuklear_sdl_gpu.h deleted file mode 100644 index df347a580..000000000 --- a/demo/sdl_gpu/nuklear_sdl_gpu.h +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Nuklear - 4.9.4 - public domain - */ -/* - * ============================================================== - * - * API - * - * =============================================================== - */ -#ifndef NK_SDL_GPU_H_ -#define NK_SDL_GPU_H_ - -NK_API struct nk_context* nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer); -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); - -#if SDL_MAJOR_VERSION < 3 -#error "nuklear_sdl_gpu requires at least SDL 3.0.0" -#endif - -#endif /* NK_SDL_GPU_H_ */ - -/* - * ============================================================== - * - * IMPLEMENTATION - * - * =============================================================== - */ -#ifdef NK_SDL_GPU_IMPLEMENTATION - -struct nk_sdl_device { - struct nk_buffer cmds; - struct nk_draw_null_texture tex_null; - SDL_Texture *font_tex; -}; - -struct nk_sdl_vertex { - float position[2]; - float uv[2]; - float col[4]; -}; - -static struct nk_sdl { - SDL_Window *win; - SDL_Renderer *renderer; - 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; - - SDL_Texture *g_SDLFontTexture = SDL_CreateTexture(sdl.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); - if (g_SDLFontTexture == NULL) { - SDL_Log("error creating texture"); - return; - } - SDL_UpdateTexture(g_SDLFontTexture, NULL, image, 4 * width); - SDL_SetTextureBlendMode(g_SDLFontTexture, SDL_BLENDMODE_BLEND); - dev->font_tex = g_SDLFontTexture; -} - -NK_API void -nk_sdl_render(enum nk_anti_aliasing AA) -{ - /* setup global state */ - struct nk_sdl_device *dev = &sdl.ogl; - - { - SDL_Rect saved_clip; - bool clipping_enabled; - int 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_R32G32B32A32_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, col)}, - {NK_VERTEX_LAYOUT_END} - }; - NK_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); - - /* iterate over and execute each draw command */ - offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf); - - clipping_enabled = SDL_RenderClipEnabled(sdl.renderer); - SDL_GetRenderClipRect(sdl.renderer, &saved_clip); - - nk_draw_foreach(cmd, &sdl.ctx, &dev->cmds) - { - if (!cmd->elem_count) continue; - - { - SDL_Rect r; - r.x = cmd->clip_rect.x; - r.y = cmd->clip_rect.y; - r.w = cmd->clip_rect.w; - r.h = cmd->clip_rect.h; - SDL_SetRenderClipRect(sdl.renderer, &r); - } - - { - const void *vertices = nk_buffer_memory_const(&vbuf); - - SDL_RenderGeometryRaw(sdl.renderer, - (SDL_Texture *)cmd->texture.ptr, - (const float*)((const nk_byte*)vertices + vp), vs, - (const SDL_FColor*)((const nk_byte*)vertices + vc), vs, - (const float*)((const nk_byte*)vertices + vt), vs, - (vbuf.needed / vs), - (void *) offset, cmd->elem_count, 2); - - offset += cmd->elem_count; - } - } - - SDL_SetRenderClipRect(sdl.renderer, &saved_clip); - if (!clipping_enabled) { - SDL_SetRenderClipRect(sdl.renderer, NULL); - } - - nk_clear(&sdl.ctx); - nk_buffer_clear(&dev->cmds); - nk_buffer_free(&vbuf); - nk_buffer_free(&ebuf); - } -} - -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_Renderer *renderer) -{ - sdl.win = win; - sdl.renderer = renderer; - 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); - 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_ptr(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 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->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); - SDL_DestroyTexture(dev->font_tex); - /* glDeleteTextures(1, &dev->font_tex); */ - nk_buffer_free(&dev->cmds); - memset(&sdl, 0, sizeof(sdl)); -} - -#endif /* NK_SDL_GPU_IMPLEMENTATION */ diff --git a/nuklear.h b/nuklear.h index 8581bbc0a..ff5ea0770 100644 --- a/nuklear.h +++ b/nuklear.h @@ -8487,18 +8487,37 @@ nk_utf_at(const char *buffer, int length, int index, * * ===============================================================*/ #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR + +/** + * Allows overriding which malloc() function is used in nk_malloc(). + * + * @see nk_malloc() + */ +#ifndef NK_MALLOC +#define NK_MALLOC(userdata, old, size) malloc(size) +#endif + +/** + * Allows overriding which free() function is used in nk_mfree(). + * + * @see nk_mfree() + */ +#ifndef NK_MFREE +#define NK_MFREE(userdata, ptr) free(ptr) +#endif + NK_LIB void* nk_malloc(nk_handle unused, void *old,nk_size size) { NK_UNUSED(unused); NK_UNUSED(old); - return malloc(size); + return NK_MALLOC(unused, old, size); } NK_LIB void nk_mfree(nk_handle unused, void *ptr) { NK_UNUSED(unused); - free(ptr); + NK_MFREE(unused, ptr); } NK_API void nk_buffer_init_default(struct nk_buffer *buffer) diff --git a/src/nuklear_buffer.c b/src/nuklear_buffer.c index e3e9b0f26..440917930 100644 --- a/src/nuklear_buffer.c +++ b/src/nuklear_buffer.c @@ -7,18 +7,37 @@ * * ===============================================================*/ #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR + +/** + * Allows overriding which malloc() function is used in nk_malloc(). + * + * @see nk_malloc() + */ +#ifndef NK_MALLOC +#define NK_MALLOC(userdata, old, size) malloc(size) +#endif + +/** + * Allows overriding which free() function is used in nk_mfree(). + * + * @see nk_mfree() + */ +#ifndef NK_MFREE +#define NK_MFREE(userdata, ptr) free(ptr) +#endif + NK_LIB void* nk_malloc(nk_handle unused, void *old,nk_size size) { NK_UNUSED(unused); NK_UNUSED(old); - return malloc(size); + return NK_MALLOC(unused, old, size); } NK_LIB void nk_mfree(nk_handle unused, void *ptr) { NK_UNUSED(unused); - free(ptr); + NK_MFREE(unused, ptr); } NK_API void nk_buffer_init_default(struct nk_buffer *buffer) From 299fe6a73dd476211a84c3c5ac24b2f350e2673d Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Fri, 21 Feb 2025 13:24:14 -0500 Subject: [PATCH 05/18] Update demo/sdl3/nuklear_sdl3_renderer.h --- demo/sdl3/nuklear_sdl3_renderer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index 68e28882a..5a8c5897c 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -345,7 +345,6 @@ void nk_sdl_shutdown(struct nk_context* ctx) ctx->userdata = nk_handle_ptr(0); SDL_free(sdl); nk_free(ctx); - /* TODO: Need to call SDL_free(ctx)? */ } #endif /* NK_SDL3_RENDERER_IMPLEMENTATION */ From 996ef5f76f57c4191ce2a61cbb8150c27d247222 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Fri, 21 Feb 2025 16:09:50 -0500 Subject: [PATCH 06/18] sdl3: Use SDL/Nuklear solutions for functions --- demo/sdl3/nuklear_sdl3_renderer.c | 7 +++---- demo/sdl3/nuklear_sdl3_renderer.h | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/demo/sdl3/nuklear_sdl3_renderer.c b/demo/sdl3/nuklear_sdl3_renderer.c index 8cf096ced..2b46252ea 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.c +++ b/demo/sdl3/nuklear_sdl3_renderer.c @@ -1,6 +1,4 @@ /* nuklear - public domain */ -#include -#include /* offsetof TODO: sdl2_renderer didn't need this header? */ #define SDL_MAIN_USE_CALLBACKS #include @@ -184,8 +182,9 @@ SDL_AppResult SDL_AppIterate(void *appstate) { static int property = 20; nk_layout_row_static(ctx, 30, 80, 1); - if (nk_button_label(ctx, "button")) - printf("button pressed\n"); + if (nk_button_label(ctx, "button")) { + SDL_Log("button pressed"); + } 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; diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index 5a8c5897c..f0c2d99bd 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -95,9 +95,9 @@ nk_sdl_render(struct nk_context* ctx, enum nk_anti_aliasing AA) SDL_Rect saved_clip; bool clipping_enabled; int 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); + size_t vp = NK_OFFSETOF(struct nk_sdl_vertex, position); + size_t vt = NK_OFFSETOF(struct nk_sdl_vertex, uv); + size_t vc = NK_OFFSETOF(struct nk_sdl_vertex, col); /* convert from command queue into draw list and draw to screen */ const struct nk_draw_command *cmd; From 95bd684b6fa732ab5ea76f806b448fa0720d1f44 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Fri, 21 Feb 2025 16:33:09 -0500 Subject: [PATCH 07/18] sdl3: Sanitize inputs --- demo/sdl3/nuklear_sdl3_renderer.h | 38 ++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index f0c2d99bd..8bc076e9a 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -62,19 +62,25 @@ struct nk_sdl { }; NK_API nk_handle nk_sdl_userdata(struct nk_context* ctx) { - struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; + struct nk_sdl* sdl; + NK_ASSERT(ctx); + sdl = (struct nk_sdl*)ctx->userdata.ptr; return sdl->userdata; } NK_API void nk_sdl_set_userdata(struct nk_context* ctx, nk_handle userdata) { - struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; + struct nk_sdl* sdl; + NK_ASSERT(ctx); + sdl = (struct nk_sdl*)ctx->userdata.ptr; sdl->userdata = userdata; } NK_INTERN void nk_sdl_device_upload_atlas(struct nk_context* ctx, const void *image, int width, int height) { - struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; + struct nk_sdl* sdl; + NK_ASSERT(ctx); + sdl = (struct nk_sdl*)ctx->userdata.ptr; SDL_Texture *g_SDLFontTexture = SDL_CreateTexture(sdl->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); if (g_SDLFontTexture == NULL) { SDL_Log("error creating texture"); @@ -89,7 +95,9 @@ NK_API void nk_sdl_render(struct nk_context* ctx, enum nk_anti_aliasing AA) { /* setup global state */ - struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; + struct nk_sdl* sdl; + NK_ASSERT(ctx); + sdl = (struct nk_sdl*)ctx->userdata.ptr; { SDL_Rect saved_clip; @@ -203,7 +211,10 @@ nk_sdl_clipboard_copy(nk_handle usr, const char *text, int len) NK_API struct nk_context* nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer) { - struct nk_sdl* sdl = SDL_malloc(sizeof(struct nk_sdl)); + struct nk_sdl* sdl; + NK_ASSERT(win); + NK_ASSERT(renderer); + sdl = SDL_malloc(sizeof(struct nk_sdl)); NK_ASSERT(sdl); sdl->win = win; sdl->renderer = renderer; @@ -219,7 +230,9 @@ nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer) NK_API struct nk_font_atlas* nk_sdl_font_stash_begin(struct nk_context* ctx) { - struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; + struct nk_sdl* sdl; + NK_ASSERT(ctx); + sdl = (struct nk_sdl*)ctx->userdata.ptr; nk_font_atlas_init_default(&sdl->atlas); nk_font_atlas_begin(&sdl->atlas); return &sdl->atlas; @@ -228,8 +241,10 @@ nk_sdl_font_stash_begin(struct nk_context* ctx) NK_API void nk_sdl_font_stash_end(struct nk_context* ctx) { - struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; + struct nk_sdl* sdl; const void *image; int w, h; + NK_ASSERT(ctx); + sdl = (struct nk_sdl*)ctx->userdata.ptr; image = nk_font_atlas_bake(&sdl->atlas, &w, &h, NK_FONT_ATLAS_RGBA32); nk_sdl_device_upload_atlas(&sdl->ctx, image, w, h); nk_font_atlas_end(&sdl->atlas, nk_handle_ptr(sdl->ogl.font_tex), &sdl->ogl.tex_null); @@ -241,9 +256,8 @@ nk_sdl_font_stash_end(struct nk_context* ctx) NK_API int nk_sdl_handle_event(struct nk_context* ctx, SDL_Event *evt) { - if (ctx == NULL) { - return 0; - } + NK_ASSERT(ctx); + NK_ASSERT(evt); switch(evt->type) { @@ -332,7 +346,9 @@ nk_sdl_handle_event(struct nk_context* ctx, SDL_Event *evt) NK_API void nk_sdl_shutdown(struct nk_context* ctx) { - struct nk_sdl* sdl = (struct nk_sdl*)ctx->userdata.ptr; + struct nk_sdl* sdl; + NK_ASSERT(ctx); + sdl = (struct nk_sdl*)ctx->userdata.ptr; nk_font_atlas_clear(&sdl->atlas); nk_buffer_free(&sdl->ogl.cmds); From fccae923a6095fa3f9ffb22af8352f9c68505872 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Fri, 21 Feb 2025 16:53:05 -0500 Subject: [PATCH 08/18] sdl3: Update mouse motion to use SDL3's floats --- demo/sdl3/nuklear_sdl3_renderer.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index 8bc076e9a..73e4e8c17 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -321,11 +321,11 @@ nk_sdl_handle_event(struct nk_context* ctx, SDL_Event *evt) 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); + ctx->input.mouse.prev = ctx->input.mouse.pos; + ctx->input.mouse.delta.x = evt->motion.xrel; + ctx->input.mouse.delta.y = evt->motion.yrel; + ctx->input.mouse.pos.x = evt->motion.x; + ctx->input.mouse.pos.y = evt->motion.y; return 1; case SDL_EVENT_TEXT_INPUT: From 6dc47298ba41bc38446cd74570d70c50057bffcf Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Fri, 21 Feb 2025 16:55:28 -0500 Subject: [PATCH 09/18] sdl3: Remov casitn of mouse_wheel --- demo/sdl3/nuklear_sdl3_renderer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index 73e4e8c17..4af9821fc 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -337,7 +337,7 @@ nk_sdl_handle_event(struct nk_context* ctx, SDL_Event *evt) return 1; case SDL_EVENT_MOUSE_WHEEL: - nk_input_scroll(ctx,nk_vec2((float)evt->wheel.x,(float)evt->wheel.y)); + nk_input_scroll(ctx, nk_vec2(evt->wheel.x, evt->wheel.y)); return 1; } return 0; From 5967a90de1b33613fb167c87d585212486c90bd3 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Fri, 21 Feb 2025 17:12:35 -0500 Subject: [PATCH 10/18] sdl3: Use SDL_strndup() to copy the string --- demo/sdl3/nuklear_sdl3_renderer.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index 4af9821fc..5e13bcb8d 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -199,11 +199,9 @@ nk_sdl_clipboard_copy(nk_handle usr, const char *text, int len) { char *str = 0; (void)usr; - if (!len) return; - str = (char*)SDL_malloc((size_t)len+1); - if (!str) return; - SDL_memcpy(str, text, (size_t)len); - str[len] = '\0'; + if (len <= 0 || text == NULL) return; + str = SDL_strndup(text, (size_t)len); + if (str == NULL) return; SDL_SetClipboardText(str); SDL_free((void*)str); } From 1305c180304fb2ba70775b0e7f4d3ed291f6f0f5 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Fri, 21 Feb 2025 18:00:32 -0500 Subject: [PATCH 11/18] sdl3: Enable compiler warnings --- demo/sdl3/CMakeLists.txt | 10 ++++++++++ demo/sdl3/nuklear_sdl3_renderer.c | 3 +++ demo/sdl3/nuklear_sdl3_renderer.h | 4 ++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/demo/sdl3/CMakeLists.txt b/demo/sdl3/CMakeLists.txt index b4cb02085..949b4244c 100644 --- a/demo/sdl3/CMakeLists.txt +++ b/demo/sdl3/CMakeLists.txt @@ -40,4 +40,14 @@ if (NUKLEAR_SDL3_EXAMPLES) # on Visual Studio, set our app as the default project set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT "nuklear_sdl3_renderer") + + # Enable Warnings + if(MSVC) + target_compile_options(nuklear_sdl3_renderer PRIVATE /W4 /WX) + else() + target_compile_options(nuklear_sdl3_renderer PRIVATE -Wall -Wextra -Wpedantic -Werror) + endif() + + # SDL3 does not support C89/C90 + set_property(TARGET nuklear_sdl3_renderer PROPERTY C_STANDARD 99) endif() diff --git a/demo/sdl3/nuklear_sdl3_renderer.c b/demo/sdl3/nuklear_sdl3_renderer.c index 2b46252ea..27e3daac8 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.c +++ b/demo/sdl3/nuklear_sdl3_renderer.c @@ -87,6 +87,8 @@ SDL_AppResult SDL_Fail(){ } SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { + NK_UNUSED(argc); + NK_UNUSED(argv); if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) { return SDL_Fail(); } @@ -238,6 +240,7 @@ SDL_AppResult SDL_AppIterate(void *appstate) { void SDL_AppQuit(void* appstate, SDL_AppResult result) { AppContext* app = (AppContext*)appstate; + NK_UNUSED(result); if (app) { nk_sdl_shutdown(app->ctx); diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index 5e13bcb8d..34dc4a46c 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -187,18 +187,18 @@ static void nk_sdl_clipboard_paste(nk_handle usr, struct nk_text_edit *edit) { const char *text = SDL_GetClipboardText(); + NK_UNUSED(usr); if (text) { nk_textedit_paste(edit, text, nk_strlen(text)); SDL_free((void *)text); } - (void)usr; } static void nk_sdl_clipboard_copy(nk_handle usr, const char *text, int len) { char *str = 0; - (void)usr; + NK_UNUSED(usr); if (len <= 0 || text == NULL) return; str = SDL_strndup(text, (size_t)len); if (str == NULL) return; From 1b212ccfceaa8d871ff0bf2a0b5e4331ca805199 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Sat, 22 Feb 2025 12:24:16 -0500 Subject: [PATCH 12/18] sdl3: Add NK_ASSERT(sdl) --- demo/sdl3/nuklear_sdl3_renderer.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index 34dc4a46c..cd15ac1fa 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -65,6 +65,7 @@ NK_API nk_handle nk_sdl_userdata(struct nk_context* ctx) { struct nk_sdl* sdl; NK_ASSERT(ctx); sdl = (struct nk_sdl*)ctx->userdata.ptr; + NK_ASSERT(sdl); return sdl->userdata; } @@ -72,6 +73,7 @@ NK_API void nk_sdl_set_userdata(struct nk_context* ctx, nk_handle userdata) { struct nk_sdl* sdl; NK_ASSERT(ctx); sdl = (struct nk_sdl*)ctx->userdata.ptr; + NK_ASSERT(sdl); sdl->userdata = userdata; } @@ -81,6 +83,7 @@ nk_sdl_device_upload_atlas(struct nk_context* ctx, const void *image, int width, struct nk_sdl* sdl; NK_ASSERT(ctx); sdl = (struct nk_sdl*)ctx->userdata.ptr; + NK_ASSERT(sdl); SDL_Texture *g_SDLFontTexture = SDL_CreateTexture(sdl->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); if (g_SDLFontTexture == NULL) { SDL_Log("error creating texture"); @@ -98,6 +101,7 @@ nk_sdl_render(struct nk_context* ctx, enum nk_anti_aliasing AA) struct nk_sdl* sdl; NK_ASSERT(ctx); sdl = (struct nk_sdl*)ctx->userdata.ptr; + NK_ASSERT(sdl); { SDL_Rect saved_clip; @@ -231,6 +235,7 @@ nk_sdl_font_stash_begin(struct nk_context* ctx) struct nk_sdl* sdl; NK_ASSERT(ctx); sdl = (struct nk_sdl*)ctx->userdata.ptr; + NK_ASSERT(sdl); nk_font_atlas_init_default(&sdl->atlas); nk_font_atlas_begin(&sdl->atlas); return &sdl->atlas; @@ -243,6 +248,7 @@ nk_sdl_font_stash_end(struct nk_context* ctx) const void *image; int w, h; NK_ASSERT(ctx); sdl = (struct nk_sdl*)ctx->userdata.ptr; + NK_ASSERT(sdl); image = nk_font_atlas_bake(&sdl->atlas, &w, &h, NK_FONT_ATLAS_RGBA32); nk_sdl_device_upload_atlas(&sdl->ctx, image, w, h); nk_font_atlas_end(&sdl->atlas, nk_handle_ptr(sdl->ogl.font_tex), &sdl->ogl.tex_null); @@ -347,6 +353,7 @@ void nk_sdl_shutdown(struct nk_context* ctx) struct nk_sdl* sdl; NK_ASSERT(ctx); sdl = (struct nk_sdl*)ctx->userdata.ptr; + NK_ASSERT(sdl); nk_font_atlas_clear(&sdl->atlas); nk_buffer_free(&sdl->ogl.cmds); From 947fce71da74fce638e27750105f39892aa9d8f5 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Sat, 22 Feb 2025 12:50:42 -0500 Subject: [PATCH 13/18] sdl3: Add safety checks against the font stash --- demo/sdl3/nuklear_sdl3_renderer.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index cd15ac1fa..e2c299e50 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -84,6 +84,13 @@ nk_sdl_device_upload_atlas(struct nk_context* ctx, const void *image, int width, NK_ASSERT(ctx); sdl = (struct nk_sdl*)ctx->userdata.ptr; NK_ASSERT(sdl); + + /* Clean up if the texture already exists. */ + if (sdl->ogl.font_tex != NULL) { + SDL_DestroyTexture(sdl->ogl.font_tex); + sdl->ogl.font_tex = NULL; + } + SDL_Texture *g_SDLFontTexture = SDL_CreateTexture(sdl->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); if (g_SDLFontTexture == NULL) { SDL_Log("error creating texture"); @@ -218,6 +225,7 @@ nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer) NK_ASSERT(renderer); sdl = SDL_malloc(sizeof(struct nk_sdl)); NK_ASSERT(sdl); + nk_zero(sdl, sizeof(struct nk_sdl)); sdl->win = win; sdl->renderer = renderer; nk_init_default(&sdl->ctx, 0); @@ -250,6 +258,7 @@ nk_sdl_font_stash_end(struct nk_context* ctx) sdl = (struct nk_sdl*)ctx->userdata.ptr; NK_ASSERT(sdl); image = nk_font_atlas_bake(&sdl->atlas, &w, &h, NK_FONT_ATLAS_RGBA32); + NK_ASSERT(image); nk_sdl_device_upload_atlas(&sdl->ctx, image, w, h); nk_font_atlas_end(&sdl->atlas, nk_handle_ptr(sdl->ogl.font_tex), &sdl->ogl.tex_null); if (sdl->atlas.default_font) { From 6ca8d0bf44789b81e7d47e78080c709709a6c4e6 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Tue, 4 Mar 2025 19:03:44 -0500 Subject: [PATCH 14/18] sdl3: Use SDL_GetModState() for CTRL mode, from @rswinkle --- demo/sdl3/nuklear_sdl3_renderer.h | 35 +++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index e2c299e50..887bdd30d 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -35,6 +35,8 @@ NK_API void nk_sdl_set_userdata(struct nk_context* ctx, nk_handl * =============================================================== */ #ifdef NK_SDL3_RENDERER_IMPLEMENTATION +#ifndef NK_SDL3_RENDERER_IMPLEMENTATION_ONCE +#define NK_SDL3_RENDERER_IMPLEMENTATION_ONCE #ifndef NK_INCLUDE_COMMAND_USERDATA #error "nuklear_sdl3 requires the NK_INCLUDE_COMMAND_USERDATA define" @@ -278,7 +280,8 @@ nk_sdl_handle_event(struct nk_context* ctx, SDL_Event *evt) case SDL_EVENT_KEY_DOWN: { int down = evt->type == SDL_EVENT_KEY_DOWN; - const bool* state = SDL_GetKeyboardState(0); + int ctrl_down = SDL_GetModState() & (SDL_KMOD_LCTRL | SDL_KMOD_RCTRL); + switch(evt->key.key) { case SDLK_RSHIFT: /* RSHIFT & LSHIFT share same routine */ @@ -293,24 +296,27 @@ nk_sdl_handle_event(struct nk_context* ctx, SDL_Event *evt) 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_A: nk_input_key(ctx, NK_KEY_TEXT_SELECT_ALL, down && ctrl_down); break; + case SDLK_Z: nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && ctrl_down); break; + case SDLK_R: nk_input_key(ctx, NK_KEY_TEXT_REDO, down && ctrl_down); break; + case SDLK_C: nk_input_key(ctx, NK_KEY_COPY, down && ctrl_down); break; + case SDLK_V: nk_input_key(ctx, NK_KEY_PASTE, down && ctrl_down); break; + case SDLK_X: nk_input_key(ctx, NK_KEY_CUT, down && ctrl_down); break; + case SDLK_B: nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && ctrl_down); break; + case SDLK_E: nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && ctrl_down); 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]) + if (ctrl_down) nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down); - else nk_input_key(ctx, NK_KEY_LEFT, down); + else + nk_input_key(ctx, NK_KEY_LEFT, down); break; case SDLK_RIGHT: - if (state[SDL_SCANCODE_LCTRL]) + if (ctrl_down) nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down); - else nk_input_key(ctx, NK_KEY_RIGHT, down); + else + nk_input_key(ctx, NK_KEY_RIGHT, down); break; } return 1; @@ -326,7 +332,9 @@ nk_sdl_handle_event(struct nk_context* ctx, SDL_Event *evt) 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; + else + 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; } @@ -377,4 +385,5 @@ void nk_sdl_shutdown(struct nk_context* ctx) nk_free(ctx); } +#endif /* NK_SDL3_RENDERER_IMPLEMENTATION_ONCE */ #endif /* NK_SDL3_RENDERER_IMPLEMENTATION */ From 29376f47eccd80958c46f872fd6ab13773404309 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Tue, 4 Mar 2025 19:08:56 -0500 Subject: [PATCH 15/18] sdl3: Use evt->key.mod instead of the function call --- demo/sdl3/nuklear_sdl3_renderer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index 887bdd30d..eb2149472 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -280,7 +280,7 @@ nk_sdl_handle_event(struct nk_context* ctx, SDL_Event *evt) case SDL_EVENT_KEY_DOWN: { int down = evt->type == SDL_EVENT_KEY_DOWN; - int ctrl_down = SDL_GetModState() & (SDL_KMOD_LCTRL | SDL_KMOD_RCTRL); + int ctrl_down = evt->key.mod & (SDL_KMOD_LCTRL | SDL_KMOD_RCTRL); switch(evt->key.key) { From 8ffbc2298f31724b38489570a8f9310786a2326a Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Wed, 5 Mar 2025 21:34:57 -0500 Subject: [PATCH 16/18] sdl3: Fix background color --- demo/sdl3/nuklear_sdl3_renderer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/demo/sdl3/nuklear_sdl3_renderer.c b/demo/sdl3/nuklear_sdl3_renderer.c index 27e3daac8..b407af096 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.c +++ b/demo/sdl3/nuklear_sdl3_renderer.c @@ -227,7 +227,11 @@ SDL_AppResult SDL_AppIterate(void *appstate) { #endif /* ----------------------------------------- */ - SDL_SetRenderDrawColor(app->renderer, 255, 0, 255, SDL_ALPHA_OPAQUE); + SDL_SetRenderDrawColor(app->renderer, + (Uint8)(app->bg.r * 255.0f), + (Uint8)(app->bg.g * 255.0f), + (Uint8)(app->bg.b * 255.0f), + SDL_ALPHA_OPAQUE); SDL_RenderClear(app->renderer); nk_sdl_render(ctx, NK_ANTI_ALIASING_ON); From 8e354095160f8b36ad440536ab4c1b2c22f1a8e5 Mon Sep 17 00:00:00 2001 From: TheRainTrain Date: Tue, 11 Mar 2025 18:27:23 +0100 Subject: [PATCH 17/18] Use built-in motion handler to circumvent FPS-limit/VSync issue --- demo/sdl3/nuklear_sdl3_renderer.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index eb2149472..dcb65f56a 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -342,11 +342,7 @@ nk_sdl_handle_event(struct nk_context* ctx, SDL_Event *evt) return 1; case SDL_EVENT_MOUSE_MOTION: - ctx->input.mouse.prev = ctx->input.mouse.pos; - ctx->input.mouse.delta.x = evt->motion.xrel; - ctx->input.mouse.delta.y = evt->motion.yrel; - ctx->input.mouse.pos.x = evt->motion.x; - ctx->input.mouse.pos.y = evt->motion.y; + nk_input_motion(ctx, evt->motion.x, evt->motion.y); return 1; case SDL_EVENT_TEXT_INPUT: From fe65ed7832ba09bb5d6d709d854c7d7a61cb4f9e Mon Sep 17 00:00:00 2001 From: Rain <75197158+TheRainTrain@users.noreply.github.com> Date: Wed, 12 Mar 2025 20:37:05 +0000 Subject: [PATCH 18/18] Precise floating point motion handling Co-authored-by: Rob Loach --- demo/sdl3/nuklear_sdl3_renderer.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/demo/sdl3/nuklear_sdl3_renderer.h b/demo/sdl3/nuklear_sdl3_renderer.h index dcb65f56a..c57a4239d 100644 --- a/demo/sdl3/nuklear_sdl3_renderer.h +++ b/demo/sdl3/nuklear_sdl3_renderer.h @@ -342,7 +342,10 @@ nk_sdl_handle_event(struct nk_context* ctx, SDL_Event *evt) return 1; case SDL_EVENT_MOUSE_MOTION: - nk_input_motion(ctx, evt->motion.x, evt->motion.y); + ctx->input.mouse.pos.x = evt->motion.x; + ctx->input.mouse.pos.y = evt->motion.y; + ctx->input.mouse.delta.x = ctx->input.mouse.pos.x - ctx->input.mouse.prev.x; + ctx->input.mouse.delta.y = ctx->input.mouse.pos.y - ctx->input.mouse.prev.y; return 1; case SDL_EVENT_TEXT_INPUT: