add resource embedding

This commit is contained in:
sam 2024-09-01 14:10:06 +12:00
parent ba0eb21dbf
commit cbfa5c3f3b
15 changed files with 149 additions and 82 deletions

View file

@ -12,8 +12,17 @@ C_OBJ=$(C_FILES:.c=.o)
SHADER_FILES=$(shell find -L * -type f -name '*.glsl')
SHADER_OBJ=$(SHADER_FILES:.glsl=.glsl.h)
RESOURCES_DIR=res
RESOURCES_OBJ=$(RESOURCES_DIR)/res.o
RESOURCES_H=include/gear/resources.h
RESOURCE_FILES=$(shell find -L $(RESOURCES_DIR) -type f -not -wholename $(RESOURCES_OBJ))
ifeq ($(CC), gcc)
CFLAGS += -Wno-use-after-free
endif
ifeq ($(OS), Windows_NT)
CFLAGS += -DSOKOL_D3D11
CFLAGS += -DSOKOL_D3D11 -D_CRT_SECURE_NO_WARNINGS
BINARY := $(BINARY).exe
else
UNAME_S := $(shell uname -s)
@ -30,12 +39,22 @@ else
endif
endif
$(BINARY): shaders $(C_OBJ) $(OBJC_OBJ)
$(CC) $(C_OBJ) $(OBJC_OBJ) $(LDFLAGS) -o $(BINARY)
.PHONY: shaders resources
$(BINARY): shaders resources $(RESOURCES_OBJ) $(C_OBJ) $(OBJC_OBJ)
$(CC) $(C_OBJ) $(OBJC_OBJ) $(RESOURCES_OBJ) $(LDFLAGS) -o $(BINARY)
shaders: $(SHADER_OBJ)
@echo Shaders compiled
resources:
$(LD) -r -b binary -o $(RESOURCES_OBJ) $(RESOURCE_FILES)
@echo "#ifndef __G_RESOURCES_H__" > $(RESOURCES_H)
@echo "#define __G_RESOURCES_H__" >> $(RESOURCES_H)
@nm -j $(RESOURCES_OBJ) | awk '{ print "extern char " $$0 "[];" }' >> $(RESOURCES_H)
@echo "#endif" >> $(RESOURCES_H)
@echo Resources compiled
%.glsl.h: %.glsl
$(SHADERC) --input $< --output $@ $(SHADER_FLAGS)
@ -52,4 +71,4 @@ bear: clean
bear -- $(MAKE) $(BINARY)
clean:
rm -rf $(C_OBJ) $(OBJC_OBJ) $(SHADER_OBJ) $(BINARY)
rm -rf $(C_OBJ) $(OBJC_OBJ) $(SHADER_OBJ) $(RESOURCES_OBJ) $(RESOURCES_H) $(BINARY)

BIN
gear Executable file

Binary file not shown.

View file

@ -35,4 +35,10 @@ typedef HMM_Mat4 mat4;
#define SL_SG_RANGE(x) (sg_range){ .ptr = x.data, .size = x.size * sizeof(*x.data) }
#define g_buffer(type, size) \
struct { \
type buf[size]; \
i32 len; \
} \
#endif

9
include/gear/font.h Normal file

File diff suppressed because one or more lines are too long

9
include/gear/resources.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef __G_RESOURCES_H__
#define __G_RESOURCES_H__
extern char _binary_res_happi_jpg_end[];
extern char _binary_res_happi_jpg_size[];
extern char _binary_res_happi_jpg_start[];
extern char _binary_res_OpenSans_Regular_ttf_end[];
extern char _binary_res_OpenSans_Regular_ttf_size[];
extern char _binary_res_OpenSans_Regular_ttf_start[];
#endif

View file

@ -1,13 +1,18 @@
#ifndef __G_CONSOLE_H__
#define __G_CONSOLE_H__
#define G_CONSOLE_MAX_LEN 512
#define G_CONSOLE_BUFFER_SIZE G_CONSOLE_MAX_LEN * 64
#include <gear/base.h>
#include <gear/ui/gui.h>
#include <log.c/log.h>
typedef g_buffer(char, G_CONSOLE_BUFFER_SIZE) g_console_buffer;
typedef struct g_console {
sl_string input;
sl_string output;
g_console_buffer input;
g_console_buffer output;
void (*log_callback)(log_Event* event);
} g_console;

View file

@ -25,6 +25,8 @@ typedef struct g_gui {
g_gui_context* ctx;
} g_gui;
extern struct nk_font* g_gui_font;
// src/ui/gui/create.c
g_gui* g_gui_create();

