added command buffer clipping
This commit is contained in:
parent
1b7edff9c0
commit
5c14ed0a9e
@ -65,9 +65,7 @@ struct gui_input in = {0};
|
||||
struct gui_config config;
|
||||
struct gui_font font = {...};
|
||||
struct gui_memory memory = {...};
|
||||
struct gui_memory_status status;
|
||||
struct gui_command_buffer buffer;
|
||||
struct gui_command_list out;
|
||||
struct gui_panel panel;
|
||||
|
||||
gui_default_config(&config);
|
||||
@ -75,7 +73,7 @@ gui_panel_init(&panel, 50, 50, 220, 170,
|
||||
GUI_PANEL_BORDER|GUI_PANEL_MOVEABLE|
|
||||
GUI_PANEL_CLOSEABLE|GUI_PANEL_SCALEABLE|
|
||||
GUI_PANEL_MINIMIZABLE, &config, &font);
|
||||
gui_buffer_init_fixed(buffer, &memory);
|
||||
gui_buffer_init_fixed(buffer, &memory, GUI_CLIP);
|
||||
|
||||
while (1) {
|
||||
gui_input_begin(&input);
|
||||
@ -83,7 +81,10 @@ while (1) {
|
||||
gui_input_end(&input);
|
||||
|
||||
struct gui_canvas canvas;
|
||||
struct gui_command_list out;
|
||||
struct gui_panel_layout layout;
|
||||
struct gui_memory_status status;
|
||||
|
||||
gui_buffer_begin(&canvas, &buffer, window_width, window_height);
|
||||
gui_panel_begin(&layout, &panel, "Demo", &canvas, &input);
|
||||
gui_panel_row(&layout, 30, 1);
|
||||
|
@ -467,6 +467,7 @@ main(int argc, char *argv[])
|
||||
struct gui_input in;
|
||||
struct gui_font font;
|
||||
struct gui_memory memory;
|
||||
struct gui_memory_status status;
|
||||
struct gui_config config;
|
||||
struct gui_canvas canvas;
|
||||
struct gui_command_buffer buffer;
|
||||
@ -501,7 +502,7 @@ main(int argc, char *argv[])
|
||||
memset(&in, 0, sizeof in);
|
||||
memory.memory = calloc(MAX_MEMORY, 1);
|
||||
memory.size = MAX_MEMORY;
|
||||
gui_buffer_init_fixed(&buffer, &memory);
|
||||
gui_buffer_init_fixed(&buffer, &memory, GUI_CLIP);
|
||||
|
||||
font.userdata = xfont;
|
||||
font.height = (gui_float)xfont->height;
|
||||
@ -540,7 +541,7 @@ main(int argc, char *argv[])
|
||||
running = gui_panel_begin(&layout, &panel , "Demo", &canvas, &in);
|
||||
demo_panel(&layout, &demo);
|
||||
gui_panel_end(&layout, &panel);
|
||||
gui_buffer_end(&list, &buffer, &canvas, NULL);
|
||||
gui_buffer_end(&list, &buffer, &canvas, &status);
|
||||
|
||||
/* Draw */
|
||||
XClearWindow(xw.dpy, xw.win);
|
||||
|
67
gui.c
67
gui.c
@ -23,6 +23,8 @@
|
||||
#define ABS(a) (((a) < 0) ? -(a) : (a))
|
||||
#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
|
||||
#define INBOX(px, py, x, y, w, h) (BETWEEN(px, x, x+w) && BETWEEN(py, y, y+h))
|
||||
#define INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1) \
|
||||
(!(((x1 > (x0 + w0)) || ((x1 + w1) < x0) || (y1 > (y0 + h0)) || (y1 + h1) < y0)))
|
||||
|
||||
#define col_load(c,j,k,l,m) (c).r = (j), (c).g = (k), (c).b = (l), (c).a = (m)
|
||||
#define vec2_load(v,a,b) (v).x = (a), (v).y = (b)
|
||||
@ -953,6 +955,7 @@ gui_buffer_push(struct gui_command_buffer* buffer,
|
||||
|
||||
buffer->end = tail;
|
||||
buffer->allocated += size + alignment;
|
||||
buffer->needed += alignment;
|
||||
buffer->count++;
|
||||
return cmd;
|
||||
}
|
||||
@ -965,6 +968,12 @@ gui_buffer_push_scissor(struct gui_command_buffer *buffer, gui_float x, gui_floa
|
||||
if (!buffer) return;
|
||||
cmd = gui_buffer_push(buffer, GUI_COMMAND_SCISSOR, sizeof(*cmd));
|
||||
if (!cmd) return;
|
||||
|
||||
buffer->clip.x = x;
|
||||
buffer->clip.y = y;
|
||||
buffer->clip.w = w;
|
||||
buffer->clip.h = h;
|
||||
|
||||
cmd->x = x;
|
||||
cmd->y = y;
|
||||
cmd->w = w;
|
||||
@ -977,6 +986,14 @@ gui_buffer_push_line(struct gui_command_buffer *buffer, gui_float x0, gui_float
|
||||
{
|
||||
struct gui_command_line *cmd;
|
||||
if (!buffer) return;
|
||||
if (buffer->clipping == GUI_CLIP) {
|
||||
const struct gui_rect *r = &buffer->clip;
|
||||
if (!INBOX(x0, y0, r->x, r->y, r->w, r->h) &&
|
||||
(!INBOX(x1, y1, r->x, r->y, r->w, r->h))) {
|
||||
buffer->clipped_memory += sizeof(*cmd);
|
||||
buffer->clipped_cmds++;
|
||||
}
|
||||
}
|
||||
cmd = gui_buffer_push(buffer, GUI_COMMAND_LINE, sizeof(*cmd));
|
||||
if (!cmd) return;
|
||||
cmd->begin[0] = x0;
|
||||
@ -992,6 +1009,14 @@ gui_buffer_push_rect(struct gui_command_buffer *buffer, gui_float x, gui_float y
|
||||
{
|
||||
struct gui_command_rect *cmd;
|
||||
if (!buffer) return;
|
||||
if (buffer->clipping == GUI_CLIP) {
|
||||
const struct gui_rect *r = &buffer->clip;
|
||||
if (!INTERSECT(r->x, r->y, r->w, r->h, x, y, w, h)) {
|
||||
buffer->clipped_memory += sizeof(*cmd);
|
||||
buffer->clipped_cmds++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cmd = gui_buffer_push(buffer, GUI_COMMAND_RECT, sizeof(*cmd));
|
||||
if (!cmd) return;
|
||||
cmd->x = x;
|
||||
@ -1007,6 +1032,15 @@ gui_buffer_push_circle(struct gui_command_buffer *buffer, gui_float x, gui_float
|
||||
{
|
||||
struct gui_command_circle *cmd;
|
||||
if (!buffer) return;
|
||||
if (buffer->clipping == GUI_CLIP) {
|
||||
const struct gui_rect *r = &buffer->clip;
|
||||
if (!INTERSECT(r->x, r->y, r->w, r->h, x, y, w, h)) {
|
||||
buffer->clipped_memory += sizeof(*cmd);
|
||||
buffer->clipped_cmds++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cmd = gui_buffer_push(buffer, GUI_COMMAND_CIRCLE, sizeof(*cmd));
|
||||
if (!cmd) return;
|
||||
cmd->x = x;
|
||||
@ -1022,6 +1056,16 @@ gui_buffer_push_triangle(struct gui_command_buffer *buffer, gui_float x0, gui_fl
|
||||
{
|
||||
struct gui_command_triangle *cmd;
|
||||
if (!buffer) return;
|
||||
if (buffer->clipping == GUI_CLIP) {
|
||||
const struct gui_rect *r = &buffer->clip;
|
||||
if (!INBOX(x0, y0, r->x, r->y, r->w, r->h) &&
|
||||
!INBOX(x1, y1, r->x, r->y, r->w, r->h) &&
|
||||
!INBOX(x2, y2, r->x, r->y, r->w, r->h)) {
|
||||
buffer->clipped_memory += sizeof(*cmd);
|
||||
buffer->clipped_cmds++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cmd = gui_buffer_push(buffer, GUI_COMMAND_TRIANGLE, sizeof(*cmd));
|
||||
if (!cmd) return;
|
||||
cmd->a[0] = x0;
|
||||
@ -1041,6 +1085,14 @@ gui_buffer_push_text(struct gui_command_buffer *buffer, gui_float x, gui_float y
|
||||
struct gui_command_text *cmd;
|
||||
if (!buffer) return;
|
||||
if (!string || !length) return;
|
||||
if (buffer->clipping == GUI_CLIP) {
|
||||
const struct gui_rect *r = &buffer->clip;
|
||||
if (!INTERSECT(r->x, r->y, r->w, r->h, x, y, w, h)) {
|
||||
buffer->clipped_memory += sizeof(*cmd);
|
||||
buffer->clipped_cmds++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cmd = gui_buffer_push(buffer, GUI_COMMAND_TEXT, sizeof(*cmd) + length + 1);
|
||||
if (!cmd) return;
|
||||
cmd->x = x;
|
||||
@ -1056,18 +1108,22 @@ gui_buffer_push_text(struct gui_command_buffer *buffer, gui_float x, gui_float y
|
||||
}
|
||||
|
||||
void
|
||||
gui_buffer_init_fixed(struct gui_command_buffer *buffer, const struct gui_memory *memory)
|
||||
gui_buffer_init_fixed(struct gui_command_buffer *buffer, const struct gui_memory *memory,
|
||||
enum gui_clipping clipping)
|
||||
{
|
||||
zero(buffer, sizeof(*buffer));
|
||||
buffer->memory = memory->memory;
|
||||
buffer->capacity = memory->size;
|
||||
buffer->begin = buffer->memory;
|
||||
buffer->end = buffer->begin;
|
||||
buffer->clipping = clipping;
|
||||
buffer->clip = null_rect;
|
||||
buffer->grow_factor = 0;
|
||||
}
|
||||
|
||||
void
|
||||
gui_buffer_init(struct gui_command_buffer *buffer, const struct gui_allocator *memory,
|
||||
gui_size initial_size, gui_float grow_factor)
|
||||
gui_size initial_size, gui_float grow_factor, enum gui_clipping clipping)
|
||||
{
|
||||
zero(buffer, sizeof(*buffer));
|
||||
buffer->memory = memory->alloc(initial_size);
|
||||
@ -1076,6 +1132,8 @@ gui_buffer_init(struct gui_command_buffer *buffer, const struct gui_allocator *m
|
||||
buffer->begin = buffer->memory;
|
||||
buffer->end = buffer->begin;
|
||||
buffer->grow_factor = grow_factor;
|
||||
buffer->clip = null_rect;
|
||||
buffer->clipping = clipping;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1103,6 +1161,8 @@ gui_buffer_end(struct gui_command_list *list, struct gui_command_buffer *buffer,
|
||||
status->size = buffer->capacity;
|
||||
status->allocated = buffer->allocated;
|
||||
status->needed = buffer->needed;
|
||||
status->clipped_commands = buffer->clipped_cmds;
|
||||
status->clipped_memory = buffer->clipped_memory;
|
||||
}
|
||||
if (list) {
|
||||
list->count = buffer->count;
|
||||
@ -1114,6 +1174,9 @@ gui_buffer_end(struct gui_command_list *list, struct gui_command_buffer *buffer,
|
||||
buffer->needed = 0;
|
||||
buffer->allocated = 0;
|
||||
buffer->count = 0;
|
||||
buffer->clip = null_rect;
|
||||
buffer->clipped_cmds = 0;
|
||||
buffer->clipped_memory = 0;
|
||||
zero(canvas, sizeof(*canvas));
|
||||
}
|
||||
|
||||
|
18
gui.h
18
gui.h
@ -258,11 +258,20 @@ struct gui_command_text {
|
||||
gui_char string[1];
|
||||
};
|
||||
|
||||
enum gui_clipping {
|
||||
GUI_NO_CLIP,
|
||||
GUI_CLIP
|
||||
};
|
||||
|
||||
struct gui_command_buffer {
|
||||
void *memory;
|
||||
struct gui_allocator allocator;
|
||||
struct gui_command *begin;
|
||||
struct gui_command *end;
|
||||
struct gui_rect clip;
|
||||
enum gui_clipping clipping;
|
||||
gui_size clipped_cmds;
|
||||
gui_size clipped_memory;
|
||||
gui_float grow_factor;
|
||||
gui_size allocated;
|
||||
gui_size capacity;
|
||||
@ -280,6 +289,8 @@ struct gui_memory_status {
|
||||
gui_size size;
|
||||
gui_size allocated;
|
||||
gui_size needed;
|
||||
gui_size clipped_commands;
|
||||
gui_size clipped_memory;
|
||||
};
|
||||
|
||||
enum gui_panel_colors {
|
||||
@ -382,10 +393,11 @@ void gui_input_char(struct gui_input*, const gui_glyph);
|
||||
void gui_input_end(struct gui_input*);
|
||||
|
||||
|
||||
/* Output */
|
||||
/* Buffer */
|
||||
void gui_buffer_init(struct gui_command_buffer*, const struct gui_allocator*,
|
||||
gui_size initial_size, gui_float grow_factor);
|
||||
void gui_buffer_init_fixed(struct gui_command_buffer*, const struct gui_memory*);
|
||||
gui_size initial_size, gui_float grow_factor, enum gui_clipping);
|
||||
void gui_buffer_init_fixed(struct gui_command_buffer*, const struct gui_memory*,
|
||||
enum gui_clipping);
|
||||
void gui_buffer_begin(struct gui_canvas *canvas, struct gui_command_buffer *buffer,
|
||||
gui_size width, gui_size height);
|
||||
void *gui_buffer_push(struct gui_command_buffer*,
|
||||
|
Loading…
Reference in New Issue
Block a user