diff --git a/bin/ios64/stb_dll_ios64.so b/bin/ios64/stb_dll_ios64.so index 2ee65b6..57b84e8 100644 Binary files a/bin/ios64/stb_dll_ios64.so and b/bin/ios64/stb_dll_ios64.so differ diff --git a/bin/linux/stb_dll.so b/bin/linux/stb_dll.so index ec7ea42..29a397e 100644 Binary files a/bin/linux/stb_dll.so and b/bin/linux/stb_dll.so differ diff --git a/bin/macos/stb_dll_macos.so b/bin/macos/stb_dll_macos.so index 2ee65b6..57b84e8 100644 Binary files a/bin/macos/stb_dll_macos.so and b/bin/macos/stb_dll_macos.so differ diff --git a/bin/win64/hmm_dll.dll b/bin/win64/hmm_dll.dll index 4957bac..11f8664 100644 Binary files a/bin/win64/hmm_dll.dll and b/bin/win64/hmm_dll.dll differ diff --git a/bin/win64/sokol_debug_dll.dll b/bin/win64/sokol_debug_dll.dll index bbc53eb..d8201b8 100644 Binary files a/bin/win64/sokol_debug_dll.dll and b/bin/win64/sokol_debug_dll.dll differ diff --git a/bin/win64/sokol_dll.dll b/bin/win64/sokol_dll.dll index 9b86629..4243991 100644 Binary files a/bin/win64/sokol_dll.dll and b/bin/win64/sokol_dll.dll differ diff --git a/bin/win64/sokol_nuklear_dll.dll b/bin/win64/sokol_nuklear_dll.dll index db22470..90496e9 100644 Binary files a/bin/win64/sokol_nuklear_dll.dll and b/bin/win64/sokol_nuklear_dll.dll differ diff --git a/bin/win64/sokol_shape_dll.dll b/bin/win64/sokol_shape_dll.dll index e0ab304..48a0191 100644 Binary files a/bin/win64/sokol_shape_dll.dll and b/bin/win64/sokol_shape_dll.dll differ diff --git a/bin/win64/stb_dll.dll b/bin/win64/stb_dll.dll index cc93521..2d51f5a 100644 Binary files a/bin/win64/stb_dll.dll and b/bin/win64/stb_dll.dll differ diff --git a/examples/samples/icon/copy.png b/examples/samples/icon/copy.png new file mode 100644 index 0000000..0a6e979 Binary files /dev/null and b/examples/samples/icon/copy.png differ diff --git a/examples/samples/icon/delete.png b/examples/samples/icon/delete.png new file mode 100644 index 0000000..7bc6dde Binary files /dev/null and b/examples/samples/icon/delete.png differ diff --git a/examples/samples/icon/edit.png b/examples/samples/icon/edit.png new file mode 100644 index 0000000..62ce0b4 Binary files /dev/null and b/examples/samples/icon/edit.png differ diff --git a/examples/samples/icon/rocket.png b/examples/samples/icon/rocket.png new file mode 100644 index 0000000..ea8e187 Binary files /dev/null and b/examples/samples/icon/rocket.png differ diff --git a/examples/samples/images/baboon.png b/examples/samples/images/baboon.png new file mode 100644 index 0000000..39cbd70 Binary files /dev/null and b/examples/samples/images/baboon.png differ diff --git a/examples/samples/nuklear_png_sapp.lua b/examples/samples/nuklear_png_sapp.lua new file mode 100644 index 0000000..70933e7 --- /dev/null +++ b/examples/samples/nuklear_png_sapp.lua @@ -0,0 +1,210 @@ +package.path = package.path..";../../?.lua" +local dirtools = require("tools.dirtools") +local base_path = dirtools.get_app_path("sokol%-luajit") + +package.cpath = package.cpath..";"..base_path.."bin/win64/?.dll" + +package.path = package.path..";"..base_path.."ffi/sokol/?.lua" +package.path = package.path..";"..base_path.."?.lua" + +--_G.SOKOL_DLL = "sokol_debug_dll" +local sapp = require("sokol_app") +sg = require("sokol_nuklear") +local nk = sg +local slib = require("sokol_libs") -- Warn - always after gfx!! + +local hmm = require("hmm") +local hutils = require("hmm_utils") + +local stb = require("stb") + +local ffi = require("ffi") + +-- returns struct nk_image +local function icon_load(filename) + + local x = ffi.new("int[1]", {0}) + local y = ffi.new("int[1]", {0}) + local n = ffi.new("int[1]", {4}) + local data = stb.stbi_load(filename, x, y, nil, 4) + if (data == nil) then error("[STB]: failed to load image: "..filename); end + + print("Image Loaded: "..filename.." Width: "..x[0].." Height: "..y[0].." Channels: "..n[0]) + + local pixformat = sg.SG_PIXELFORMAT_RGBA8 + + local sg_img_desc = ffi.new("sg_image_desc[1]") + sg_img_desc[0].width = x[0] + sg_img_desc[0].height = y[0] + sg_img_desc[0].pixel_format = pixformat + sg_img_desc[0].sample_count = 1 + + sg_img_desc[0].data.subimage[0][0].ptr = data + sg_img_desc[0].data.subimage[0][0].size = x[0] * y[0] * n[0] + + local new_img = sg.sg_make_image(sg_img_desc) + + -- // create a sokol-nuklear image object which associates an sg_image with an sg_sampler + local img_desc = ffi.new("snk_image_desc_t[1]") + img_desc[0].image = new_img + local snk_img = nk.snk_make_image(img_desc) + local nk_hnd = nk.snk_nkhandle(snk_img) + local nk_img = nk.nk_image_handle(nk_hnd); + + stb.stbi_image_free(data) + return nk_img +end + +-- -------------------------------------------------------------------------------------- + +local pix = {} + +local function init(void) + -- // setup sokol-gfx, sokol-time and sokol-imgui + local sg_desc = ffi.new("sg_desc[1]") + sg_desc[0].environment = slib.sglue_environment() + sg_desc[0].logger.func = slib.slog_func + sg.sg_setup( sg_desc ) + + -- // use sokol-nuklear with all default-options (we're not doing + -- // multi-sampled rendering or using non-default pixel formats) + local snk = ffi.new("snk_desc_t[1]") + snk[0].dpi_scale = sapp.sapp_dpi_scale() + snk[0].logger.func = slib.slog_func + nk.snk_setup(snk) + + local base_path = "samples/" + pix["baboon"] = icon_load(base_path.."images/baboon.png") + pix["copy"] = icon_load(base_path.."icon/copy.png") + pix["del"] = icon_load(base_path.."icon/delete.png") + pix["rocket"] = icon_load(base_path.."icon/rocket.png") + pix["edit"] = icon_load(base_path.."icon/edit.png") +end + +-- -------------------------------------------------------------------------------------- + +local function cleanup() + + sg.sg_shutdown() +end + +-- -------------------------------------------------------------------------------------- + +local function input(event) + nk.snk_handle_event(event) +end + +-- -------------------------------------------------------------------------------------- +-- Static vars +-- +-- Note: Many vars are locally set or globals. This was from a direct C conversion. +-- To make static vars workaround then place them below. + +local show_menu = ffi.new("bool[1]", {nk.nk_true}) +local border = ffi.new("bool[1]", {nk.nk_true}) +local resize = ffi.new("bool[1]", {nk.nk_true}) +local movable = ffi.new("bool[1]", {nk.nk_true}) +local no_scrollbar = ffi.new("bool[1]", {nk.nk_false}) +local scale_left = ffi.new("bool[1]", {nk.nk_false}) +local winrect = ffi.new("struct nk_rect[1]", {{10, 25, 1000, 600}}) + +-- /* window flags */ +local window_flags = 0 +local minimizable = ffi.new("bool[1]", {nk.nk_true}) + +-- /* popups */ +local header_align = nk.NK_HEADER_RIGHT + +-- -------------------------------------------------------------------------------------- + +local function draw_demo_ui(ctx) + + -- /* window flags */ + ctx[0].style.window.header.align = header_align + if (border[0] == true) then window_flags = bit.bor(window_flags, nk.NK_WINDOW_BORDER) end + if (resize[0] == true) then window_flags = bit.bor(window_flags, nk.NK_WINDOW_SCALABLE) end + if (movable[0] == true) then window_flags = bit.bor(window_flags, nk.NK_WINDOW_MOVABLE) end + if (no_scrollbar[0] == true) then window_flags = bit.bor(window_flags, nk.NK_WINDOW_NO_SCROLLBAR) end + if (scale_left[0] == true) then window_flags = bit.bor(window_flags, nk.NK_WINDOW_SCALE_LEFT) end + if (minimizable[0] == true) then window_flags = bit.bor(window_flags, nk.NK_WINDOW_MINIMIZABLE) end + + if (nk.nk_begin(ctx, "PNG View", winrect[0], window_flags) == true) then + + if (show_menu[0] == true) then + + -- /* menubar */ + local menu_states = { MENU_DEFAULT = 0, MENU_WINDOWS = 1} + nk.nk_menubar_begin(ctx) + + -- /* menu #1 */ + nk.nk_layout_row_begin(ctx, nk.NK_STATIC, 500, 5) + nk.nk_layout_row_push(ctx, 600) + + nk.nk_image(ctx, pix["baboon"]) + + -- /*------------------------------------------------ + -- * CONTEXTUAL + -- *------------------------------------------------*/ + if (nk.nk_contextual_begin(ctx, nk.NK_WINDOW_NO_SCROLLBAR, nk.nk_vec2(150, 300), nk.nk_window_get_bounds(ctx)) == true) then + nk.nk_layout_row_dynamic(ctx, 30, 1); + if (nk.nk_contextual_item_image_label(ctx, pix.copy, "Clone", nk.NK_TEXT_RIGHT) == true) then + print("pressed clone!\n") + end + if (nk.nk_contextual_item_image_label(ctx, pix.del, "Delete", nk.NK_TEXT_RIGHT) == true) then + print("pressed delete!\n") + end + if (nk.nk_contextual_item_image_label(ctx, pix.rocket, "Rocket", nk.NK_TEXT_RIGHT) == true) then + print("pressed rocket!\n") + end + if (nk.nk_contextual_item_image_label(ctx, pix.edit, "Edit", nk.NK_TEXT_RIGHT) == true) then + print("pressed edit!\n") + end + nk.nk_contextual_end(ctx) + end + + nk.nk_layout_row_end(ctx) + end + end + nk.nk_end(ctx) + return not nk.nk_window_is_closed(ctx, "Overview") +end + +-- -------------------------------------------------------------------------------------- + +local function frame(void) + + local ctx = nk.snk_new_frame() + + -- // see big function at end of file + draw_demo_ui(ctx) + + -- // the sokol_gfx draw pass + local pass = ffi.new("sg_pass[1]") + pass[0].action.colors[0].load_action = sg.SG_LOADACTION_CLEAR + pass[0].action.colors[0].clear_value = { 0.25, 0.5, 0.7, 1.0 } + pass[0].swapchain = slib.sglue_swapchain() + sg.sg_begin_pass(pass) + + nk.snk_render(sapp.sapp_width(), sapp.sapp_height()) + sg.sg_end_pass() + sg.sg_commit() +end + +-- -------------------------------------------------------------------------------------- + +local app_desc = ffi.new("sapp_desc[1]") +app_desc[0].init_cb = init +app_desc[0].frame_cb = frame +app_desc[0].cleanup_cb = cleanup +app_desc[0].event_cb = input +app_desc[0].width = 1920 +app_desc[0].height = 1080 +app_desc[0].window_title = "nuklear (sokol-app)" +app_desc[0].icon.sokol_default = true +app_desc[0].logger.func = slib.slog_func +app_desc[0].enable_clipboard = true +app_desc[0].ios_keyboard_resizes_canvas = false + +sapp.sapp_run( app_desc ) + +-- -------------------------------------------------------------------------------------- diff --git a/ffi/sokol/stb.lua b/ffi/sokol/stb.lua new file mode 100644 index 0000000..e6eb4cd --- /dev/null +++ b/ffi/sokol/stb.lua @@ -0,0 +1,144 @@ +local ffi = require( "ffi" ) + +local libs = ffi_stb_dll or { + OSX = { x64 = "stb_dll" }, + Windows = { x64 = "stb_dll.dll" }, + Linux = { x64 = "stb_dll.so", arm = "stb_dll.so" }, + BSD = { x64 = "stb_dll.so" }, + POSIX = { x64 = "stb_dll.so" }, + Other = { x64 = "stb_dll.so" }, +} + +local lib = ffi_stb_dll or libs[ ffi.os ][ ffi.arch ] +local stb_lib = ffi.load( lib ) + +ffi.cdef[[ + +/********** stb_lib ****************************************************************/ + +typedef unsigned char stbi_uc; +typedef unsigned short stbi_us; + +////////////////////////////////////////////////////////////////////////////// +// +// PRIMARY API - works on images of any type +// + +// +// load image by filename, open file, or memory buffer +// + +typedef struct +{ + int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative + int (*eof) (void *user); // returns nonzero if we are at end of file/data +} stbi_io_callbacks; + +//////////////////////////////////// +// +// 8-bits-per-channel interface +// + +stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); +stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); + +stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +stbi_uc *stbi_load_from_file (void *f, int *x, int *y, int *channels_in_file, int desired_channels); + +// for stbi_load_from_file, file pointer is left pointing immediately after image + +stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); + +//////////////////////////////////// +// +// 16-bits-per-channel interface +// + +stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); +stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + +stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +stbi_us *stbi_load_from_file_16(void *f, int *x, int *y, int *channels_in_file, int desired_channels); + + +//////////////////////////////////// +// +// float-per-channel interface +// + +float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); +float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + +float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +float *stbi_loadf_from_file (void *f, int *x, int *y, int *channels_in_file, int desired_channels); + + +void stbi_hdr_to_ldr_gamma(float gamma); +void stbi_hdr_to_ldr_scale(float scale); + +void stbi_ldr_to_hdr_gamma(float gamma); +void stbi_ldr_to_hdr_scale(float scale); + + +// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR +int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); +int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); + +int stbi_is_hdr (char const *filename); +int stbi_is_hdr_from_file(void *f); + + +// get a VERY brief reason for failure +// on most compilers (and ALL modern mainstream compilers) this is threadsafe +const char *stbi_failure_reason (void); + +// free the loaded image -- this is just free() +void stbi_image_free (void *retval_from_stbi_load); + +// get image dimensions & components without fully decoding +int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); +int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); +int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); +int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); + +int stbi_info (char const *filename, int *x, int *y, int *comp); +int stbi_info_from_file (void *f, int *x, int *y, int *comp); +int stbi_is_16_bit (char const *filename); +int stbi_is_16_bit_from_file(void *f); + + +// for image formats that explicitly notate that they have premultiplied alpha, +// we just return the colors as stored in the file. set this flag to force +// unpremultiplication. results are undefined if the unpremultiply overflow. +void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + +// indicate whether we should process iphone images back to canonical format, +// or just pass them through "as-is" +void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + +// flip the image vertically, so the first pixel in the output array is the bottom left +void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); + +// as above, but only applies to images loaded on the thread that calls the function +// this function is only available if your compiler supports thread-local variables; +// calling it will fail to link if your compiler doesn't +void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply); +void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert); +void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); + +// ZLIB client - used by PNG, available for other purposes + +char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); +char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); +char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); +int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + +char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); +int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + + + +]] + +return stb_lib \ No newline at end of file