diff --git a/src/gfx2d/gfx2d.c b/src/gfx2d/gfx2d.c deleted file mode 100644 index 263c7a4..0000000 --- a/src/gfx2d/gfx2d.c +++ /dev/null @@ -1,146 +0,0 @@ -fn_wasm_import void wasm_clear(void); -fn_wasm_import void wasm_draw_text(isize str, i32 len, f64 x, f64 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(f64 x, f64 y, f64 w, f64 h, f32 r, f32 g, f32 b, f32 a); -fn_wasm_import f64 wasm_measure_text(isize str, i32 len, isize font_str, i32 font_len, i32 font_size); -fn_wasm_import f64 wasm_get_font_height(isize font_str, i32 font_len, i32 font_size); -fn_wasm_import void wasm_set_clip(f64 x, f64 y, f64 w, f64 h); - - -// gb_read_only s8_t font_face = s8_const_lit("open_sans_regular"); -gb_read_only s8_t font_face = s8_const_lit("consolas"); - -fn void set_clip(r2f64_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 f64 get_font_height(void) { - return wasm_get_font_height((isize) font_face.str, font_face.len, 20*wasm_dpr) / wasm_dpr; -} - -fn f64 measure_text_ex(s8_t string) { - return wasm_measure_text((isize)string.str, string.len, (isize) font_face.str, font_face.len, 20*wasm_dpr) / wasm_dpr; -} - -fn f64 measure_text(char *str) { - return measure_text_ex(s8_from_char(str)); -} - -fn void draw_text(v2f64_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, 20*wasm_dpr, color.r * 255.f, color.g * 255.f, color.b * 255.f, color.a); -} - -fn void draw_textf(v2f64_t pos, char *str, ...) { - char buff[1024]; - va_list args; - va_start(args, str); - i32 len = stbsp_vsnprintf(buff, sizeof(buff), str, args); - va_end(args); - - wasm_draw_text((isize)buff, len, wasm_dpr * pos.x, wasm_dpr * pos.y, (isize) font_face.str, font_face.len, 20*wasm_dpr, 0, 0, 0, 1); -} - -fn void draw_rect(r2f64_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); -} - -typedef enum { - gfx_kind_null, - gfx_kind_clear, - gfx_kind_draw_rect, - gfx_kind_draw_text, - gfx_kind_set_clip, -} gfx_kind_t; - -typedef struct gfx_cmd_t gfx_cmd_t; -struct gfx_cmd_t { - gfx_cmd_t *next; - gfx_kind_t kind; - r2f64_t rect; - v4f32_t color; - s8_t text; -}; - -typedef struct gfx_t gfx_t; -struct gfx_t { - gfx_cmd_t *first; - gfx_cmd_t *last; - app_event_t *ev; -}; - -// @todo: -typedef struct gfx_group_t gfx_group_t; -struct gfx_group_t { - gfx_cmd_t *first; - gfx_cmd_t *last; -}; - -void gfx_begin(gfx_t *gfx, app_event_t *ev) { - gfx->ev = ev; -} - -void gfx_end(gfx_t *gfx) { - app_event_t *ev = gfx->ev; - r2f64_t window = (r2f64_t){0, 0, ev->window_size.x, ev->window_size.y}; - for (gfx_cmd_t *cmd = gfx->first; cmd; cmd = cmd->next) { - if (cmd->kind == gfx_kind_clear) { - wasm_clear(); - draw_rect(window, cmd->color); - } else if (cmd->kind == gfx_kind_draw_rect) { - draw_rect(cmd->rect, cmd->color); - } else if (cmd->kind == gfx_kind_draw_text) { - draw_text(cmd->rect.min, cmd->color, cmd->text); - } else if (cmd->kind == gfx_kind_set_clip) { - set_clip(cmd->rect); - } else { - invalid_codepath; - } - } - - gfx->first = gfx->last = NULL; -} - -void gfx_add_cmd(gfx_t *gfx, gfx_cmd_t cmd) { - gfx_cmd_t *c = ma_push_type(tcx.temp, gfx_cmd_t); - *c = cmd; - SLLQ_APPEND(gfx->first, gfx->last, c); -} - -void gfx_clear(gfx_t *gfx, v4f32_t color) { - gfx_add_cmd(gfx, (gfx_cmd_t){ - .kind = gfx_kind_clear, - .color = color, - }); -} - -void gfx_rect(gfx_t *gfx, r2f64_t rect, v4f32_t color) { - gfx_add_cmd(gfx, (gfx_cmd_t){ - .kind = gfx_kind_draw_rect, - .color = color, - .rect = rect, - }); -} - -void gfx_set_clip(gfx_t *gfx, r2f64_t rect) { - gfx_add_cmd(gfx, (gfx_cmd_t){ - .kind = gfx_kind_set_clip, - .rect = rect, - }); -} - -void gfx_text(gfx_t *gfx, v2f64_t pos, v4f32_t color, s8_t string) { - gfx_add_cmd(gfx, (gfx_cmd_t){ - .kind = gfx_kind_draw_text, - .text = s8_copy(tcx.temp, string), - .color = color, - .rect.min = pos, - }); -} -void gfx_textf(gfx_t *gfx, v2f64_t pos, v4f32_t color, char *str, ...) { - S8_FMT(tcx.temp, str, text); - gfx_add_cmd(gfx, (gfx_cmd_t){ - .kind = gfx_kind_draw_text, - .text = text, - .color = color, - .rect.min = pos, - }); -} \ No newline at end of file diff --git a/src/render/render_opengl.c b/src/render/render_opengl.c index 3e6071e..0e21e97 100644 --- a/src/render/render_opengl.c +++ b/src/render/render_opengl.c @@ -34,7 +34,6 @@ typedef struct rn_state_t rn_state_t; struct rn_state_t { rn_font_t main_font; rn_shader_t shader2d; - v2f32_t window_size; rn_cmd_t *first_cmd; rn_cmd_t *last_cmd; @@ -81,102 +80,6 @@ void gl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, G } } -void rn_begin(v2f32_t window_size) { - rn_state.window_size = window_size; -} - -void rn_init(ma_arena_t *perm) { - rn_state.cap = 1024*64; - rn_state.vertices = ma_push_array(perm, rn_vertex_t, rn_state.cap); - - { - ma_temp_t scratch = ma_begin_scratch1(perm); - s8_t font_data = rn_get_default_font(tcx.temp); - rn_atlas_t *atlas = rn_create_atlas(scratch.arena, (v2i32_t){2048, 2048}); - - u32 font_size = 100; - rn_state.main_font = rn_create_font(perm, font_data, atlas, font_size); - - GLint filter = GL_NEAREST; - // if (StyleFontFilter == 1) filter = GL_LINEAR; - glCreateTextures(GL_TEXTURE_2D, 1, &atlas->texture_id); - glTextureParameteri(atlas->texture_id, GL_TEXTURE_MIN_FILTER, filter); - glTextureParameteri(atlas->texture_id, GL_TEXTURE_MAG_FILTER, filter); - glTextureParameteri(atlas->texture_id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTextureParameteri(atlas->texture_id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTextureStorage2D(atlas->texture_id, 1, GL_R8, (GLsizei)atlas->size.x, (GLsizei)atlas->size.y); - glTextureSubImage2D(atlas->texture_id, 0, 0, 0, (GLsizei)atlas->size.x, (GLsizei)atlas->size.y, GL_RED, GL_UNSIGNED_BYTE, atlas->bitmap); - rn_state.main_font.texture_id = atlas->texture_id; - ma_end_scratch(scratch); - } - - - glDebugMessageCallback(&gl_debug_callback, NULL); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - - glCreateBuffers(1, &rn_state.vbo); - glNamedBufferStorage(rn_state.vbo, rn_state.cap * sizeof(rn_vertex_t), 0, GL_DYNAMIC_STORAGE_BIT); - - glCreateVertexArrays(1, &rn_state.vao); - - GLint vbuf_index = 0; - glVertexArrayVertexBuffer(rn_state.vao, vbuf_index, rn_state.vbo, 0, sizeof(struct rn_vertex_t)); - - GLint a_pos = 0; - glVertexArrayAttribFormat(rn_state.vao, a_pos, 2, GL_FLOAT, GL_FALSE, offsetof(struct rn_vertex_t, pos)); - glVertexArrayAttribBinding(rn_state.vao, a_pos, vbuf_index); - glEnableVertexArrayAttrib(rn_state.vao, a_pos); - - GLint a_tex = 1; - glVertexArrayAttribFormat(rn_state.vao, a_tex, 2, GL_FLOAT, GL_FALSE, offsetof(struct rn_vertex_t, tex)); - glVertexArrayAttribBinding(rn_state.vao, a_tex, vbuf_index); - glEnableVertexArrayAttrib(rn_state.vao, a_tex); - - GLint a_color = 2; - glVertexArrayAttribFormat(rn_state.vao, a_color, 4, GL_FLOAT, GL_FALSE, offsetof(struct rn_vertex_t, color)); - glVertexArrayAttribBinding(rn_state.vao, a_color, vbuf_index); - glEnableVertexArrayAttrib(rn_state.vao, a_color); - - char *glsl_vshader = - "#version 450 core\n" - "layout(location=0) uniform vec2 U_InvHalfScreenSize;\n" - "layout(location=0) in vec2 VPos;\n" - "layout(location=1) in vec2 VTex;\n" - "layout(location=2) in vec4 VColor;\n" - "\n" - "out gl_PerVertex { vec4 gl_Position; }; // required because of ARB_separate_shader_objects\n" - "out vec2 FUV;\n" - "out vec4 FColor;\n" - "\n" - "void main() {\n" - " vec2 pos = VPos * U_InvHalfScreenSize;\n" - " pos.y = 2 - pos.y; // invert y axis\n" - " pos -= vec2(1, 1); // convert to 0,1 range\n" - "\n" - " gl_Position = vec4(pos, 0, 1);\n" - " FUV = VTex;\n" - "\n" - " FColor = VColor;\n" - "}\n"; - - char *glsl_fshader = - "#version 450 core\n" - "\n" - "in vec2 FUV;\n" - "in vec4 FColor;\n" - "\n" - "layout (binding=0) uniform sampler2D S_Texture;\n" - "layout (location=0) out vec4 OutColor;\n" - "\n" - "void main() {\n" - " vec4 c = FColor;\n" - " c.a *= texture(S_Texture, FUV).r;\n" - " OutColor = c;\n" - "}\n"; - - rn_state.shader2d = rn_create_shader(glsl_vshader, glsl_fshader); -} - rn_cmd_t *rn_get_cmd(rn_cmd_kind_t kind) { b32 alloc_new = false; if (rn_state.last_cmd == NULL) { @@ -274,6 +177,109 @@ v2f32_t rn_base_draw_string(rn_font_t *font, s8_t string, v2f32_t pos, v4f32_t c return result; } +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); +} + +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); +} + +void rn_init(ma_arena_t *perm) { + rn_state.cap = 1024*64; + rn_state.vertices = ma_push_array(perm, rn_vertex_t, rn_state.cap); + + { + ma_temp_t scratch = ma_begin_scratch1(perm); + s8_t font_data = rn_get_default_font(tcx.temp); + rn_atlas_t *atlas = rn_create_atlas(scratch.arena, (v2i32_t){2048, 2048}); + + u32 font_size = 100; + rn_state.main_font = rn_create_font(perm, font_data, atlas, font_size); + + GLint filter = GL_NEAREST; + // if (StyleFontFilter == 1) filter = GL_LINEAR; + glCreateTextures(GL_TEXTURE_2D, 1, &atlas->texture_id); + glTextureParameteri(atlas->texture_id, GL_TEXTURE_MIN_FILTER, filter); + glTextureParameteri(atlas->texture_id, GL_TEXTURE_MAG_FILTER, filter); + glTextureParameteri(atlas->texture_id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTextureParameteri(atlas->texture_id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTextureStorage2D(atlas->texture_id, 1, GL_R8, (GLsizei)atlas->size.x, (GLsizei)atlas->size.y); + glTextureSubImage2D(atlas->texture_id, 0, 0, 0, (GLsizei)atlas->size.x, (GLsizei)atlas->size.y, GL_RED, GL_UNSIGNED_BYTE, atlas->bitmap); + rn_state.main_font.texture_id = atlas->texture_id; + ma_end_scratch(scratch); + } + + + glDebugMessageCallback(&gl_debug_callback, NULL); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + + glCreateBuffers(1, &rn_state.vbo); + glNamedBufferStorage(rn_state.vbo, rn_state.cap * sizeof(rn_vertex_t), 0, GL_DYNAMIC_STORAGE_BIT); + + glCreateVertexArrays(1, &rn_state.vao); + + GLint vbuf_index = 0; + glVertexArrayVertexBuffer(rn_state.vao, vbuf_index, rn_state.vbo, 0, sizeof(struct rn_vertex_t)); + + GLint a_pos = 0; + glVertexArrayAttribFormat(rn_state.vao, a_pos, 2, GL_FLOAT, GL_FALSE, offsetof(struct rn_vertex_t, pos)); + glVertexArrayAttribBinding(rn_state.vao, a_pos, vbuf_index); + glEnableVertexArrayAttrib(rn_state.vao, a_pos); + + GLint a_tex = 1; + glVertexArrayAttribFormat(rn_state.vao, a_tex, 2, GL_FLOAT, GL_FALSE, offsetof(struct rn_vertex_t, tex)); + glVertexArrayAttribBinding(rn_state.vao, a_tex, vbuf_index); + glEnableVertexArrayAttrib(rn_state.vao, a_tex); + + GLint a_color = 2; + glVertexArrayAttribFormat(rn_state.vao, a_color, 4, GL_FLOAT, GL_FALSE, offsetof(struct rn_vertex_t, color)); + glVertexArrayAttribBinding(rn_state.vao, a_color, vbuf_index); + glEnableVertexArrayAttrib(rn_state.vao, a_color); + + char *glsl_vshader = + "#version 450 core\n" + "layout(location=0) uniform vec2 U_InvHalfScreenSize;\n" + "layout(location=0) in vec2 VPos;\n" + "layout(location=1) in vec2 VTex;\n" + "layout(location=2) in vec4 VColor;\n" + "\n" + "out gl_PerVertex { vec4 gl_Position; }; // required because of ARB_separate_shader_objects\n" + "out vec2 FUV;\n" + "out vec4 FColor;\n" + "\n" + "void main() {\n" + " vec2 pos = VPos * U_InvHalfScreenSize;\n" + " pos.y = 2 - pos.y; // invert y axis\n" + " pos -= vec2(1, 1); // convert to 0,1 range\n" + "\n" + " gl_Position = vec4(pos, 0, 1);\n" + " FUV = VTex;\n" + "\n" + " FColor = VColor;\n" + "}\n"; + + char *glsl_fshader = + "#version 450 core\n" + "\n" + "in vec2 FUV;\n" + "in vec4 FColor;\n" + "\n" + "layout (binding=0) uniform sampler2D S_Texture;\n" + "layout (location=0) out vec4 OutColor;\n" + "\n" + "void main() {\n" + " vec4 c = FColor;\n" + " c.a *= texture(S_Texture, FUV).r;\n" + " OutColor = c;\n" + "}\n"; + + rn_state.shader2d = rn_create_shader(glsl_vshader, glsl_fshader); +} + +void rn_begin(void) { +} + void rn_end(v2f32_t window_size, v4f32_t color) { f32 wx = window_size.x; f32 wy = window_size.y; @@ -303,4 +309,8 @@ void rn_end(v2f32_t window_size, v4f32_t color) { glDrawArrays(GL_TRIANGLES, 0, it->len); } else_is_invalid; } + + rn_state.first_cmd = NULL; + rn_state.last_cmd = NULL; + rn_state.len = 0; } diff --git a/src/wasm_app/main.c b/src/wasm_app/main.c index f4db017..0ebf5cd 100644 --- a/src/wasm_app/main.c +++ b/src/wasm_app/main.c @@ -95,8 +95,8 @@ fn b32 app_update(app_event_list_t events) { { app_event_t *ev = events.last; - rn_begin(v2f64_to_v2f32(ev->window_size)); - rn_base_draw_string(&rn_state.main_font, s8_lit("hello world!"), v2f32(0,0), black_color_global, true); + rn_begin(); + rn_draw_string(&rn_state.main_font, v2f32(0,0), black_color_global, s8_lit("hello world!")); rn_end(v2f64_to_v2f32(ev->window_size), white_color_global); }