BIN
res/happi.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -2,6 +2,7 @@
#include <gear/camera.h>
#include <gear/ui/gui.h>
#include <gear/ui/console.h>
#include <gear/resources.h>
#include <sokol/sokol_app.h>
#include <sokol/sokol_gfx.h>
@ -14,8 +15,6 @@ g_renderer* renderer;
g_camera* camera;
g_gui* gui;
struct nk_font* font;
void init() {
sg_setup(&(sg_desc){
.environment = sglue_environment(),
@ -30,43 +29,10 @@ void init() {
for(sl_vec_it(layer, gui->layers)) {
log_info(" %s", (*layer)->name);
}
struct nk_font_atlas* atlas = calloc(1, sizeof(struct nk_font_atlas));
nk_font_atlas_init_default(atlas);
nk_font_atlas_begin(atlas);
float font_size = 22.0f;
const char* font_path = "assets/OpenSans-Regular.ttf";
struct nk_font_config config = nk_font_config(font_size);
font = nk_font_atlas_add_from_file(atlas, font_path, font_size, &config);
const void *image;
int atlas_width, atlas_height;
image = nk_font_atlas_bake(atlas, &atlas_width, &atlas_height, NK_FONT_ATLAS_RGBA32);
sg_image_desc img_desc = {0};
img_desc.width = atlas_width;
img_desc.height = atlas_height;
img_desc.data.subimage[0][0].ptr = image;
img_desc.data.subimage[0][0].size = atlas_width * atlas_height * 4;
img_desc.pixel_format = SG_PIXELFORMAT_RGBA8;
sg_image font_image = sg_make_image(&img_desc);
sg_sampler samp = sg_make_sampler(&(sg_sampler_desc){ 0 });
snk_image_t snk_img = snk_make_image(&(snk_image_desc_t){
.image = font_image,
.sampler = samp
});
// Complete the font atlas setup
nk_font_atlas_end(atlas, snk_nkhandle(snk_img), NULL);
}
void frame() {
g_gui_update(gui);
nk_style_set_font(gui->ctx, &font->handle);
g_renderer_begin(renderer);
g_gui_render(sapp_width(), sapp_height());
@ -74,6 +40,8 @@ void frame() {
}
void cleanup() {
log_info("Shutting down");
g_renderer_destroy(renderer);
g_gui_destroy(gui);
g_camera_destroy(camera);

View file

@ -1,23 +1,41 @@
#include "log.c/log.h"
#include <gear/ui/gui.h>
#include <gear/ui/console.h>
#include <log.c/log.h>
/*
sz combined_len = console->output.len + len;
if(combined_len > G_CONSOLE_MAX_LEN) {
sz required_trim = combined_len - G_CONSOLE_MAX_LEN;
if(required_trim < G_CONSOLE_MAX_LEN / 10) required_trim = G_CONSOLE_MAX_LEN / 5;
memcpy(console->output.buf, console->output.buf + required_trim, G_CONSOLE_MAX_LEN - required_trim);
}*/
char format_input_buf[G_CONSOLE_MAX_LEN] = { 0 };
char fmt[G_CONSOLE_MAX_LEN];
void log_callback(log_Event* event) {
char* formatted_input;
vasprintf(&formatted_input, event->fmt, event->ap);
char* formatted;
sz len = asprintf(&formatted, "%s\n", formatted_input);
free(formatted_input);
strncpy(fmt, event->fmt, G_CONSOLE_MAX_LEN);
strcat(fmt, "\n");
sz len = vsnprintf(format_input_buf, G_CONSOLE_MAX_LEN, fmt, event->ap);
g_console* console = event->udata;
while(console->output.len + len >= G_CONSOLE_BUFFER_SIZE) {
char* new_start = memchr(console->output.buf, '\n', G_CONSOLE_MAX_LEN);
if(new_start == NULL) {
new_start = console->output.buf;
}
for(sz i = 0; i < len; i++) {
sl_vec_push(console->output, formatted[i]);
new_start++;
sz len = new_start - console->output.buf;
memmove(console->output.buf, new_start, G_CONSOLE_BUFFER_SIZE - len);
console->output.len -= len;
}
free(formatted);
strcat(console->output.buf, format_input_buf);
console->output.len += len;
}
g_gui_layer* g_console_create() {
@ -26,17 +44,8 @@ g_gui_layer* g_console_create() {
log_info("Console allocated successfully");
log_debug("Console pointer: %p", console);
console->input = (sl_string){
.data = malloc(1),
.size = 0,
.capacity = 1
};
console->output = (sl_string){
.data = malloc(1),
.size = 0,
.capacity = 1
};
memset(&console->input, 0, G_CONSOLE_BUFFER_SIZE);
memset(&console->output, 0, G_CONSOLE_BUFFER_SIZE);
} else {
log_fatal("Failed to allocate console");
exit(EXIT_FAILURE);

View file

@ -3,9 +3,6 @@
void g_console_destroy(void* console_vp) {
g_console* console = console_vp;
sl_vec_free(console->input);
sl_vec_free(console->output);
free(console);
log_debug("Freed console: %p", console);

View file

@ -4,30 +4,23 @@
void g_console_draw(g_gui_context* ctx, g_gui_layer* layer) {
g_console* console = layer->data;
if(console->input.size >= console->input.capacity) {
sl_vec_grow(console->input);
}
if(console->output.size >= console->output.capacity) {
sl_vec_grow(console->input);
}
if (nk_begin(ctx, "Console", nk_rect(50, 50, 500, 500),
NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_CLOSABLE | NK_WINDOW_SCALABLE)) {
float frame_height = nk_window_get_content_region(ctx).h;
nk_layout_row_dynamic(ctx, frame_height - 42.5f, 1);
snk_edit_string(ctx, NK_EDIT_CLIPBOARD | NK_EDIT_SELECTABLE | NK_EDIT_MULTILINE,
console->output.data, (i32*)(&console->output.size),
console->output.size + 1, nk_filter_default);
snk_edit_string(ctx, NK_EDIT_CLIPBOARD | NK_EDIT_SELECTABLE | NK_EDIT_MULTILINE | NK_EDIT_GOTO_END_ON_ACTIVATE,
console->output.buf, &console->output.len,
G_CONSOLE_BUFFER_SIZE, nk_filter_default);
nk_layout_row_dynamic(ctx, 30.0f, 1);
enum nk_edit_events event = snk_edit_string(ctx, NK_EDIT_FIELD | NK_EDIT_SIG_ENTER,
console->input.data, (i32*)(&console->input.size),
console->input.size + 2, nk_filter_default);
console->input.buf, &console->input.len,
G_CONSOLE_MAX_LEN, nk_filter_default);
if(event & NK_EDIT_COMMITED) {
log_info("cmd: %s", sl_c_str(console->input));
console->input.size = 0;
log_info("cmd: %s", console->input);
memset(console->input.buf, 0, G_CONSOLE_MAX_LEN);
console->input.len = 0;
}
}

View file

@ -1,8 +1,11 @@
#include <gear/ui/gui.h>
#include <gear/ui/console.h>
#include <gear/resources.h>
#include <sokol/sokol_log.h>
#include <log.c/log.h>
struct nk_font* g_gui_font;
g_gui* g_gui_create() {
snk_setup(&(snk_desc_t){
.dpi_scale = sapp_dpi_scale(),
@ -21,5 +24,51 @@ g_gui* g_gui_create() {
exit(EXIT_FAILURE);
}
struct nk_font_atlas* atlas = calloc(1, sizeof(struct nk_font_atlas));
if(atlas != NULL) {
log_info("Font atlas allocated successfully");
log_debug("Font atlas pointer: %p", atlas);
nk_font_atlas_init_default(atlas);
nk_font_atlas_begin(atlas);
f32 font_size = 22.05f;
struct nk_font_config config = nk_font_config(font_size);
config.pixel_snap = true;
g_gui_font = nk_font_atlas_add_from_memory(atlas,
_binary_res_OpenSans_Regular_ttf_start,
_binary_res_OpenSans_Regular_ttf_end - _binary_res_OpenSans_Regular_ttf_start,
font_size, &config);
i32 atlas_width, atlas_height;
const u8* pixels = nk_font_atlas_bake(atlas, &atlas_width, &atlas_height, NK_FONT_ATLAS_RGBA32);
sg_image font_image = sg_make_image(&(sg_image_desc){
.label = "Font image",
.width = atlas_width,
.height = atlas_height,
.data.subimage[0][0] = (sg_range){
.ptr = pixels,
.size = atlas_width * atlas_height * 4
},
.pixel_format = SG_PIXELFORMAT_RGBA8
});
sg_sampler font_sampler = sg_make_sampler(&(sg_sampler_desc){
.label = "Font sampler"
});
snk_image_t snk_img = snk_make_image(&(snk_image_desc_t){
.image = font_image,
.sampler = font_sampler
});
nk_font_atlas_end(atlas, snk_nkhandle(snk_img), NULL);
} else {
log_fatal("Failed to allocate font atlas");
exit(EXIT_FAILURE);
}
return gui;
}

View file

@ -6,7 +6,8 @@
void g_gui_update(g_gui* gui) {
gui->ctx = snk_new_frame();
nk_style_set_font(gui->ctx, &g_gui_font->handle);
for(sl_vec_it(layer, gui->layers)) {
(*layer)->draw(gui->ctx, *layer);
}