From 8b5ff08fb0cd62fd70caee351330a5dff395c6f3 Mon Sep 17 00:00:00 2001 From: SlyVTT Date: Wed, 3 May 2023 22:37:23 +0200 Subject: [PATCH] added line Shader --- azur/CMakeLists.txt | 4 +- azur/include/azur/gint/render.h | 5 + azur/src/gint/render.c | 2 +- azur/src/gint/shaders/line.c | 156 ++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 azur/src/gint/shaders/line.c diff --git a/azur/CMakeLists.txt b/azur/CMakeLists.txt index 39a1ffd..454266e 100644 --- a/azur/CMakeLists.txt +++ b/azur/CMakeLists.txt @@ -67,7 +67,9 @@ if(AZUR_GRAPHICS_GINT_CG) src/gint/shaders/image_p4_dye.c # Triangle shader src/gint/shaders/triangle.c - src/gint/shaders/triangle.S) + src/gint/shaders/triangle.S + # Line shader + src/gint/shaders/line.c) endif() add_library(azur STATIC ${SOURCES}) diff --git a/azur/include/azur/gint/render.h b/azur/include/azur/gint/render.h index a5ea06f..62487e1 100644 --- a/azur/include/azur/gint/render.h +++ b/azur/include/azur/gint/render.h @@ -205,6 +205,9 @@ void azrp_subimage(int x, int y, bopti_image_t const *image, void azrp_triangle(int x1, int y1, int x2, int y2, int x3, int y3, int color); +void azrp_line( int x1, int y1, int x2, int y2, int color); + + /* See below for more detailed image functions. Dynamic effects are provided with the same naming convention as gint. */ @@ -216,6 +219,8 @@ void azrp_shader_image_rgb16_configure(void); void azrp_shader_image_p8_configure(void); void azrp_shader_image_p4_configure(void); void azrp_shader_triangle_configure(void); +void azrp_shader_line_configure(void); + //--- // Performance indicators diff --git a/azur/src/gint/render.c b/azur/src/gint/render.c index 4926f52..c115ef8 100644 --- a/azur/src/gint/render.c +++ b/azur/src/gint/render.c @@ -30,7 +30,7 @@ static int commands_count=0, commands_length=0; Rendering order is integer order. */ static uint32_t commands_array[AZRP_MAX_COMMANDS]; -static GALIGNED(4) uint8_t commands_data[16384]; +static GALIGNED(4) uint8_t commands_data[4*16384]; /* Array of shader programs and uniforms. */ static azrp_shader_t *shaders[AZRP_MAX_SHADERS] = { NULL }; diff --git a/azur/src/gint/shaders/line.c b/azur/src/gint/shaders/line.c new file mode 100644 index 0000000..788086b --- /dev/null +++ b/azur/src/gint/shaders/line.c @@ -0,0 +1,156 @@ +#include + +uint8_t AZRP_SHADER_LINE = -1; + +__attribute__((constructor)) +static void register_shader(void) +{ + extern azrp_shader_t azrp_shader_line; + AZRP_SHADER_LINE = azrp_register_shader(azrp_shader_line); +} + +void azrp_shader_line_configure(void) +{ + azrp_set_uniforms(AZRP_SHADER_LINE, (void *)azrp_width); +} + +static int min(int x, int y) +{ + return (x < y) ? x : y; +} +static int max(int x, int y) +{ + return (x > y) ? x : y; +} + +//--- + +struct command { + uint8_t shader_id; + uint16_t color; + uint16_t curr_y; + uint16_t curr_x; + int16_t dx, dy, sx, sy; + int16_t cumul; + int16_t i; +}; + +int ABS( int x1 ) +{ + if (x1 >= 0) return x1; + else return (-1 * x1); +} + +int SGN( int x1 ) +{ + if (x1 > 0) return 1; + else if (x1 = 0) return 0; + else return -1; +} + +void azrp_line(int xA, int yA, int xB, int yB, int color) +{ + prof_enter(azrp_perf_cmdgen); + + int x1, x2; + int y1, y2; + + + // we swap to always start with the point on top as the fragment are updated from top to bottom + if (yA <= yB) + { + x1 = xA; + y1 = yA; + x2 = xB; + y2 = yB; + } + else + { + x1 = xB; + y1 = yB; + x2 = xA; + y2 = yA; + } + + + int frag_first = y1 >> 4; + int frag_last = y2 >> 4; + int frag_count = frag_last - frag_first + 1; + + struct command cmd; + cmd.shader_id = AZRP_SHADER_LINE; + cmd.color = color; + + cmd.curr_x = x1; + cmd.curr_y = y1 & 15; + + cmd.dx = ABS(x2-x1); + cmd.sx = SGN(x2-x1); + + cmd.dy = ABS(y2-y1); + cmd.sy = SGN(y2-y1); + + cmd.i = 1; + cmd.cumul = (cmd.dx >= cmd.dy) ? cmd.dx >> 1 : cmd.dy >> 1; + + azrp_queue_command(&cmd, sizeof cmd, frag_first, frag_count); + prof_leave(azrp_perf_cmdgen); +} + +void azrp_shader_line( void *uniforms, void *comnd, void *fragment ) +{ + struct command *cmd = (struct command *) comnd; + uint16_t *frag = (uint16_t *) fragment; + + frag[ azrp_width * cmd->curr_y + cmd->curr_x ] = cmd->color; + + int i; + + if (cmd->dy == 0) + { + for( i = cmd->i; i < cmd->dx-1 ; i++ ) + { + cmd->curr_x += cmd->sx; + frag[ azrp_width * cmd->curr_y + cmd->curr_x ] = cmd->color; + } + } + else if (cmd->dx >= cmd->dy) + { + for( i = cmd->i; i < cmd->dx-1; i++ ) + { + cmd->curr_x += cmd->sx; + cmd->cumul += cmd->dy; + if (cmd->cumul > cmd->dx) + { + cmd->cumul -= cmd->dx; + cmd->curr_y += cmd->sy; + } + // if curr_y=16, this means we are changing to next fragment + if (cmd->curr_y == azrp_frag_height ) break; + + frag[ azrp_width * cmd->curr_y + cmd->curr_x ] = cmd->color; + } + } + else + { + for( i = cmd->i; i < cmd->dy-1; i++ ) + { + cmd->curr_y += cmd->sy; + cmd->cumul += cmd->dx; + if (cmd->cumul > cmd->dy) + { + cmd->cumul -= cmd->dy; + cmd->curr_x += cmd->sx; + } + + // if curr_y=16, this means we are changing to next fragment + if (cmd->curr_y == azrp_frag_height) break; + + frag[ azrp_width * cmd->curr_y + cmd->curr_x ] = cmd->color; + } + } + + cmd->curr_y &= 15; + + cmd->i = i; +} \ No newline at end of file