2025-01-29 17:48:20 +08:00
|
|
|
package.path = package.path..";../../?.lua"
|
|
|
|
|
local dirtools = require("tools.vfs.dirtools").init("sokol%-luajit")
|
2024-12-24 09:39:08 +08:00
|
|
|
|
|
|
|
|
--_G.SOKOL_DLL = "sokol_debug_dll"
|
|
|
|
|
local sapp = require("sokol_app")
|
2025-01-29 17:48:20 +08:00
|
|
|
sg = require("sokol_gfx")
|
2024-12-24 09:39:08 +08:00
|
|
|
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")
|
|
|
|
|
|
|
|
|
|
local utils = require("utils")
|
2026-07-30 22:59:09 +08:00
|
|
|
require("engine.platform")
|
2024-12-24 09:39:08 +08:00
|
|
|
|
|
|
|
|
-- --------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
local fonts = nil
|
|
|
|
|
local atlas = ffi.new("struct nk_font_atlas[1]")
|
|
|
|
|
|
|
|
|
|
-- --------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
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 )
|
2026-07-30 22:59:09 +08:00
|
|
|
win.Sleep(10)
|
2024-12-24 09:39:08 +08:00
|
|
|
|
|
|
|
|
-- // 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
|
|
|
|
|
snk[0].no_default_font = true
|
|
|
|
|
nk.snk_setup(snk)
|
|
|
|
|
|
|
|
|
|
-- Hide sokol mouse, use the nuklear one
|
|
|
|
|
sapp.sapp_show_mouse(false)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- --------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
local master_img_width = ffi.new("int[1]", 0)
|
|
|
|
|
local master_img_height = ffi.new("int[1]", 0)
|
|
|
|
|
|
|
|
|
|
local function font_loader( atlas, font_file, font_size, cfg)
|
|
|
|
|
|
|
|
|
|
local newfont = nk.nk_font_atlas_add_from_file(atlas, font_file, font_size, cfg)
|
2025-11-07 09:02:40 +08:00
|
|
|
return nil, newfont
|
2024-12-24 09:39:08 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- --------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
local function font_atlas_img( image )
|
|
|
|
|
local sg_img_desc = ffi.new("sg_image_desc[1]")
|
|
|
|
|
sg_img_desc[0].width = master_img_width[0]
|
|
|
|
|
sg_img_desc[0].height = master_img_height[0]
|
|
|
|
|
sg_img_desc[0].pixel_format = sg.SG_PIXELFORMAT_RGBA8
|
|
|
|
|
sg_img_desc[0].sample_count = 1
|
|
|
|
|
|
|
|
|
|
sg_img_desc[0].data.subimage[0][0].ptr = image
|
|
|
|
|
sg_img_desc[0].data.subimage[0][0].size = master_img_width[0] * master_img_height[0] * 4
|
|
|
|
|
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)
|
|
|
|
|
return nk_hnd
|
|
|
|
|
end
|
|
|
|
|
|
2025-11-07 09:02:40 +08:00
|
|
|
local rune_ranges = ffi.new("nk_rune[9]", {
|
|
|
|
|
0xE000, 0xF8FF, -- private use / Nerd Font symbols
|
|
|
|
|
0
|
|
|
|
|
})
|
|
|
|
|
|
2024-12-24 09:39:08 +08:00
|
|
|
-- --------------------------------------------------------------------------------------
|
|
|
|
|
-- Setup fonts
|
|
|
|
|
local function setup_font(ctx)
|
|
|
|
|
|
|
|
|
|
fonts = {}
|
2025-01-29 17:48:20 +08:00
|
|
|
local font_path = "projects/examples/samples/font/"
|
2024-12-24 09:39:08 +08:00
|
|
|
|
|
|
|
|
local image = nil
|
|
|
|
|
|
|
|
|
|
nk.nk_font_atlas_init_default(atlas)
|
|
|
|
|
nk.nk_font_atlas_begin(atlas)
|
|
|
|
|
|
|
|
|
|
image, fonts[1] = font_loader(atlas, font_path.."acknowtt.ttf", 16.0, nil)
|
|
|
|
|
|
2025-11-07 09:02:40 +08:00
|
|
|
local config = nk.nk_font_config(40.0)
|
|
|
|
|
config.range = rune_ranges
|
|
|
|
|
image, fonts[2] = font_loader(atlas, font_path.."fontawesome-webfont.ttf", 40.0, config)
|
2024-12-24 09:39:08 +08:00
|
|
|
|
|
|
|
|
image, fonts[3] = font_loader(atlas, font_path.."ProggyClean.ttf", 18.0, nil)
|
|
|
|
|
|
2025-11-07 09:02:40 +08:00
|
|
|
local image = nk.nk_font_atlas_bake(atlas, master_img_width, master_img_height, nk.NK_FONT_ATLAS_RGBA32)
|
|
|
|
|
|
2024-12-24 09:39:08 +08:00
|
|
|
-- Dump the atlas to check it.
|
2025-10-23 12:15:32 +08:00
|
|
|
stb.stbi_write_png( "data/temp/atlas_font.png", master_img_width[0], master_img_height[0], 4, image, master_img_width[0] * 4)
|
2024-12-24 09:39:08 +08:00
|
|
|
|
|
|
|
|
-- print(master_img_width[0], master_img_height[0], 4)
|
|
|
|
|
local nk_img = font_atlas_img(image)
|
|
|
|
|
nk.nk_font_atlas_end(atlas, nk_img, nil)
|
|
|
|
|
nk.nk_font_atlas_cleanup(atlas)
|
|
|
|
|
|
|
|
|
|
nk.nk_style_load_all_cursors(ctx, atlas[0].cursors)
|
|
|
|
|
nk.nk_style_set_font(ctx, fonts[1].handle)
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
if(fonts == nil) then
|
|
|
|
|
setup_font(ctx)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
nk.nk_style_show_cursor(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, "Multi Font Sample", 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, 80, 5)
|
|
|
|
|
nk.nk_layout_row_push(ctx, 250)
|
|
|
|
|
|
|
|
|
|
nk.nk_style_set_font(ctx, fonts[1].handle)
|
|
|
|
|
nk.nk_button_label(ctx, "Hello In acknowtt Font")
|
|
|
|
|
|
|
|
|
|
local utf = ffi.new("char[2]", {0x83, 0xf1})
|
|
|
|
|
nk.nk_style_set_font(ctx, fonts[2].handle)
|
|
|
|
|
nk.nk_button_label(ctx, "")
|
|
|
|
|
|
|
|
|
|
nk.nk_style_set_font(ctx, fonts[3].handle)
|
|
|
|
|
nk.nk_button_label(ctx, "Hello in ProggyClean")
|
|
|
|
|
|
2025-11-07 09:02:40 +08:00
|
|
|
local text = ""
|
|
|
|
|
local w = fonts[2].handle.width(fonts[2].handle.userdata, fonts[2].handle.height, text, #text)
|
|
|
|
|
local h = fonts[2].handle.height
|
|
|
|
|
local rect = nk.nk_rect(100, 100, w, h)
|
|
|
|
|
local hcolor = nk.nk_rgba(0xff, 0xff, 0xff, 0xff)
|
|
|
|
|
nk.nk_draw_text(nk.nk_window_get_canvas(ctx), rect, text, #text, fonts[2].handle, hcolor, hcolor)
|
|
|
|
|
|
2024-12-24 09:39:08 +08:00
|
|
|
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)
|
|
|
|
|
|
2025-11-13 16:35:40 +08:00
|
|
|
local ctx = nk.snk_new_frame(false)
|
2024-12-24 09:39:08 +08:00
|
|
|
|
|
|
|
|
-- // 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 )
|
|
|
|
|
|
|
|
|
|
-- --------------------------------------------------------------------------------------
|