Batched rendering 50%
This commit is contained in:
parent
6b3d61c035
commit
efa1515121
|
@ -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);
|
||||
|
|
|
@ -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));}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
return(out);
|
||||
if (group == 0){
|
||||
group = push_array_zero(&target->arena, Render_Group, 1);
|
||||
sll_queue_push(target->group_first, target->group_last, group);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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 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);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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,16 +384,67 @@ 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;
|
||||
}
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
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;
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <Windows.h>
|
||||
|
|
Loading…
Reference in New Issue