-
Notifications
You must be signed in to change notification settings - Fork 619
Add SDL3 #779
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add SDL3 #779
Changes from 6 commits
f9f00dc
aecd78a
6222a9c
079d3b6
e050f90
2c587ce
299fe6a
996ef5f
95bd684
fccae92
6dc4729
5967a90
1305c18
1b212cc
947fce7
6ca8d0b
29376f4
8ffbc22
8e35409
fe65ed7
c171b37
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
include(FetchContent) | ||
FetchContent_Declare( | ||
SDL3 | ||
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git | ||
GIT_TAG release-3.2.4 | ||
GIT_SHALLOW TRUE | ||
) | ||
FetchContent_MakeAvailable(SDL3) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,251 @@ | ||
/* nuklear - public domain */ | ||
#include <stdio.h> | ||
#include <stddef.h> /* offsetof TODO: sdl2_renderer didn't need this header? */ | ||
|
||
#define SDL_MAIN_USE_CALLBACKS | ||
#include <SDL3/SDL.h> | ||
#include <SDL3/SDL_main.h> | ||
|
||
#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 | ||
#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" | ||
|
||
#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; | ||
struct nk_context * ctx; | ||
struct nk_colorf bg; | ||
} 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", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &appContext->window, &appContext->renderer)) { | ||
SDL_free(appContext); | ||
return SDL_Fail(); | ||
} | ||
|
||
SDL_StartTextInput(appContext->window); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On desktop platforms, SDL_StartTextInput() is implicitly called on SDL window creation. On some, typically non desktop, platforms this call implicitly enables and shows virtual keyboard. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In SDL3, this needs to be explicitly called on Desktop platforms. I think adding a comment about the behavior of calling this on mobile is probably in order There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, is there a cleaner way we could accomplish this? Perhaps a callback when a textbox on focus/blur? |
||
|
||
appContext->bg.r = 0.10f; | ||
appContext->bg.g = 0.18f; | ||
appContext->bg.b = 0.24f; | ||
appContext->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; | ||
} | ||
|
||
struct nk_context* ctx = nk_sdl_init(appContext->window, appContext->renderer); | ||
appContext->ctx = ctx; | ||
|
||
{ | ||
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 */ | ||
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);*/ | ||
/*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(ctx); | ||
|
||
/* 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(app->ctx, event); | ||
|
||
return SDL_APP_CONTINUE; | ||
} | ||
|
||
SDL_AppResult SDL_AppIterate(void *appstate) { | ||
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), | ||
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(app->bg), nk_vec2(nk_widget_width(ctx),400))) { | ||
nk_layout_row_dynamic(ctx, 120, 1); | ||
app->bg = nk_color_picker(ctx, app->bg, NK_RGBA); | ||
nk_layout_row_dynamic(ctx, 25, 1); | ||
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); | ||
} | ||
} | ||
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); | ||
RobLoach marked this conversation as resolved.
Show resolved
Hide resolved
|
||
SDL_RenderClear(app->renderer); | ||
|
||
nk_sdl_render(ctx, 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) { | ||
nk_sdl_shutdown(app->ctx); | ||
SDL_DestroyRenderer(app->renderer); | ||
SDL_DestroyWindow(app->window); | ||
SDL_free(app); | ||
} | ||
|
||
SDL_Quit(); | ||
} |
Uh oh!
There was an error while loading. Please reload this page.