4coder/4ed_render_target.cpp

104 lines
2.7 KiB
C++

/*
* Mr. 4th Dimention - Allen Webster
*
* 10.11.2017
*
* Render target function implementations.
*
*/
// 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);
}
else{
t->out_of_memory = true;
}
return(out);
}
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 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;
}
// 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);
}
return(out);
}
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);
return(result);
}
// BOTTOM