it's working on web and in window, waow
This commit is contained in:
126
src/render/render.c
Normal file
126
src/render/render.c
Normal file
@@ -0,0 +1,126 @@
|
||||
fn rn_cmd_t *rn_get_cmd(rn_cmd_kind_t kind) {
|
||||
b32 alloc_new = false;
|
||||
if (rn_state.last_cmd == NULL) {
|
||||
alloc_new = true;
|
||||
} else if (rn_state.last_cmd->kind != kind) {
|
||||
alloc_new = true;
|
||||
}
|
||||
|
||||
rn_cmd_t *result = rn_state.last_cmd;
|
||||
if (alloc_new) {
|
||||
result = ma_push_type(tcx.temp, rn_cmd_t);
|
||||
result->kind = kind;
|
||||
SLLQ_APPEND(rn_state.first_cmd, rn_state.last_cmd, result);
|
||||
|
||||
if (rn_cmd_kind_quad) {
|
||||
result->vertex = rn_state.vertices + rn_state.len;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
fn rn_vertex_t *rn_push_vertex(rn_cmd_t *cmd, u32 count) {
|
||||
rn_vertex_t *result = cmd->vertex + cmd->len;
|
||||
rn_state.len += count;
|
||||
cmd->len += count;
|
||||
return result;
|
||||
}
|
||||
|
||||
fn void rn_push_quad(r2f32_t rect, r2f32_t tex, v4f32_t color) {
|
||||
rn_cmd_t *cmd = rn_get_cmd(rn_cmd_kind_quad);
|
||||
rn_vertex_t *v = rn_push_vertex(cmd, 6);
|
||||
v[0] = (rn_vertex_t){
|
||||
{rect.min.x, rect.max.y},
|
||||
{ tex.min.x, tex.max.y},
|
||||
color
|
||||
};
|
||||
v[1] = (rn_vertex_t){
|
||||
{rect.max.x, rect.max.y},
|
||||
{ tex.max.x, tex.max.y},
|
||||
color
|
||||
};
|
||||
v[2] = (rn_vertex_t){
|
||||
{rect.min.x, rect.min.y},
|
||||
{ tex.min.x, tex.min.y},
|
||||
color
|
||||
};
|
||||
v[3] = (rn_vertex_t){
|
||||
{rect.min.x, rect.min.y},
|
||||
{ tex.min.x, tex.min.y},
|
||||
color
|
||||
};
|
||||
v[4] = (rn_vertex_t){
|
||||
{rect.max.x, rect.max.y},
|
||||
{ tex.max.x, tex.max.y},
|
||||
color
|
||||
};
|
||||
v[5] = (rn_vertex_t){
|
||||
{rect.max.x, rect.min.y},
|
||||
{ tex.max.x, tex.min.y},
|
||||
color
|
||||
};
|
||||
}
|
||||
|
||||
fn void rn_draw_rect(r2f32_t rect, v4f32_t color) {
|
||||
rn_push_quad(rect, rn_state.main_font->white_texture_bounding_box, color);
|
||||
}
|
||||
|
||||
fn void rn_draw_rect_border(r2f32_t rect, v4f32_t color, f32 border_thickness) {
|
||||
r2f32_t left = r2f32_cut_left(&rect, border_thickness);
|
||||
r2f32_t right = r2f32_cut_right(&rect, border_thickness);
|
||||
r2f32_t top = r2f32_cut_top(&rect, border_thickness);
|
||||
r2f32_t bottom = r2f32_cut_bottom(&rect, border_thickness);
|
||||
rn_push_quad(left, rn_state.main_font->white_texture_bounding_box, color);
|
||||
rn_push_quad(right, rn_state.main_font->white_texture_bounding_box, color);
|
||||
rn_push_quad(top, rn_state.main_font->white_texture_bounding_box, color);
|
||||
rn_push_quad(bottom, rn_state.main_font->white_texture_bounding_box, color);
|
||||
}
|
||||
|
||||
fn i64 rn_get_char_spacing(rn_font_t *font, u32 codepoint) {
|
||||
rn_glyph_t *g = rn_get_glyph(font, codepoint);
|
||||
if (g->xadvance) return (i64)g->xadvance;
|
||||
return (i64)g->size.x;
|
||||
}
|
||||
|
||||
fn i64 rn_get_line_spacing(rn_font_t *font) {
|
||||
i64 result = (i64)(font->ascent - font->descent + font->line_gap);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn v2f32_t rn_base_draw_string(rn_font_t *font, s8_t string, v2f32_t pos, v4f32_t color, b32 draw) {
|
||||
pos.y += rn_get_line_spacing(font) + font->descent;
|
||||
v2f32_t original_pos = pos;
|
||||
|
||||
for (utf8_iter_t iter = utf8_iterate_ex(string.str, (int)string.len); iter.item; utf8_advance(&iter)) {
|
||||
u32 codepoint = iter.item;
|
||||
rn_glyph_t *g = rn_get_glyph(font, codepoint);
|
||||
r2f32_t rect = r2f32_mindim(v2f32_add(pos, g->offset), g->size);
|
||||
if (draw && codepoint != '\n' && codepoint != ' ' && codepoint != '\t') {
|
||||
rn_push_quad(rect, g->atlas_bounding_box, color);
|
||||
}
|
||||
pos.x += g->xadvance;
|
||||
}
|
||||
|
||||
|
||||
v2f32_t result = {pos.x - original_pos.x, font->size};
|
||||
return result;
|
||||
}
|
||||
|
||||
fn v2f32_t rn_draw_string(rn_font_t *font, v2f32_t pos, v4f32_t color, s8_t string) {
|
||||
return rn_base_draw_string(font, string, pos, color, true);
|
||||
}
|
||||
|
||||
fn v2f32_t rn_draw_stringf(rn_font_t *font, v2f32_t pos, v4f32_t color, char *str, ...) {
|
||||
S8_FMT(tcx.temp, str, result);
|
||||
return rn_draw_string(font, pos, color, result);
|
||||
}
|
||||
|
||||
fn v2f32_t rn_measure_string(rn_font_t *font, s8_t string) {
|
||||
return rn_base_draw_string(font, string, v2f32(0,0), v4f32(0,0,0,0), false);
|
||||
}
|
||||
|
||||
fn void rn_set_clip(r2f32_t rect) {
|
||||
rn_cmd_t *cmd = rn_get_cmd(rn_cmd_kind_set_clip);
|
||||
cmd->rect = rect;
|
||||
}
|
||||
2950
src/render/render.gen.c
Normal file
2950
src/render/render.gen.c
Normal file
File diff suppressed because it is too large
Load Diff
85
src/render/render.h
Normal file
85
src/render/render.h
Normal file
@@ -0,0 +1,85 @@
|
||||
typedef struct rn_glyph_t rn_glyph_t;
|
||||
struct rn_glyph_t {
|
||||
v2f32_t size;
|
||||
v2f32_t offset;
|
||||
f32 xadvance;
|
||||
f32 left_side_bearing;
|
||||
r2f32_t atlas_bounding_box;
|
||||
};
|
||||
|
||||
typedef struct rn_font_t rn_font_t;
|
||||
struct rn_font_t {
|
||||
rn_glyph_t *glyphs;
|
||||
i32 glyph_count;
|
||||
|
||||
u32 first_char, last_char;
|
||||
u32 texture_id;
|
||||
|
||||
f32 size;
|
||||
f32 descent;
|
||||
f32 ascent;
|
||||
f32 line_gap;
|
||||
|
||||
r2f32_t white_texture_bounding_box;
|
||||
};
|
||||
|
||||
typedef struct rn_atlas_t rn_atlas_t;
|
||||
struct rn_atlas_t {
|
||||
u8 *bitmap;
|
||||
v2i32_t size;
|
||||
v2f32_t inverse_size;
|
||||
i32 xcursor;
|
||||
i32 ycursor;
|
||||
|
||||
i32 biggest_height;
|
||||
r2f32_t white_texture_bounding_box;
|
||||
u32 texture_id;
|
||||
};
|
||||
|
||||
typedef struct rn_shader_t rn_shader_t;
|
||||
struct rn_shader_t {
|
||||
u32 pipeline;
|
||||
u32 fshader;
|
||||
u32 vshader;
|
||||
};
|
||||
|
||||
typedef struct rn_vertex_t rn_vertex_t;
|
||||
struct rn_vertex_t {
|
||||
v2f32_t pos;
|
||||
v2f32_t tex;
|
||||
v4f32_t color;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
rn_cmd_kind_null,
|
||||
rn_cmd_kind_quad,
|
||||
rn_cmd_kind_set_clip,
|
||||
} rn_cmd_kind_t;
|
||||
|
||||
typedef struct rn_cmd_t rn_cmd_t;
|
||||
struct rn_cmd_t {
|
||||
rn_cmd_t *next;
|
||||
rn_cmd_kind_t kind;
|
||||
union {
|
||||
v4f32_t color;
|
||||
r2f32_t rect;
|
||||
struct { rn_vertex_t *vertex; u32 len; };
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct rn_state_t rn_state_t;
|
||||
struct rn_state_t {
|
||||
rn_font_t *main_font;
|
||||
rn_shader_t shader2d;
|
||||
app_frame_t *frame;
|
||||
|
||||
rn_cmd_t *first_cmd;
|
||||
rn_cmd_t *last_cmd;
|
||||
rn_vertex_t *vertices;
|
||||
u32 len;
|
||||
u32 cap;
|
||||
|
||||
u32 vao;
|
||||
u32 vbo;
|
||||
};
|
||||
gb rn_state_t rn_state;
|
||||
10
src/render/render.meta.c
Normal file
10
src/render/render.meta.c
Normal file
@@ -0,0 +1,10 @@
|
||||
void mt_render(ma_arena_t *arena) {
|
||||
sb8_t *sb = sb8_serial_begin(arena);
|
||||
sb8_printf(sb, "// automatically generated using: " __FILE__ "\n");
|
||||
|
||||
sb8_printf(sb, "gb_read_only ");
|
||||
s8_t content = OS_ReadFile(&Perm, s8_lit("../package/FiraCode-Regular.ttf"));
|
||||
mt_serial_to_cbyte_array_ex(sb, content, s8_printf(arena, "main_font_data"));
|
||||
sb8_printf(sb, "gb_read_only s8_t main_font = s8_array_lit(main_font_data);\n");
|
||||
os_write_file(mt_cpath(arena), sb8_serial_end(arena, sb));
|
||||
}
|
||||
@@ -1,41 +1,3 @@
|
||||
typedef struct rn_glyph_t rn_glyph_t;
|
||||
struct rn_glyph_t {
|
||||
v2f32_t size;
|
||||
v2f32_t offset;
|
||||
f32 xadvance;
|
||||
f32 left_side_bearing;
|
||||
r2f32_t atlas_bounding_box;
|
||||
};
|
||||
|
||||
typedef struct rn_font_t rn_font_t;
|
||||
struct rn_font_t {
|
||||
rn_glyph_t *glyphs;
|
||||
i32 glyph_count;
|
||||
|
||||
u32 first_char, last_char;
|
||||
u32 texture_id;
|
||||
|
||||
f32 size;
|
||||
f32 descent;
|
||||
f32 ascent;
|
||||
f32 line_gap;
|
||||
|
||||
r2f32_t white_texture_bounding_box;
|
||||
};
|
||||
|
||||
typedef struct rn_atlas_t rn_atlas_t;
|
||||
struct rn_atlas_t {
|
||||
u8 *bitmap;
|
||||
v2i32_t size;
|
||||
v2f32_t inverse_size;
|
||||
i32 xcursor;
|
||||
i32 ycursor;
|
||||
|
||||
i32 biggest_height;
|
||||
r2f32_t white_texture_bounding_box;
|
||||
u32 texture_id;
|
||||
};
|
||||
|
||||
rn_atlas_t *rn_create_atlas(ma_arena_t *arena, v2i32_t size) {
|
||||
rn_atlas_t *result = ma_push_type(arena, rn_atlas_t);
|
||||
result->size = size;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#include "render.h"
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#define STBTT_ifloor(x) ((int)f64_floor(x))
|
||||
#define STBTT_iceil(x) ((int)f64_ceil(x))
|
||||
@@ -13,6 +16,11 @@
|
||||
#define STBTT_strlen(x) (str_len(x))
|
||||
#define STBTT_memcpy memory_copy
|
||||
#define STBTT_memset memory_set
|
||||
#include "render/stb_truetype.h"
|
||||
#include "render/render_font.c"
|
||||
#include "render/render_opengl.c"
|
||||
#include "stb_truetype.h"
|
||||
#include "render_font.c"
|
||||
#include "render.c"
|
||||
#include "render.gen.c"
|
||||
#include "render_opengl.c"
|
||||
#else
|
||||
#include "render_wasm_canvas.c"
|
||||
#endif
|
||||
@@ -1,50 +1,3 @@
|
||||
typedef struct rn_shader_t rn_shader_t;
|
||||
struct rn_shader_t {
|
||||
u32 pipeline;
|
||||
u32 fshader;
|
||||
u32 vshader;
|
||||
};
|
||||
|
||||
typedef struct rn_vertex_t rn_vertex_t;
|
||||
struct rn_vertex_t {
|
||||
v2f32_t pos;
|
||||
v2f32_t tex;
|
||||
v4f32_t color;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
rn_cmd_kind_null,
|
||||
rn_cmd_kind_quad,
|
||||
rn_cmd_kind_set_clip,
|
||||
} rn_cmd_kind_t;
|
||||
|
||||
typedef struct rn_cmd_t rn_cmd_t;
|
||||
struct rn_cmd_t {
|
||||
rn_cmd_t *next;
|
||||
rn_cmd_kind_t kind;
|
||||
union {
|
||||
v4f32_t color;
|
||||
r2f32_t rect;
|
||||
struct { rn_vertex_t *vertex; u32 len; };
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct rn_state_t rn_state_t;
|
||||
struct rn_state_t {
|
||||
rn_font_t *main_font;
|
||||
rn_shader_t shader2d;
|
||||
|
||||
rn_cmd_t *first_cmd;
|
||||
rn_cmd_t *last_cmd;
|
||||
rn_vertex_t *vertices;
|
||||
u32 len;
|
||||
u32 cap;
|
||||
|
||||
u32 vao;
|
||||
u32 vbo;
|
||||
};
|
||||
gb rn_state_t rn_state;
|
||||
|
||||
fn rn_shader_t rn_create_shader(char *glsl_vshader, char *glsl_fshader) {
|
||||
rn_shader_t result = {};
|
||||
result.vshader = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vshader);
|
||||
@@ -79,133 +32,6 @@ fn void gl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity
|
||||
}
|
||||
}
|
||||
|
||||
fn rn_cmd_t *rn_get_cmd(rn_cmd_kind_t kind) {
|
||||
b32 alloc_new = false;
|
||||
if (rn_state.last_cmd == NULL) {
|
||||
alloc_new = true;
|
||||
} else if (rn_state.last_cmd->kind != kind) {
|
||||
alloc_new = true;
|
||||
}
|
||||
|
||||
rn_cmd_t *result = rn_state.last_cmd;
|
||||
if (alloc_new) {
|
||||
result = ma_push_type(tcx.temp, rn_cmd_t);
|
||||
result->kind = kind;
|
||||
SLLQ_APPEND(rn_state.first_cmd, rn_state.last_cmd, result);
|
||||
|
||||
if (rn_cmd_kind_quad) {
|
||||
result->vertex = rn_state.vertices + rn_state.len;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
fn rn_vertex_t *rn_push_vertex(rn_cmd_t *cmd, u32 count) {
|
||||
rn_vertex_t *result = cmd->vertex + cmd->len;
|
||||
rn_state.len += count;
|
||||
cmd->len += count;
|
||||
return result;
|
||||
}
|
||||
|
||||
fn void rn_push_quad(r2f32_t rect, r2f32_t tex, v4f32_t color) {
|
||||
rn_cmd_t *cmd = rn_get_cmd(rn_cmd_kind_quad);
|
||||
rn_vertex_t *v = rn_push_vertex(cmd, 6);
|
||||
v[0] = (rn_vertex_t){
|
||||
{rect.min.x, rect.max.y},
|
||||
{ tex.min.x, tex.max.y},
|
||||
color
|
||||
};
|
||||
v[1] = (rn_vertex_t){
|
||||
{rect.max.x, rect.max.y},
|
||||
{ tex.max.x, tex.max.y},
|
||||
color
|
||||
};
|
||||
v[2] = (rn_vertex_t){
|
||||
{rect.min.x, rect.min.y},
|
||||
{ tex.min.x, tex.min.y},
|
||||
color
|
||||
};
|
||||
v[3] = (rn_vertex_t){
|
||||
{rect.min.x, rect.min.y},
|
||||
{ tex.min.x, tex.min.y},
|
||||
color
|
||||
};
|
||||
v[4] = (rn_vertex_t){
|
||||
{rect.max.x, rect.max.y},
|
||||
{ tex.max.x, tex.max.y},
|
||||
color
|
||||
};
|
||||
v[5] = (rn_vertex_t){
|
||||
{rect.max.x, rect.min.y},
|
||||
{ tex.max.x, tex.min.y},
|
||||
color
|
||||
};
|
||||
}
|
||||
|
||||
fn void rn_draw_rect(r2f32_t rect, v4f32_t color) {
|
||||
rn_push_quad(rect, rn_state.main_font->white_texture_bounding_box, color);
|
||||
}
|
||||
|
||||
fn void rn_draw_rect_border(r2f32_t rect, v4f32_t color, f32 border_thickness) {
|
||||
r2f32_t left = r2f32_cut_left(&rect, border_thickness);
|
||||
r2f32_t right = r2f32_cut_right(&rect, border_thickness);
|
||||
r2f32_t top = r2f32_cut_top(&rect, border_thickness);
|
||||
r2f32_t bottom = r2f32_cut_bottom(&rect, border_thickness);
|
||||
rn_push_quad(left, rn_state.main_font->white_texture_bounding_box, color);
|
||||
rn_push_quad(right, rn_state.main_font->white_texture_bounding_box, color);
|
||||
rn_push_quad(top, rn_state.main_font->white_texture_bounding_box, color);
|
||||
rn_push_quad(bottom, rn_state.main_font->white_texture_bounding_box, color);
|
||||
}
|
||||
|
||||
fn i64 rn_get_char_spacing(rn_font_t *font, u32 codepoint) {
|
||||
rn_glyph_t *g = rn_get_glyph(font, codepoint);
|
||||
if (g->xadvance) return (i64)g->xadvance;
|
||||
return (i64)g->size.x;
|
||||
}
|
||||
|
||||
fn i64 rn_get_line_spacing(rn_font_t *font) {
|
||||
i64 result = (i64)(font->ascent - font->descent + font->line_gap);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn v2f32_t rn_base_draw_string(rn_font_t *font, s8_t string, v2f32_t pos, v4f32_t color, b32 draw) {
|
||||
pos.y += rn_get_line_spacing(font) + font->descent;
|
||||
v2f32_t original_pos = pos;
|
||||
|
||||
for (utf8_iter_t iter = utf8_iterate_ex(string.str, (int)string.len); iter.item; utf8_advance(&iter)) {
|
||||
u32 codepoint = iter.item;
|
||||
rn_glyph_t *g = rn_get_glyph(font, codepoint);
|
||||
r2f32_t rect = r2f32_mindim(v2f32_add(pos, g->offset), g->size);
|
||||
if (draw && codepoint != '\n' && codepoint != ' ' && codepoint != '\t') {
|
||||
rn_push_quad(rect, g->atlas_bounding_box, color);
|
||||
}
|
||||
pos.x += g->xadvance;
|
||||
}
|
||||
|
||||
|
||||
v2f32_t result = {pos.x - original_pos.x, font->size};
|
||||
return result;
|
||||
}
|
||||
|
||||
fn v2f32_t rn_draw_string(rn_font_t *font, v2f32_t pos, v4f32_t color, s8_t string) {
|
||||
return rn_base_draw_string(font, string, pos, color, true);
|
||||
}
|
||||
|
||||
fn v2f32_t rn_draw_stringf(rn_font_t *font, v2f32_t pos, v4f32_t color, char *str, ...) {
|
||||
S8_FMT(tcx.temp, str, result);
|
||||
return rn_draw_string(font, pos, color, result);
|
||||
}
|
||||
|
||||
fn v2f32_t rn_measure_string(rn_font_t *font, s8_t string) {
|
||||
return rn_base_draw_string(font, string, v2f32(0,0), v4f32(0,0,0,0), false);
|
||||
}
|
||||
|
||||
fn void rn_set_clip(r2f32_t rect) {
|
||||
rn_cmd_t *cmd = rn_get_cmd(rn_cmd_kind_set_clip);
|
||||
cmd->rect = rect;
|
||||
}
|
||||
|
||||
fn void rn_reload_font(s8_t font_data, f32 font_size) {
|
||||
if (rn_state.main_font->texture_id) {
|
||||
glDeleteTextures(1, &rn_state.main_font->texture_id);
|
||||
@@ -227,13 +53,12 @@ fn void rn_reload_font(s8_t font_data, f32 font_size) {
|
||||
ma_end_scratch(scratch);
|
||||
}
|
||||
|
||||
fn void rn_init(ma_arena_t *perm, s8_t font_data, f32 font_size) {
|
||||
fn void rn_init(ma_arena_t *perm, f32 font_size) {
|
||||
rn_state.cap = 1024*256;
|
||||
rn_state.vertices = ma_push_array(perm, rn_vertex_t, rn_state.cap);
|
||||
|
||||
rn_state.main_font = rn_create_font(perm);
|
||||
rn_reload_font(font_data, font_size);
|
||||
|
||||
rn_reload_font(main_font, font_size);
|
||||
|
||||
glDebugMessageCallback(&gl_debug_callback, NULL);
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
@@ -301,12 +126,13 @@ fn void rn_init(ma_arena_t *perm, s8_t font_data, f32 font_size) {
|
||||
rn_state.shader2d = rn_create_shader(glsl_vshader, glsl_fshader);
|
||||
}
|
||||
|
||||
void rn_begin(void) {
|
||||
void rn_begin(app_frame_t *frame) {
|
||||
rn_state.frame = frame;
|
||||
}
|
||||
|
||||
void rn_end(v2f32_t window_size, v4f32_t color) {
|
||||
f32 wx = window_size.x;
|
||||
f32 wy = window_size.y;
|
||||
void rn_end(void) {
|
||||
f32 wx = rn_state.frame->window_size.x;
|
||||
f32 wy = rn_state.frame->window_size.y;
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
@@ -315,7 +141,7 @@ void rn_end(v2f32_t window_size, v4f32_t color) {
|
||||
|
||||
glViewport(0, 0, (GLsizei)wx, (GLsizei)wy);
|
||||
glScissor(0, 0, (GLsizei)wx, (GLsizei)wy);
|
||||
glClearColor(color.r, color.g, color.b, color.a);
|
||||
glClearColor(1,1,1,1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
// Default draw using the font texture
|
||||
@@ -338,7 +164,7 @@ void rn_end(v2f32_t window_size, v4f32_t color) {
|
||||
GLsizei h = (GLsizei)(it->rect.max.y - y);
|
||||
if (w <= 0) w = 0;
|
||||
if (h <= 0) h = 0;
|
||||
glScissor(x, (GLint)window_size.y - (GLint)it->rect.max.y, w, h);
|
||||
glScissor(x, (GLint)wy - (GLint)it->rect.max.y, w, h);
|
||||
} else_is_invalid;
|
||||
}
|
||||
|
||||
|
||||
66
src/render/render_wasm_canvas.c
Normal file
66
src/render/render_wasm_canvas.c
Normal file
@@ -0,0 +1,66 @@
|
||||
fn_wasm_import void wasm_clear(void);
|
||||
fn_wasm_import void wasm_draw_text(isize str, i32 len, f32 x, f32 y, isize font_str, i32 font_len, i32 font_size, f32 r, f32 g, f32 b, f32 a);
|
||||
fn_wasm_import void wasm_draw_rect(f32 x, f32 y, f32 w, f32 h, f32 r, f32 g, f32 b, f32 a);
|
||||
fn_wasm_import f32 wasm_measure_text(isize str, i32 len, isize font_str, i32 font_len, i32 font_size);
|
||||
fn_wasm_import f32 wasm_get_font_height(isize font_str, i32 font_len, i32 font_size);
|
||||
fn_wasm_import void wasm_set_clip(f32 x, f32 y, f32 w, f32 h);
|
||||
|
||||
gb_read_only s8_t font_face = s8_const_lit("consolas");
|
||||
|
||||
typedef struct rn_font_t rn_font_t;
|
||||
struct rn_font_t {
|
||||
f32 size;
|
||||
};
|
||||
|
||||
typedef struct rn_state_t rn_state_t;
|
||||
struct rn_state_t {
|
||||
rn_font_t *main_font;
|
||||
app_frame_t *frame;
|
||||
};
|
||||
rn_state_t rn_state;
|
||||
|
||||
// fn f64 get_font_height(void) {
|
||||
// return wasm_get_font_height((isize) font_face.str, font_face.len, m*wasm_dpr) / wasm_dpr;
|
||||
// }
|
||||
|
||||
fn void rn_init(ma_arena_t *perm, f32 font_size) {
|
||||
rn_state.main_font = ma_push_type(perm, rn_font_t);
|
||||
rn_state.main_font->size = font_size;
|
||||
}
|
||||
|
||||
fn void rn_draw_rect(r2f32_t rect, v4f32_t color) {
|
||||
wasm_draw_rect(wasm_dpr * rect.min.x, wasm_dpr * rect.min.y, wasm_dpr * (rect.max.x - rect.min.x), wasm_dpr * (rect.max.y - rect.min.y), color.r * 255.f, color.g * 255.f, color.b * 255.f, color.a);
|
||||
}
|
||||
|
||||
fn void rn_draw_rect_border(r2f32_t rect, v4f32_t color, f32 border_thickness) {
|
||||
}
|
||||
|
||||
fn v2f32_t rn_measure_string(rn_font_t *font, s8_t string) {
|
||||
f32 x = wasm_measure_text((isize)string.str, string.len, (isize) font_face.str, font_face.len, rn_state.main_font->size) / wasm_dpr;
|
||||
return (v2f32_t){x, rn_state.main_font->size};
|
||||
}
|
||||
|
||||
fn v2f32_t rn_draw_string(rn_font_t *font, v2f32_t pos, v4f32_t color, s8_t string) {
|
||||
wasm_draw_text((isize)string.str, string.len, wasm_dpr * pos.x, wasm_dpr * pos.y, (isize) font_face.str, font_face.len, rn_state.main_font->size, color.r * 255.f, color.g * 255.f, color.b * 255.f, color.a);
|
||||
v2f32_t size = rn_measure_string(font, string);
|
||||
return size;
|
||||
}
|
||||
|
||||
fn v2f32_t rn_draw_stringf(rn_font_t *font, v2f32_t pos, v4f32_t color, char *str, ...) {
|
||||
S8_FMT(tcx.temp, str, string);
|
||||
return rn_draw_string(font, pos, color, string);
|
||||
}
|
||||
|
||||
fn void rn_set_clip(r2f32_t rect) {
|
||||
wasm_set_clip(wasm_dpr * rect.min.x, wasm_dpr * rect.min.y, wasm_dpr * (rect.max.x - rect.min.x), wasm_dpr * (rect.max.y - rect.min.y));
|
||||
}
|
||||
|
||||
fn void rn_begin(app_frame_t *frame) {
|
||||
rn_state.frame = frame;
|
||||
r2f32_t window_rect = r2f32(0, 0, rn_state.frame->window_size.x, rn_state.frame->window_size.y);
|
||||
wasm_clear();
|
||||
rn_draw_rect(window_rect, white_color_global);
|
||||
}
|
||||
|
||||
fn void rn_end() {
|
||||
}
|
||||
Reference in New Issue
Block a user