Merge branch 'main' of https://git.poto.cafe/wanp/townengine
This commit is contained in:
commit
d34516c4ee
@ -20,9 +20,9 @@ static void title_tick(State *state) {
|
|||||||
((float)ctx.resolution.x / 2) - ((float)320 / 2), 64, 320, 128 }));
|
((float)ctx.resolution.x / 2) - ((float)320 / 2), 64, 320, 128 }));
|
||||||
|
|
||||||
/* draw the tick count as an example of dynamic text */
|
/* draw the tick count as an example of dynamic text */
|
||||||
size_t text_str_len = snprintf(NULL, 0, "%lu", state->ctx->frame_number) + 1;
|
size_t text_str_len = snprintf(NULL, 0, "%llu", state->ctx->frame_number) + 1;
|
||||||
char *text_str = cmalloc(text_str_len);
|
char *text_str = cmalloc(text_str_len);
|
||||||
snprintf(text_str, text_str_len, "%lu", state->ctx->frame_number);
|
snprintf(text_str, text_str_len, "%llu", state->ctx->frame_number);
|
||||||
|
|
||||||
const char *font = "/fonts/kenney-pixel.ttf";
|
const char *font = "/fonts/kenney-pixel.ttf";
|
||||||
int text_h = 32;
|
int text_h = 32;
|
||||||
@ -39,7 +39,6 @@ static void title_tick(State *state) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
draw_text(text_str, (Vec2){ 0, 0 }, text_h, (Color) { 255, 255, 255, 255 }, font);
|
draw_text(text_str, (Vec2){ 0, 0 }, text_h, (Color) { 255, 255, 255, 255 }, font);
|
||||||
|
|
||||||
free(text_str);
|
free(text_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ TWN_API void draw_sprite(char const *path,
|
|||||||
TWN_API void draw_rectangle(Rect rect, Color color);
|
TWN_API void draw_rectangle(Rect rect, Color color);
|
||||||
|
|
||||||
/* pushes a filled circle onto the circle render queue */
|
/* pushes a filled circle onto the circle render queue */
|
||||||
|
/* note that its edges may look jagged with a radius larger than 2048 */
|
||||||
TWN_API void draw_circle(Vec2 position, float radius, Color color);
|
TWN_API void draw_circle(Vec2 position, float radius, Color color);
|
||||||
|
|
||||||
/* TODO: have font optional, with something minimal coming embedded */
|
/* TODO: have font optional, with something minimal coming embedded */
|
||||||
|
@ -22,18 +22,14 @@ void draw_circle(Vec2 position, float radius, Color color) {
|
|||||||
arrput(ctx.render_queue_2d, primitive);
|
arrput(ctx.render_queue_2d, primitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: caching and reuse scheme */
|
|
||||||
/* vertices_out and indices_out MUST BE FREED */
|
|
||||||
void create_circle_geometry(Vec2 position,
|
void create_circle_geometry(Vec2 position,
|
||||||
Color color,
|
Color color,
|
||||||
float radius,
|
float radius,
|
||||||
size_t num_vertices,
|
size_t num_vertices,
|
||||||
SDL_Vertex **vertices_out,
|
SDL_Vertex vertices[],
|
||||||
int **indices_out)
|
int indices[])
|
||||||
{
|
{
|
||||||
SDL_Vertex *vertices = cmalloc(sizeof *vertices * (num_vertices + 1));
|
|
||||||
int *indices = cmalloc(sizeof *indices * (num_vertices * 3));
|
|
||||||
|
|
||||||
/* the angle (in radians) to rotate by on each iteration */
|
/* the angle (in radians) to rotate by on each iteration */
|
||||||
float seg_rotation_angle = (360.0f / (float)num_vertices) * ((float)M_PI / 180);
|
float seg_rotation_angle = (360.0f / (float)num_vertices) * ((float)M_PI / 180);
|
||||||
|
|
||||||
@ -82,7 +78,4 @@ void create_circle_geometry(Vec2 position,
|
|||||||
index = num_vertices;
|
index = num_vertices;
|
||||||
indices[triangle_offset + 2] = (int)index;
|
indices[triangle_offset + 2] = (int)index;
|
||||||
}
|
}
|
||||||
|
|
||||||
*vertices_out = vertices;
|
|
||||||
*indices_out = indices;
|
|
||||||
}
|
}
|
||||||
|
@ -126,12 +126,14 @@ void render(void);
|
|||||||
/* clears all render queues */
|
/* clears all render queues */
|
||||||
void render_queue_clear(void);
|
void render_queue_clear(void);
|
||||||
|
|
||||||
|
/* fills two existing arrays with the geometry data of a circle */
|
||||||
|
/* the size of indices must be at least 3 times the number of vertices */
|
||||||
void create_circle_geometry(Vec2 position,
|
void create_circle_geometry(Vec2 position,
|
||||||
Color color,
|
Color color,
|
||||||
float radius,
|
float radius,
|
||||||
size_t num_vertices,
|
size_t num_vertices,
|
||||||
SDL_Vertex **vertices_out,
|
SDL_Vertex vertices[],
|
||||||
int **indices_out);
|
int indices[]);
|
||||||
|
|
||||||
struct QuadBatch {
|
struct QuadBatch {
|
||||||
size_t size; /* how many primitives are in current batch */
|
size_t size; /* how many primitives are in current batch */
|
||||||
|
@ -87,6 +87,9 @@ typedef enum {
|
|||||||
static Pipeline pipeline_last_used = PIPELINE_NO;
|
static Pipeline pipeline_last_used = PIPELINE_NO;
|
||||||
|
|
||||||
|
|
||||||
|
#define CIRCLE_VERTICES_MAX 2048
|
||||||
|
|
||||||
|
|
||||||
void use_space_pipeline(void) {
|
void use_space_pipeline(void) {
|
||||||
if (pipeline_last_used == PIPELINE_SPACE)
|
if (pipeline_last_used == PIPELINE_SPACE)
|
||||||
return;
|
return;
|
||||||
@ -166,16 +169,16 @@ void use_2d_pipeline(void) {
|
|||||||
|
|
||||||
|
|
||||||
void render_circle(const CirclePrimitive *circle) {
|
void render_circle(const CirclePrimitive *circle) {
|
||||||
SDL_Vertex *vertices = NULL;
|
static SDL_Vertex vertices[CIRCLE_VERTICES_MAX];
|
||||||
int *indices = NULL;
|
static int indices[CIRCLE_VERTICES_MAX * 3];
|
||||||
int num_vertices = (int)circle->radius;
|
int num_vertices = MIN((int)circle->radius, CIRCLE_VERTICES_MAX-1);
|
||||||
|
|
||||||
create_circle_geometry(circle->position,
|
create_circle_geometry(circle->position,
|
||||||
circle->color,
|
circle->color,
|
||||||
circle->radius,
|
circle->radius,
|
||||||
num_vertices,
|
num_vertices,
|
||||||
&vertices,
|
vertices,
|
||||||
&indices);
|
indices);
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glVertexPointer(2,
|
glVertexPointer(2,
|
||||||
@ -196,9 +199,6 @@ void render_circle(const CirclePrimitive *circle) {
|
|||||||
|
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
SDL_free(vertices);
|
|
||||||
SDL_free(indices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,6 +31,19 @@ typedef struct StringArena {
|
|||||||
static StringArena string_arena;
|
static StringArena string_arena;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct FontFileBuffer {
|
||||||
|
size_t len;
|
||||||
|
unsigned char *buffer;
|
||||||
|
} FontFileBuffer;
|
||||||
|
|
||||||
|
typedef struct FontFileCacheItem {
|
||||||
|
char *key;
|
||||||
|
FontFileBuffer value;
|
||||||
|
} FontFileCacheItem;
|
||||||
|
|
||||||
|
static FontFileCacheItem *font_file_cache_hash;
|
||||||
|
|
||||||
|
|
||||||
static void string_arena_init(StringArena *arena) {
|
static void string_arena_init(StringArena *arena) {
|
||||||
arena->head = cmalloc(sizeof *arena->head);
|
arena->head = cmalloc(sizeof *arena->head);
|
||||||
arena->current_block = arena->head;
|
arena->current_block = arena->head;
|
||||||
@ -103,12 +116,22 @@ static FontData *text_load_font_data(const char *path, int height_px) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
unsigned char *buf = NULL;
|
unsigned char *buf = NULL;
|
||||||
int64_t buf_len = file_to_bytes(path, &buf);
|
int64_t buf_len = 0;
|
||||||
|
|
||||||
|
/* if the file was already loaded just get it */
|
||||||
|
FontFileCacheItem *font_file_ptr = shgetp_null(font_file_cache_hash, path);
|
||||||
|
if (font_file_ptr != NULL) {
|
||||||
|
buf = font_file_ptr->value.buffer;
|
||||||
|
buf_len = font_file_ptr->value.len;
|
||||||
|
} else {
|
||||||
|
buf_len = file_to_bytes(path, &buf);
|
||||||
|
FontFileBuffer buffer = { buf_len, buf };
|
||||||
|
shput(font_file_cache_hash, path, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
stbtt_InitFont(&font_data->info, buf, stbtt_GetFontOffsetForIndex(buf, 0));
|
stbtt_InitFont(&font_data->info, buf, stbtt_GetFontOffsetForIndex(buf, 0));
|
||||||
|
|
||||||
/* might as well get these now, for later */
|
/* might as well get these now, for later */
|
||||||
font_data->file_bytes = buf;
|
|
||||||
font_data->file_bytes_len = buf_len;
|
|
||||||
font_data->scale_factor = stbtt_ScaleForPixelHeight(&font_data->info, (float)height_px);
|
font_data->scale_factor = stbtt_ScaleForPixelHeight(&font_data->info, (float)height_px);
|
||||||
stbtt_GetFontVMetrics(
|
stbtt_GetFontVMetrics(
|
||||||
&font_data->info,
|
&font_data->info,
|
||||||
@ -142,7 +165,6 @@ static FontData *text_load_font_data(const char *path, int height_px) {
|
|||||||
|
|
||||||
|
|
||||||
static void text_destroy_font_data(FontData *font_data) {
|
static void text_destroy_font_data(FontData *font_data) {
|
||||||
SDL_free(font_data->file_bytes);
|
|
||||||
delete_gpu_texture(font_data->texture);
|
delete_gpu_texture(font_data->texture);
|
||||||
SDL_free(font_data);
|
SDL_free(font_data);
|
||||||
}
|
}
|
||||||
@ -192,7 +214,7 @@ static void text_draw_with(FontData* font_data, char* text, Vec2 position, Color
|
|||||||
|
|
||||||
|
|
||||||
static void ensure_font_cache(const char *font_path, int height_px) {
|
static void ensure_font_cache(const char *font_path, int height_px) {
|
||||||
/* HACK: stupid, bad, don't do this */
|
/* HACK: don't */
|
||||||
bool is_cached = false;
|
bool is_cached = false;
|
||||||
for (size_t i = 0; i < arrlenu(ctx.text_cache.data); ++i) {
|
for (size_t i = 0; i < arrlenu(ctx.text_cache.data); ++i) {
|
||||||
FontData *font_data = ctx.text_cache.data[i];
|
FontData *font_data = ctx.text_cache.data[i];
|
||||||
@ -229,6 +251,8 @@ void render_text(const TextPrimitive *text) {
|
|||||||
void text_cache_init(TextCache *cache) {
|
void text_cache_init(TextCache *cache) {
|
||||||
arrsetlen(cache->data, 0);
|
arrsetlen(cache->data, 0);
|
||||||
string_arena_init(&string_arena);
|
string_arena_init(&string_arena);
|
||||||
|
|
||||||
|
sh_new_arena(font_file_cache_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -237,8 +261,13 @@ void text_cache_deinit(TextCache *cache) {
|
|||||||
text_destroy_font_data(ctx.text_cache.data[i]);
|
text_destroy_font_data(ctx.text_cache.data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
arrfree(cache->data);
|
for (size_t i = 0; i < shlenu(font_file_cache_hash); ++i) {
|
||||||
|
SDL_free(font_file_cache_hash[i].value.buffer);
|
||||||
|
}
|
||||||
|
shfree(font_file_cache_hash);
|
||||||
|
|
||||||
string_arena_deinit(&string_arena);
|
string_arena_deinit(&string_arena);
|
||||||
|
arrfree(cache->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,8 +22,6 @@ typedef struct FontData {
|
|||||||
stbtt_fontinfo info;
|
stbtt_fontinfo info;
|
||||||
|
|
||||||
const char *file_path;
|
const char *file_path;
|
||||||
unsigned char *file_bytes;
|
|
||||||
size_t file_bytes_len;
|
|
||||||
|
|
||||||
GPUTexture texture;
|
GPUTexture texture;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user