From efa15151216425f85f36b0feef5b62fc77397de6 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 25 Jul 2019 00:17:01 -0700 Subject: [PATCH] Batched rendering 50% --- 4coder_base_types.cpp | 20 ++ 4coder_generated/app_functions.h | 6 +- 4ed_api_implementation.cpp | 7 +- 4ed_app_target.cpp | 2 - 4ed_font_interface.h | 2 +- 4ed_font_set.cpp | 1 + 4ed_render_format.cpp | 225 ------------- 4ed_render_format.h | 72 ----- 4ed_render_target.cpp | 417 ++++++++++++++++++++----- 4ed_render_target.h | 37 ++- 4ed_view.cpp | 3 +- opengl/4ed_opengl_funcs.h | 1 + opengl/4ed_opengl_render.cpp | 157 +++++++--- platform_all/4ed_shared_init_logic.cpp | 4 +- platform_win32/win32_4ed.cpp | 1 - 15 files changed, 527 insertions(+), 428 deletions(-) delete mode 100644 4ed_render_format.cpp delete mode 100644 4ed_render_format.h diff --git a/4coder_base_types.cpp b/4coder_base_types.cpp index 7ac891fc..249a40b1 100644 --- a/4coder_base_types.cpp +++ b/4coder_base_types.cpp @@ -1426,6 +1426,26 @@ operator!=(Vec4_f32 a, Vec4_f32 b){ //////////////////////////////// +static b32 +operator==(Rect_i32 a, Rect_i32 b){ + return(a.p0 == b.p0 && a.p0 == b.p0); +} +static b32 +operator==(Rect_f32 a, Rect_f32 b){ + return(a.p0 == b.p0 && a.p0 == b.p0); +} + +static b32 +operator!=(Rect_i32 a, Rect_i32 b){ + return(!(a == b)); +} +static b32 +operator!=(Rect_f32 a, Rect_f32 b){ + return(!(a == b)); +} + +//////////////////////////////// + static f32 lerp(f32 a, f32 t, f32 b){ return(a + (b-a)*t); diff --git a/4coder_generated/app_functions.h b/4coder_generated/app_functions.h index a5bb2145..d79c63a1 100644 --- a/4coder_generated/app_functions.h +++ b/4coder_generated/app_functions.h @@ -162,7 +162,7 @@ struct Application_Links; #define GET_STRING_ADVANCE_SIG(n) f32 n(Application_Links *app, Face_ID font_id, String_Const_u8 str) #define DRAW_RECTANGLE_SIG(n) void n(Application_Links *app, Rect_f32 rect, int_color color) #define DRAW_RECTANGLE_OUTLINE_SIG(n) void n(Application_Links *app, f32_Rect rect, int_color color) -#define DRAW_CLIP_PUSH_SIG(n) void n(Application_Links *app, f32_Rect clip_box) +#define DRAW_CLIP_PUSH_SIG(n) void n(Application_Links *app, Rect_f32 clip_box) #define DRAW_CLIP_POP_SIG(n) f32_Rect n(Application_Links *app) #define DRAW_COORDINATE_CENTER_PUSH_SIG(n) void n(Application_Links *app, Vec2 point) #define DRAW_COORDINATE_CENTER_POP_SIG(n) Vec2 n(Application_Links *app) @@ -1070,7 +1070,7 @@ static Vec2 draw_string(Application_Links *app, Face_ID font_id, String_Const_u8 static f32 get_string_advance(Application_Links *app, Face_ID font_id, String_Const_u8 str){return(app->get_string_advance(app, font_id, str));} static void draw_rectangle(Application_Links *app, Rect_f32 rect, int_color color){(app->draw_rectangle(app, rect, color));} static void draw_rectangle_outline(Application_Links *app, f32_Rect rect, int_color color){(app->draw_rectangle_outline(app, rect, color));} -static void draw_clip_push(Application_Links *app, f32_Rect clip_box){(app->draw_clip_push(app, clip_box));} +static void draw_clip_push(Application_Links *app, Rect_f32 clip_box){(app->draw_clip_push(app, clip_box));} static f32_Rect draw_clip_pop(Application_Links *app){return(app->draw_clip_pop(app));} static void draw_coordinate_center_push(Application_Links *app, Vec2 point){(app->draw_coordinate_center_push(app, point));} static Vec2 draw_coordinate_center_pop(Application_Links *app){return(app->draw_coordinate_center_pop(app));} @@ -1250,7 +1250,7 @@ static Vec2 draw_string(Application_Links *app, Face_ID font_id, String_Const_u8 static f32 get_string_advance(Application_Links *app, Face_ID font_id, String_Const_u8 str){return(app->get_string_advance_(app, font_id, str));} static void draw_rectangle(Application_Links *app, Rect_f32 rect, int_color color){(app->draw_rectangle_(app, rect, color));} static void draw_rectangle_outline(Application_Links *app, f32_Rect rect, int_color color){(app->draw_rectangle_outline_(app, rect, color));} -static void draw_clip_push(Application_Links *app, f32_Rect clip_box){(app->draw_clip_push_(app, clip_box));} +static void draw_clip_push(Application_Links *app, Rect_f32 clip_box){(app->draw_clip_push_(app, clip_box));} static f32_Rect draw_clip_pop(Application_Links *app){return(app->draw_clip_pop_(app));} static void draw_coordinate_center_push(Application_Links *app, Vec2 point){(app->draw_coordinate_center_push_(app, point));} static Vec2 draw_coordinate_center_pop(Application_Links *app){return(app->draw_coordinate_center_pop_(app));} diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index f9c4a3c8..97edd57b 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -3666,17 +3666,16 @@ Draw_Rectangle_Outline(Application_Links *app, f32_Rect rect, int_color color) } API_EXPORT void -Draw_Clip_Push(Application_Links *app, f32_Rect clip_box){ +Draw_Clip_Push(Application_Links *app, Rect_f32 clip_box){ Models *models = (Models*)app->cmd_context; //clip_box = draw_helper__models_space_to_screen_space(models, clip_box); - render_push_clip(models->target, i32R(clip_box)); + draw_push_clip(models->target, Ri32(clip_box)); } API_EXPORT f32_Rect Draw_Clip_Pop(Application_Links *app){ Models *models = (Models*)app->cmd_context; - f32_Rect result = f32R(render_pop_clip(models->target)); - return(result); + return(Rf32(draw_pop_clip(models->target))); } API_EXPORT void diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index bbf26c2d..5a179452 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -41,7 +41,6 @@ struct Mem_Options{ }; #include "4ed_render_target.h" -#include "4ed_render_format.h" #include "4ed.h" #include "4ed_buffer_model.h" @@ -81,7 +80,6 @@ struct Mem_Options{ #include "4ed_font_set.cpp" #include "4ed_translation.cpp" #include "4ed_render_target.cpp" -#include "4ed_render_format.cpp" #include "4ed_command.cpp" #include "4ed_buffer.cpp" #include "4ed_string_matching.cpp" diff --git a/4ed_font_interface.h b/4ed_font_interface.h index f273d0b2..1b24a39e 100644 --- a/4ed_font_interface.h +++ b/4ed_font_interface.h @@ -39,9 +39,9 @@ struct Codepoint_Index_Map{ struct Face{ Face_Description description; + Face_ID id; // NOTE(allen): Metrics - f32 height; f32 ascent; f32 descent; diff --git a/4ed_font_set.cpp b/4ed_font_set.cpp index 53cf39ca..a1665f2f 100644 --- a/4ed_font_set.cpp +++ b/4ed_font_set.cpp @@ -85,6 +85,7 @@ font_set_new_face(Font_Set *set, Face_Description *description){ slot->arena = arena; slot->face = face; result = font_set__alloc_face_id(set); + face->id = result; table_insert(&set->id_to_slot_table, result, (u64)slot); } else{ diff --git a/4ed_render_format.cpp b/4ed_render_format.cpp deleted file mode 100644 index 6814b029..00000000 --- a/4ed_render_format.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * 10.11.2017 - * - * Render buffer fill helpers. - * - */ - -// TOP - -internal void -draw_push_clip(Render_Target *target, i32_Rect clip_box){ - render_push_clip(target, clip_box); -} - -internal i32_Rect -draw_pop_clip(Render_Target *target){ - i32_Rect result = render_pop_clip(target); - return(result); -} - -internal void -draw_change_clip(Render_Target *target, i32_Rect clip_box){ - render_change_clip(target, clip_box); -} - -internal void -begin_frame(Render_Target *target, void *font_set){ - target->buffer.pos = 0; - target->font_set = font_set; -} - -internal void -begin_render_section(Render_Target *target, System_Functions *system, - i32 frame_index, f32 literal_dt, f32 animation_dt){ - target->clip_top = -1; - - i32_Rect clip; - clip.x0 = 0; - clip.y0 = 0; - clip.x1 = target->width; - clip.y1 = target->height; - draw_push_clip(target, clip); - - target->frame_index = frame_index; - target->literal_dt = literal_dt; - target->animation_dt = animation_dt; -} - -internal void -end_render_section(Render_Target *target, System_Functions *system){ - Assert(target->clip_top == 0); -} - -//////////////////////////////// - -#define CmdHeader(t) cmd.header.size = sizeof(cmd), cmd.header.type = t - -internal void -draw_rectangle(Render_Target *target, f32_Rect rect, u32 color){ - Render_Command_Rectangle cmd = {}; - CmdHeader(RenCom_Rectangle); - cmd.color = color; - cmd.vertices[0] = V2(rect.x0, rect.y0); - cmd.vertices[1] = V2(rect.x1, rect.y0); - cmd.vertices[2] = V2(rect.x0, rect.y1); - cmd.vertices[3] = V2(rect.x1, rect.y1); - void *h = render_begin_push(target, &cmd, cmd.header.size); - render_end_push(target, h); -} - -internal void -draw_rectangle_outline(Render_Target *target, f32_Rect rect, u32 color){ - draw_rectangle(target, Rf32(rect.x0, rect.y0, rect.x1, rect.y0 + 1), color); - draw_rectangle(target, Rf32(rect.x1 - 1, rect.y0, rect.x1, rect.y1), color); - draw_rectangle(target, Rf32(rect.x0, rect.y1 - 1, rect.x1, rect.y1), color); - draw_rectangle(target, Rf32(rect.x0, rect.y0, rect.x0 + 1, rect.y1), color); -} - -internal void -draw_font_glyph(Render_Target *target, Face_ID font_id, u32 codepoint, f32 x, f32 y, u32 color, u32 flags){ - Render_Command_Glyph cmd = {}; - CmdHeader(RenCom_Glyph); - cmd.pos.x = x; - cmd.pos.y = y; - cmd.color = color; - cmd.font_id = font_id; - cmd.codepoint = codepoint; - cmd.flags = flags; - void *h = render_begin_push(target, &cmd, cmd.header.size); - render_end_push(target, h); -} - -//////////////////////////////// - -internal void -draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){ - draw_rectangle(target, f32R(rect), color); -} - -internal void -draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){ - draw_rectangle_outline(target, f32R(rect), color); -} - -internal void -draw_margin(Render_Target *target, f32_Rect outer, f32_Rect inner, u32 color){ - draw_rectangle(target, f32R(outer.x0, outer.y0, outer.x1, inner.y0), color); - draw_rectangle(target, f32R(outer.x0, inner.y1, outer.x1, outer.y1), color); - draw_rectangle(target, f32R(outer.x0, inner.y0, inner.x0, inner.y1), color); - draw_rectangle(target, f32R(inner.x1, inner.y0, outer.x1, inner.y1), color); -} - -internal void -draw_margin(Render_Target *target, f32_Rect outer, f32 width, u32 color){ - f32_Rect inner = rect_inner(outer, width); - draw_margin(target, outer, inner, color); -} - -internal void -draw_margin(Render_Target *target, i32_Rect outer, i32_Rect inner, u32 color){ - draw_rectangle(target, i32R(outer.x0, outer.y0, outer.x1, inner.y0), color); - draw_rectangle(target, i32R(outer.x0, inner.y1, outer.x1, outer.y1), color); - draw_rectangle(target, i32R(outer.x0, inner.y0, inner.x0, inner.y1), color); - draw_rectangle(target, i32R(inner.x1, inner.y0, outer.x1, inner.y1), color); -} - -internal void -draw_margin(Render_Target *target, i32_Rect outer, i32 width, u32 color){ - i32_Rect inner = rect_inner(outer, width); - draw_margin(target, outer, inner, color); -} - -internal Vec2 -snap_point_to_boundary(Vec2 point){ - point.x = (f32)(floor32(point.x)); - point.y = (f32)(floor32(point.y)); - return(point); -} - -internal f32 -draw_string(Render_Target *target, Face_ID font_id, String_Const_u8 string, Vec2 point, u32 color, u32 flags, Vec2 delta){ - f32 total_delta = 0.f; - - Face *face = 0; - - if (face != 0){ - point = snap_point_to_boundary(point); - - f32 byte_advance = face->byte_advance; - f32 *byte_sub_advances = face->byte_sub_advances; - - u8 *str = (u8*)string.str; - u8 *str_end = str + string.size; - - Translation_State tran = {}; - Translation_Emits emits = {}; - - for (u32 i = 0; str < str_end; ++str, ++i){ - translating_fully_process_byte(&tran, *str, i, (i32)string.size, &emits); - - for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){ - TRANSLATION_DECL_GET_STEP(step, behavior, J, emits); - - if (behavior.do_codepoint_advance){ - u32 codepoint = step.value; - if (color != 0){ - draw_font_glyph(target, font_id, codepoint, point.x, point.y, color, flags); - } - f32 d = font_get_glyph_advance(face, codepoint); - point += d*delta; - total_delta += d; - } - else if (behavior.do_number_advance){ - u8 n = (u8)(step.value); - if (color != 0){ - u8 cs[3]; - cs[0] = '\\'; - byte_to_ascii(n, cs+1); - Vec2 pp = point; - for (u32 j = 0; j < 3; ++j){ - draw_font_glyph(target, font_id, cs[j], pp.x, pp.y, color, flags); - pp += delta*byte_sub_advances[j]; - } - } - point += byte_advance*delta; - total_delta += byte_advance; - } - } - } - } - - return(total_delta); -} - -internal f32 -draw_string(Render_Target *target, Face_ID font_id, String_Const_u8 string, Vec2 point, u32 color){ - return(draw_string(target, font_id, string, point, color, 0, V2(1.f, 0.f))); -} - -internal f32 -draw_string(Render_Target *target, Face_ID font_id, u8 *str, Vec2 point, - u32 color, u32 flags, Vec2 delta){ - return(draw_string(target, font_id, SCu8(str), point, color, flags, delta)); -} - -internal f32 -draw_string(Render_Target *target, Face_ID font_id, u8 *str, Vec2 point, - u32 color){ - return(draw_string(target, font_id, SCu8(str), point, color, 0, V2(1.f, 0.f))); -} - -internal f32 -font_string_width(Render_Target *target, Face_ID font_id, String_Const_u8 str){ - return(draw_string(target, font_id, str, V2(0, 0), 0, 0, V2(0, 0))); -} - -internal f32 -font_string_width(Render_Target *target, Face_ID font_id, u8 *str){ - return(draw_string(target, font_id, SCu8(str), V2(0, 0), 0, 0, V2(0, 0))); -} - -// BOTTOM - diff --git a/4ed_render_format.h b/4ed_render_format.h deleted file mode 100644 index 9dfdbfff..00000000 --- a/4ed_render_format.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * 10.11.2017 - * - * Format for 4coder render commands. - * - */ - -// TOP - -#if !defined(FRED_RENDER_FORMAT_H) -#define FRED_RENDER_FORMAT_H - -enum Render_Command_Type{ - RenCom_Rectangle, - RenCom_Glyph, - RenCom_ChangeClip, -}; - -struct Render_Command_Header{ - union{ - struct{ - i32 size; - i32 type; - }; - u64 force_8_byte_align_; - }; -}; - -struct Render_Command_Rectangle{ - Render_Command_Header header; - u32 color; - Vec2 vertices[4]; -}; - -struct Render_Command_Rectangle_Outline{ - Render_Command_Header header; - u32 color; - Vec2 vertices[5]; -}; - -struct Render_Command_Gradient{ - Render_Command_Header header; - f32_Rect rect; - u32 left_color; - u32 right_color; -}; - -struct Render_Command_Glyph{ - Render_Command_Header header; - Vec2 pos; - u32 color; - Face_ID font_id; - u32 codepoint; - u32 flags; -}; - -struct Render_Command_Change_Clip{ - Render_Command_Header header; - i32_Rect box; -}; - -struct Render_Pseudo_Command_Free_Texture{ - Render_Command_Header header; - Render_Free_Texture free_texture_node; -}; - -#endif - -// BOTTOM - diff --git a/4ed_render_target.cpp b/4ed_render_target.cpp index 9eebd2ca..b2225d62 100644 --- a/4ed_render_target.cpp +++ b/4ed_render_target.cpp @@ -9,95 +9,370 @@ // TOP -#define Render_Begin_Push_Sig(n,t,p,s) void* (n)(Render_Target *t, void *p, i32 s) -#define Render_End_Push_Sig(n,t,h) void (n)(Render_Target *t, void *h) -#define Render_Change_Clip_Sig(n,t,c) void (n)(Render_Target *t, i32_Rect c) -#define Render_Push_Clip_Sig(n,t,c) void (n)(Render_Target *t, i32_Rect c) -#define Render_Pop_Clip_Sig(n,t) i32_Rect (n)(Render_Target *t) - -//////////////////////////////// - -internal -Render_Begin_Push_Sig(render_internal_begin_push, t, ptr, size){ - void *out = push_array(&t->buffer, u8, size); - if (out != 0){ - memcpy(out, ptr, size); +internal void +draw__begin_new_group(Render_Target *target){ + Render_Group *group = 0; + if (target->group_last != 0){ + if (target->group_last->vertex_list.vertex_count == 0){ + group = target->group_last; + } } - else{ - t->out_of_memory = true; + if (group == 0){ + group = push_array_zero(&target->arena, Render_Group, 1); + sll_queue_push(target->group_first, target->group_last, group); } - return(out); + group->face_id = target->current_face_id; + group->clip_box = target->current_clip_box; } -internal -Render_End_Push_Sig(render_internal_end_push, t, h){ - if (h != 0){ - push_align(&t->buffer, 8); - u8 *end_ptr = push_array(&t->buffer, u8, 0); - Render_Command_Header *header = (Render_Command_Header*)h; - header->size = (i32)(end_ptr - (u8*)h); +internal Render_Vertex_Array_Node* +draw__extend_group_vertex_memory(Arena *arena, Render_Vertex_List *list, i32 size){ + Render_Vertex_Array_Node *node = push_array_zero(arena, Render_Vertex_Array_Node, 1); + sll_queue_push(list->first, list->last, node); + node->vertices = push_array(arena, Render_Vertex, size); + node->vertex_max = size; + return(node); +} + +internal void +draw__write_vertices_in_current_group(Render_Target *target, Render_Vertex *vertices, i32 count){ + if (count > 0){ + Render_Group *group = target->group_last; + if (group != 0){ + Render_Vertex_List *list = &group->vertex_list; + + Render_Vertex_Array_Node *last = list->last; + + Render_Vertex *tail_vertex = 0; + i32 tail_count = 0; + if (last != 0){ + tail_vertex = last->vertices + last->vertex_count; + tail_count = last->vertex_max - last->vertex_count; + } + + i32 base_vertex_max = 64; + i32 transfer_count = clamp_top(count, tail_count); + if (transfer_count > 0){ + block_copy_dynamic_array(tail_vertex, vertices, transfer_count); + last->vertex_count += transfer_count; + list->vertex_count += transfer_count; + base_vertex_max = last->vertex_max; + } + + i32 count_left_over = count - transfer_count; + if (count_left_over > 0){ + Render_Vertex *vertices_left_over = vertices + transfer_count; + + i32 next_node_size = (base_vertex_max + count_left_over)*2; + Render_Vertex_Array_Node *memory = draw__extend_group_vertex_memory(&target->arena, list, next_node_size); + block_copy_dynamic_array(memory->vertices, vertices_left_over, count_left_over); + memory->vertex_count += count_left_over; + list->vertex_count += count_left_over; + } + } } } internal void -render_internal_push_clip(Render_Target *t, i32_Rect clip_box){ - t->clip_all = (clip_box.x0 >= clip_box.x1 || clip_box.y0 >= clip_box.y1); - if (t->clip_all){ - return; +draw__set_clip_box(Render_Target *target, Rect_i32 clip_box){ + if (target->current_clip_box != clip_box){ + target->current_clip_box = clip_box; + draw__begin_new_group(target); + } +} + +internal void +draw__set_face_id(Render_Target *target, Face_ID face_id){ + if (target->current_face_id != face_id){ + target->current_face_id = face_id; + draw__begin_new_group(target); } - - // TODO(allen): If the previous command was also a push clip should - // undo that one and just do this one. (OPTIMIZATION). - Render_Command_Change_Clip cmd = {}; - cmd.header.size = sizeof(cmd); - cmd.header.type = RenCom_ChangeClip; - cmd.box = clip_box; - void *h = render_internal_begin_push(t, &cmd, cmd.header.size); - render_internal_end_push(t, h); } //////////////////////////////// -internal -Render_Begin_Push_Sig(render_begin_push, t, ptr, size){ - void *out = 0; - if (!t->clip_all){ - out = render_internal_begin_push(t, ptr, size); +internal void +draw_push_clip(Render_Target *target, Rect_i32 clip_box){ + if (target->clip_top != -1){ + clip_box = intersection_of(clip_box, target->clip_boxes[target->clip_top]); } - return(out); + Assert(target->clip_top + 1 < ArrayCount(target->clip_boxes)); + target->clip_boxes[++target->clip_top] = clip_box; + draw__set_clip_box(target, clip_box); } -internal -Render_End_Push_Sig(render_end_push, t, h){ - render_internal_end_push(t, h); -} - -internal -Render_Change_Clip_Sig(render_change_clip, t, clip_box){ - Assert(t->clip_top > -1); - t->clip_boxes[t->clip_top] = clip_box; - render_internal_push_clip(t, clip_box); -} - -internal -Render_Push_Clip_Sig(render_push_clip, t, clip_box){ - if (t->clip_top != -1){ - clip_box = intersection_of(clip_box, t->clip_boxes[t->clip_top]); - } - Assert(t->clip_top + 1 < ArrayCount(t->clip_boxes)); - t->clip_boxes[++t->clip_top] = clip_box; - render_internal_push_clip(t, clip_box); -} - -internal -Render_Pop_Clip_Sig(render_pop_clip, t){ - Assert(t->clip_top > 0); - i32_Rect result = t->clip_boxes[t->clip_top]; - --t->clip_top; - i32_Rect clip_box = t->clip_boxes[t->clip_top]; - render_internal_push_clip(t, clip_box); +internal Rect_i32 +draw_pop_clip(Render_Target *target){ + Assert(target->clip_top > 0); + i32_Rect result = target->clip_boxes[target->clip_top]; + --target->clip_top; + i32_Rect clip_box = target->clip_boxes[target->clip_top]; + draw__set_clip_box(target, clip_box); return(result); } +internal void +draw_change_clip(Render_Target *target, Rect_i32 clip_box){ + Assert(target->clip_top > -1); + target->clip_boxes[target->clip_top] = clip_box; + draw__set_clip_box(target, clip_box); +} + +internal void +begin_frame(Render_Target *target, void *font_set){ + linalloc_clear(&target->arena); + target->group_first = 0; + target->group_last = 0; + target->current_face_id = 0; + target->current_clip_box = Ri32(0, 0, target->width, target->height); + target->font_set = font_set; +} + +internal void +begin_render_section(Render_Target *target, System_Functions *system, + i32 frame_index, f32 literal_dt, f32 animation_dt){ + target->clip_top = -1; + + i32_Rect clip; + clip.x0 = 0; + clip.y0 = 0; + clip.x1 = target->width; + clip.y1 = target->height; + draw_push_clip(target, clip); + + target->frame_index = frame_index; + target->literal_dt = literal_dt; + target->animation_dt = animation_dt; +} + +internal void +end_render_section(Render_Target *target, System_Functions *system){ + Assert(target->clip_top == 0); +} + +//////////////////////////////// + +#if 0 +internal void +draw_font_glyph(Render_Target *target, Face_ID font_id, u32 codepoint, f32 x, f32 y, u32 color, u32 flags){ + Render_Command_Glyph cmd = {}; + CmdHeader(RenCom_Glyph); + cmd.pos.x = x; + cmd.pos.y = y; + cmd.color = color; + cmd.font_id = font_id; + cmd.codepoint = codepoint; + cmd.flags = flags; + void *h = render_begin_push(target, &cmd, cmd.header.size); + render_end_push(target, h); +} +#endif + +internal void +draw_rectangle(Render_Target *target, Rect_f32 rect, u32 color){ + Render_Vertex vertices[6] = {}; + vertices[0].xy = V2(rect.x0, rect.y0); + vertices[1].xy = V2(rect.x1, rect.y0); + vertices[2].xy = V2(rect.x0, rect.y1); + vertices[3].xy = V2(rect.x1, rect.y0); + vertices[4].xy = V2(rect.x0, rect.y1); + vertices[5].xy = V2(rect.x1, rect.y1); + Vec4 c = unpack_color4(color); + for (i32 i = 0; i < 6; i += 1){ + vertices[i].color = c; + } + draw__write_vertices_in_current_group(target, vertices, 6); +} + +internal void +draw_font_glyph(Render_Target *target, Face *face, u32 codepoint, f32 x, f32 y, u32 color, u32 flags){ + draw__set_face_id(target, face->id); + + u16 glyph_index = 0; + if (!codepoint_index_map_read(&face->codepoint_to_index_map, codepoint, &glyph_index)){ + glyph_index = 0; + } + Glyph_Bounds bounds = face->bounds[glyph_index]; + Vec3_f32 texture_dim = face->texture_dim; + + f32_Rect uv = Rf32(bounds.uv.x0, bounds.uv.y0, + bounds.uv.x1, bounds.uv.y1); + + Render_Vertex vertices[6] = {}; + if (!HasFlag(flags, GlyphFlag_Rotate90)){ + f32_Rect xy = Rf32(x + bounds.xy_off.x0, y + bounds.xy_off.y0, + x + bounds.xy_off.x1, y + bounds.xy_off.y1); + + vertices[0].xy = V2(xy.x0, xy.y1); vertices[0].uvw = V3(uv.x0, uv.y1, bounds.w); + vertices[1].xy = V2(xy.x1, xy.y1); vertices[1].uvw = V3(uv.x1, uv.y1, bounds.w); + vertices[3].xy = V2(xy.x0, xy.y0); vertices[3].uvw = V3(uv.x0, uv.y0, bounds.w); + vertices[5].xy = V2(xy.x1, xy.y0); vertices[5].uvw = V3(uv.x1, uv.y0, bounds.w); + } + else{ + f32_Rect xy = Rf32(x - bounds.xy_off.y1, y + bounds.xy_off.x0, + x - bounds.xy_off.y0, y + bounds.xy_off.x1); + + vertices[0].xy = V2(xy.x0, xy.y1); vertices[0].uvw = V3(uv.x1, uv.y1, bounds.w); + vertices[1].xy = V2(xy.x1, xy.y1); vertices[1].uvw = V3(uv.x1, uv.y0, bounds.w); + vertices[3].xy = V2(xy.x0, xy.y0); vertices[3].uvw = V3(uv.x0, uv.y1, bounds.w); + vertices[5].xy = V2(xy.x1, xy.y0); vertices[5].uvw = V3(uv.x0, uv.y0, bounds.w); + } + + vertices[2] = vertices[1]; + vertices[3] = vertices[4]; + + Vec4 c = unpack_color4(color); + for (i32 i = 0; i < 6; i += 1){ + vertices[0].color = c; + } +} + +internal void +draw_font_glyph(Render_Target *target, Font_Set *font_set, Face_ID face_id, u32 codepoint, f32 x, f32 y, u32 color, u32 flags){ + Face *face = font_set_face_from_id(font_set, face_id); + if (face != 0){ + draw_font_glyph(target, face, codepoint, x, y, color, flags); + } +} + +//////////////////////////////// + +internal void +draw_rectangle_outline(Render_Target *target, f32_Rect rect, u32 color){ + draw_rectangle(target, Rf32(rect.x0, rect.y0, rect.x1, rect.y0 + 1), color); + draw_rectangle(target, Rf32(rect.x1 - 1, rect.y0, rect.x1, rect.y1), color); + draw_rectangle(target, Rf32(rect.x0, rect.y1 - 1, rect.x1, rect.y1), color); + draw_rectangle(target, Rf32(rect.x0, rect.y0, rect.x0 + 1, rect.y1), color); +} + +//////////////////////////////// + +internal void +draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){ + draw_rectangle(target, f32R(rect), color); +} + +internal void +draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){ + draw_rectangle_outline(target, f32R(rect), color); +} + +internal void +draw_margin(Render_Target *target, f32_Rect outer, f32_Rect inner, u32 color){ + draw_rectangle(target, f32R(outer.x0, outer.y0, outer.x1, inner.y0), color); + draw_rectangle(target, f32R(outer.x0, inner.y1, outer.x1, outer.y1), color); + draw_rectangle(target, f32R(outer.x0, inner.y0, inner.x0, inner.y1), color); + draw_rectangle(target, f32R(inner.x1, inner.y0, outer.x1, inner.y1), color); +} + +internal void +draw_margin(Render_Target *target, f32_Rect outer, f32 width, u32 color){ + f32_Rect inner = rect_inner(outer, width); + draw_margin(target, outer, inner, color); +} + +internal void +draw_margin(Render_Target *target, i32_Rect outer, i32_Rect inner, u32 color){ + draw_rectangle(target, i32R(outer.x0, outer.y0, outer.x1, inner.y0), color); + draw_rectangle(target, i32R(outer.x0, inner.y1, outer.x1, outer.y1), color); + draw_rectangle(target, i32R(outer.x0, inner.y0, inner.x0, inner.y1), color); + draw_rectangle(target, i32R(inner.x1, inner.y0, outer.x1, inner.y1), color); +} + +internal void +draw_margin(Render_Target *target, i32_Rect outer, i32 width, u32 color){ + i32_Rect inner = rect_inner(outer, width); + draw_margin(target, outer, inner, color); +} + +internal Vec2 +snap_point_to_boundary(Vec2 point){ + point.x = (f32)(floor32(point.x)); + point.y = (f32)(floor32(point.y)); + return(point); +} + +internal f32 +draw_string(Render_Target *target, Face_ID font_id, String_Const_u8 string, Vec2 point, u32 color, u32 flags, Vec2 delta){ + f32 total_delta = 0.f; + + Face *face = 0; + + if (face != 0){ + point = snap_point_to_boundary(point); + + f32 byte_advance = face->byte_advance; + f32 *byte_sub_advances = face->byte_sub_advances; + + u8 *str = (u8*)string.str; + u8 *str_end = str + string.size; + + Translation_State tran = {}; + Translation_Emits emits = {}; + + for (u32 i = 0; str < str_end; ++str, ++i){ + translating_fully_process_byte(&tran, *str, i, (i32)string.size, &emits); + + for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){ + TRANSLATION_DECL_GET_STEP(step, behavior, J, emits); + + if (behavior.do_codepoint_advance){ + u32 codepoint = step.value; + if (color != 0){ + draw_font_glyph(target, face, codepoint, point.x, point.y, color, flags); + } + f32 d = font_get_glyph_advance(face, codepoint); + point += d*delta; + total_delta += d; + } + else if (behavior.do_number_advance){ + u8 n = (u8)(step.value); + if (color != 0){ + u8 cs[3]; + cs[0] = '\\'; + byte_to_ascii(n, cs+1); + Vec2 pp = point; + for (u32 j = 0; j < 3; ++j){ + draw_font_glyph(target, face, cs[j], pp.x, pp.y, color, flags); + pp += delta*byte_sub_advances[j]; + } + } + point += byte_advance*delta; + total_delta += byte_advance; + } + } + } + } + + return(total_delta); +} + +internal f32 +draw_string(Render_Target *target, Face_ID font_id, String_Const_u8 string, Vec2 point, u32 color){ + return(draw_string(target, font_id, string, point, color, 0, V2(1.f, 0.f))); +} + +internal f32 +draw_string(Render_Target *target, Face_ID font_id, u8 *str, Vec2 point, + u32 color, u32 flags, Vec2 delta){ + return(draw_string(target, font_id, SCu8(str), point, color, flags, delta)); +} + +internal f32 +draw_string(Render_Target *target, Face_ID font_id, u8 *str, Vec2 point, + u32 color){ + return(draw_string(target, font_id, SCu8(str), point, color, 0, V2(1.f, 0.f))); +} + +internal f32 +font_string_width(Render_Target *target, Face_ID font_id, String_Const_u8 str){ + return(draw_string(target, font_id, str, V2(0, 0), 0, 0, V2(0, 0))); +} + +internal f32 +font_string_width(Render_Target *target, Face_ID font_id, u8 *str){ + return(draw_string(target, font_id, SCu8(str), V2(0, 0), 0, 0, V2(0, 0))); +} + // BOTTOM diff --git a/4ed_render_target.h b/4ed_render_target.h index f80d84e2..91b1a0a4 100644 --- a/4ed_render_target.h +++ b/4ed_render_target.h @@ -17,11 +17,37 @@ struct Render_Free_Texture{ u32 tex_id; }; +struct Render_Vertex{ + Vec2 xy; + Vec3 uvw; + Vec4 color; +}; + +struct Render_Vertex_Array_Node{ + Render_Vertex_Array_Node *next; + Render_Vertex *vertices; + i32 vertex_count; + i32 vertex_max; +}; + +struct Render_Vertex_List{ + Render_Vertex_Array_Node *first; + Render_Vertex_Array_Node *last; + i32 vertex_count; +}; + +struct Render_Group{ + Render_Group *next; + Render_Vertex_List vertex_list; + // parameters + Face_ID face_id; + i32_Rect clip_box; +}; + struct Render_Target{ i32_Rect clip_boxes[5]; i32 clip_top; b8 clip_all; - b8 out_of_memory; i32 width; i32 height; i32 bound_texture; @@ -34,10 +60,15 @@ struct Render_Target{ Render_Free_Texture *free_texture_first; Render_Free_Texture *free_texture_last; - // TODO(allen): rewrite render system to work on an arena - Cursor buffer; + Arena arena; + Render_Group *group_first; + Render_Group *group_last; + i32 group_count; + Face_ID current_face_id; + Rect_i32 current_clip_box; void *font_set; + u32 fallback_texture_id; }; #endif diff --git a/4ed_view.cpp b/4ed_view.cpp index ccd52a2f..e5cfa591 100644 --- a/4ed_view.cpp +++ b/4ed_view.cpp @@ -805,6 +805,7 @@ render_loaded_file_in_view__inner(Models *models, Render_Target *target, View *v Editing_File *file = view->file; Arena *scratch = &models->mem.arena; Color_Table color_table = models->color_table; + Font_Set *font_set = &models->font_set; Assert(file != 0); Assert(!file->is_dummy); @@ -1197,7 +1198,7 @@ render_loaded_file_in_view__inner(Models *models, Render_Target *target, View *v } char_color = color_blend(char_color, fade_amount, fade_color); if (item->codepoint != 0){ - draw_font_glyph(target, font_id, item->codepoint, item->x0, item->y0, char_color, GlyphFlag_None); + draw_font_glyph(target, font_set, font_id, item->codepoint, item->x0, item->y0, char_color, GlyphFlag_None); } if (color_wireframe != 0){ diff --git a/opengl/4ed_opengl_funcs.h b/opengl/4ed_opengl_funcs.h index 8ed2a786..dd6c9aef 100644 --- a/opengl/4ed_opengl_funcs.h +++ b/opengl/4ed_opengl_funcs.h @@ -26,6 +26,7 @@ GL_FUNC(glDeleteVertexArrays, void, (GLsizei n, const GLuint *arrays)) GL_FUNC(glGenBuffers, void, (GLsizei n, GLuint *buffers)) GL_FUNC(glBindBuffer, void, (GLenum target, GLuint buffer)) GL_FUNC(glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage)) +GL_FUNC(glBufferSubData, void, (GLenum target, GLsizeiptr offset, GLsizeiptr size, const void *data)) GL_FUNC(glCreateShader, GLuint, (GLenum type)) GL_FUNC(glShaderSource, void, (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length)) diff --git a/opengl/4ed_opengl_render.cpp b/opengl/4ed_opengl_render.cpp index fea30a6a..8f91e304 100644 --- a/opengl/4ed_opengl_render.cpp +++ b/opengl/4ed_opengl_render.cpp @@ -21,6 +21,15 @@ gl__bind_texture(Render_Target *t, i32 texid){ } } +internal void +gl__bind_any_texture(Render_Target *t){ + if (t->bound_texture == 0){ + Assert(t->fallback_texture_id != 0); + glBindTexture(GL_TEXTURE_2D_ARRAY, t->fallback_texture_id); + t->bound_texture = t->fallback_texture_id; + } +} + internal u32 gl__get_texture(Vec3_i32 dim, Texture_Kind texture_kind){ u32 tex = 0; @@ -59,15 +68,15 @@ char *gl__header = R"foo(#version 150 char *gl__vertex = R"foo( uniform vec2 view_t; uniform mat2x2 view_m; - uniform vec4 color; in vec2 vertex_p; in vec3 vertex_t; +in vec4 vertex_c; smooth out vec4 fragment_color; smooth out vec3 uvw; void main(void) { gl_Position = vec4(view_m*(vertex_p - view_t), 0.f, 1.f); -fragment_color = color; +fragment_color = vertex_c; uvw = vertex_t; } )foo"; @@ -76,24 +85,22 @@ char *gl__fragment = R"foo( smooth in vec4 fragment_color; smooth in vec3 uvw; uniform sampler2DArray sampler; -uniform float texture_override; out vec4 out_color; void main(void) { -out_color = fragment_color*(texture(sampler, uvw).r + texture_override); +out_color = fragment_color*texture(sampler, uvw).r; } )foo"; #define AttributeList(X) \ X(vertex_p) \ -X(vertex_t) +X(vertex_t) \ +X(vertex_c) #define UniformList(X) \ X(view_t) \ X(view_m) \ -X(color) \ -X(sampler) \ -X(texture_override) +X(sampler) struct GL_Program{ u32 program; @@ -157,7 +164,8 @@ gl__make_program(char *header, char *vertex, char *fragment){ return(result); } -#define GLOffset(p,m) ((void*)(OffsetOfMemberStruct(p,m))) +#define GLOffsetStruct(p,m) ((void*)(OffsetOfMemberStruct(p,m))) +#define GLOffset(S,m) ((void*)(OffsetOfMember(S,m))) internal void gl_render(Render_Target *t, Arena *scratch){ @@ -201,6 +209,14 @@ gl_render(Render_Target *t, Arena *scratch){ gpu_program = gl__make_program(gl__header, gl__vertex, gl__fragment); glUseProgram(gpu_program.program); + + //////////////////////////////// + + { + t->fallback_texture_id = gl__get_texture(V3i32(2, 2, 1), TextureKind_Mono); + u8 white_block[] = { 0xFF, 0xFF, 0xFF, 0xFF, }; + gl__fill_texture(TextureKind_Mono, 0, V3i32(0, 0, 0), V3i32(2, 2, 1), white_block); + } } i32 width = t->width; @@ -222,6 +238,7 @@ gl_render(Render_Target *t, Arena *scratch){ t->free_texture_first = 0; t->free_texture_last = 0; +#if 0 i32 glyph_counter = 0; u8 *start = (u8*)t->buffer.base; @@ -235,14 +252,18 @@ gl_render(Render_Target *t, Arena *scratch){ case RenCom_Rectangle: { Render_Command_Rectangle *rectangle = (Render_Command_Rectangle*)header; - gl__bind_texture(t, 0); - - Vec4 c = unpack_color4(rectangle->color); + gl__bind_any_texture(t); i32 vertex_count = ArrayCount(rectangle->vertices); glBufferData(GL_ARRAY_BUFFER, sizeof(rectangle->vertices), rectangle->vertices, GL_STREAM_DRAW); glEnableVertexAttribArray(gpu_program.vertex_p); - glVertexAttribPointer(gpu_program.vertex_p, 2, GL_FLOAT, true, sizeof(rectangle->vertices[0]), 0); + glEnableVertexAttribArray(gpu_program.vertex_t); + glEnableVertexAttribArray(gpu_program.vertex_c); + //glVertexAttribPointer(gpu_program.vertex_p, 2, GL_FLOAT, true, sizeof(rectangle->vertices[0]), 0); + Render_Vertex *vertices = rectangle->vertices; + glVertexAttribPointer(gpu_program.vertex_p, 2, GL_FLOAT, true, sizeof(*vertices), GLOffset(vertices, xy)); + glVertexAttribPointer(gpu_program.vertex_t, 3, GL_FLOAT, true, sizeof(*vertices), GLOffset(vertices, uvw)); + glVertexAttribPointer(gpu_program.vertex_c, 4, GL_FLOAT, true, sizeof(*vertices), GLOffset(vertices, color)); glUniform2f(gpu_program.view_t, width/2.f, height/2.f); f32 m[4] = { @@ -250,11 +271,12 @@ gl_render(Render_Target *t, Arena *scratch){ 0.f, -2.f/height, }; glUniformMatrix2fv(gpu_program.view_m, 1, GL_FALSE, m); - glUniform4f(gpu_program.color, c.r*c.a, c.g*c.a, c.b*c.a, c.a); - glUniform1f(gpu_program.texture_override, 1.f); + glUniform1i(gpu_program.sampler, 0); - glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count); + glDrawArrays(GL_TRIANGLES, 0, vertex_count); glDisableVertexAttribArray(gpu_program.vertex_p); + glDisableVertexAttribArray(gpu_program.vertex_t); + glDisableVertexAttribArray(gpu_program.vertex_c); }break; case RenCom_Glyph: @@ -289,35 +311,35 @@ gl_render(Render_Target *t, Arena *scratch){ f32_Rect xy = Rf32(x + bounds.xy_off.x0, y + bounds.xy_off.y0, x + bounds.xy_off.x1, y + bounds.xy_off.y1); - struct Textutred_Vertex{ - Vec2 xy; - Vec2 uv; - }; - - Textutred_Vertex vertices[4]; + Render_Vertex vertices[4]; if (!HasFlag(glyph->flags, GlyphFlag_Rotate90)){ - vertices[0].xy = V2(xy.x0, xy.y1); vertices[0].uv = V2(uv.x0, uv.y1); - vertices[1].xy = V2(xy.x1, xy.y1); vertices[1].uv = V2(uv.x1, uv.y1); - vertices[2].xy = V2(xy.x0, xy.y0); vertices[2].uv = V2(uv.x0, uv.y0); - vertices[3].xy = V2(xy.x1, xy.y0); vertices[3].uv = V2(uv.x1, uv.y0); + vertices[0].xy = V2(xy.x0, xy.y1); vertices[0].uvw = V3(uv.x0, uv.y1, bounds.w); + vertices[1].xy = V2(xy.x1, xy.y1); vertices[1].uvw = V3(uv.x1, uv.y1, bounds.w); + vertices[2].xy = V2(xy.x0, xy.y0); vertices[2].uvw = V3(uv.x0, uv.y0, bounds.w); + vertices[3].xy = V2(xy.x1, xy.y0); vertices[3].uvw = V3(uv.x1, uv.y0, bounds.w); } else{ - vertices[0].xy = V2(xy.x0, xy.y1); vertices[0].uv = V2(uv.x1, uv.y1); - vertices[1].xy = V2(xy.x1, xy.y1); vertices[1].uv = V2(uv.x1, uv.y0); - vertices[2].xy = V2(xy.x0, xy.y0); vertices[2].uv = V2(uv.x0, uv.y1); - vertices[3].xy = V2(xy.x1, xy.y0); vertices[3].uv = V2(uv.x0, uv.y0); + vertices[0].xy = V2(xy.x0, xy.y1); vertices[0].uvw = V3(uv.x1, uv.y1, bounds.w); + vertices[1].xy = V2(xy.x1, xy.y1); vertices[1].uvw = V3(uv.x1, uv.y0, bounds.w); + vertices[2].xy = V2(xy.x0, xy.y0); vertices[2].uvw = V3(uv.x0, uv.y1, bounds.w); + vertices[3].xy = V2(xy.x1, xy.y0); vertices[3].uvw = V3(uv.x0, uv.y0, bounds.w); + } + + Vec4 c = unpack_color4(glyph->color); + for (i32 i = 0; i < 4; i += 1){ + vertices[i].color = c; } gl__bind_texture(t, tex); - Vec4 c = unpack_color4(glyph->color); - i32 vertex_count = ArrayCount(vertices); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW); glEnableVertexAttribArray(gpu_program.vertex_p); glEnableVertexAttribArray(gpu_program.vertex_t); + glEnableVertexAttribArray(gpu_program.vertex_c); glVertexAttribPointer(gpu_program.vertex_p, 2, GL_FLOAT, true, sizeof(vertices[0]), GLOffset(&vertices[0], xy)); - glVertexAttribPointer(gpu_program.vertex_t, 2, GL_FLOAT, true, sizeof(vertices[0]), GLOffset(&vertices[0], uv)); + glVertexAttribPointer(gpu_program.vertex_t, 3, GL_FLOAT, true, sizeof(vertices[0]), GLOffset(&vertices[0], uvw)); + glVertexAttribPointer(gpu_program.vertex_c, 4, GL_FLOAT, true, sizeof(vertices[0]), GLOffset(&vertices[0], color)); glUniform2f(gpu_program.view_t, width/2.f, height/2.f); f32 m[4] = { @@ -325,14 +347,12 @@ gl_render(Render_Target *t, Arena *scratch){ 0.f, -2.f/height, }; glUniformMatrix2fv(gpu_program.view_m, 1, GL_FALSE, m); - glUniform4f(gpu_program.color, c.r*c.a, c.g*c.a, c.b*c.a, c.a); - glUniform1i(gpu_program.sampler, 0); - glUniform1f(gpu_program.texture_override, 0.f); glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count); glDisableVertexAttribArray(gpu_program.vertex_p); glDisableVertexAttribArray(gpu_program.vertex_t); + glDisableVertexAttribArray(gpu_program.vertex_c); #if 0 if (codepoint != ' ' && font.settings->parameters.underline){ @@ -355,8 +375,8 @@ gl_render(Render_Target *t, Arena *scratch){ glEnable(GL_TEXTURE_2D); } -#endif }break; +#endif case RenCom_ChangeClip: { @@ -364,15 +384,66 @@ gl_render(Render_Target *t, Arena *scratch){ i32_Rect box = clip->box; glScissor(box.x0, height - box.y1, box.x1 - box.x0, box.y1 - box.y0); }break; + + case RenCom_Group: + { + Render_Command_Group *group = (Render_Command_Group*)header; + Rect_i32 box = group->clip_box; + glScissor(box.x0, height - box.y1, box.x1 - box.x0, box.y1 - box.y0); + + + }break; } } - - if (target.out_of_memory){ - glScissor(0, 0, width, height); - glClearColor(0.f, 1.f, 0.f, 1.f); - glClear(GL_COLOR_BUFFER_BIT); - target.out_of_memory = false; +#else + for (Render_Group *group = t->group_first; + group != 0; + group = group->next){ + Rect_i32 box = group->clip_box; + glScissor(box.x0, height - box.y1, box.x1 - box.x0, box.y1 - box.y0); + + i32 vertex_count = group->vertex_list.vertex_count; + if (vertex_count > 0){ + Face *face = font_set_face_from_id(font_set, group->face_id); + if (face != 0){ + gl__bind_texture(t, face->texture); + } + else{ + gl__bind_any_texture(t); + } + + glBufferData(GL_ARRAY_BUFFER, vertex_count*sizeof(Render_Vertex), 0, GL_STREAM_DRAW); + i32 cursor = 0; + for (Render_Vertex_Array_Node *node = group->vertex_list.first; + node != 0; + node = node->next){ + i32 size = node->vertex_count*sizeof(*node->vertices); + glBufferSubData(GL_ARRAY_BUFFER, cursor, size, node->vertices); + cursor += size; + } + + glEnableVertexAttribArray(gpu_program.vertex_p); + glEnableVertexAttribArray(gpu_program.vertex_t); + glEnableVertexAttribArray(gpu_program.vertex_c); + glVertexAttribPointer(gpu_program.vertex_p, 2, GL_FLOAT, true, sizeof(Render_Vertex), GLOffset(Render_Vertex, xy)); + glVertexAttribPointer(gpu_program.vertex_t, 3, GL_FLOAT, true, sizeof(Render_Vertex), GLOffset(Render_Vertex, uvw)); + glVertexAttribPointer(gpu_program.vertex_c, 4, GL_FLOAT, true, sizeof(Render_Vertex), GLOffset(Render_Vertex, color)); + + glUniform2f(gpu_program.view_t, width/2.f, height/2.f); + f32 m[4] = { + 2.f/width, 0.f, + 0.f, -2.f/height, + }; + glUniformMatrix2fv(gpu_program.view_m, 1, GL_FALSE, m); + glUniform1i(gpu_program.sampler, 0); + + glDrawArrays(GL_TRIANGLES, 0, vertex_count); + glDisableVertexAttribArray(gpu_program.vertex_p); + glDisableVertexAttribArray(gpu_program.vertex_t); + glDisableVertexAttribArray(gpu_program.vertex_c); + } } +#endif glFlush(); } diff --git a/platform_all/4ed_shared_init_logic.cpp b/platform_all/4ed_shared_init_logic.cpp index 1e245a16..2ecd9d4e 100644 --- a/platform_all/4ed_shared_init_logic.cpp +++ b/platform_all/4ed_shared_init_logic.cpp @@ -31,10 +31,10 @@ memory_init(){ memory_vars.debug_memory = system_memory_allocate_extended(0, memory_vars.debug_memory_size); i32 render_memsize = MB(1); - target.buffer = make_cursor(system_memory_allocate(render_memsize), render_memsize); + target.arena = make_arena_system(&sysfunc); b32 alloc_success = true; - if (memory_vars.vars_memory == 0 || memory_vars.target_memory == 0 || memory_vars.user_memory == 0 || target.buffer.base == 0){ + if (memory_vars.vars_memory == 0 || memory_vars.target_memory == 0 || memory_vars.user_memory == 0){ alloc_success = false; } diff --git a/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index df1087d8..ee6ad894 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -46,7 +46,6 @@ #include "4ed_font_set.h" #include "4ed_system.h" #include "4ed_render_target.h" -#include "4ed_render_format.h" #include "4ed.h" #include