#include uint8_t AZRP_SHADER_CIRCLE = -1; __attribute__((constructor)) static void register_shader(void) { extern azrp_shader_t azrp_shader_circle; AZRP_SHADER_CIRCLE = azrp_register_shader(azrp_shader_circle); } void azrp_shader_circle_configure(void) { azrp_set_uniforms(AZRP_SHADER_CIRCLE, (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; } //--- typedef struct { uint16_t x; uint16_t y; }Pixel; Pixel TablePixels[14][396]; // 14 fragments each able to store as much pixels as width uint16_t NbPixels[14]; // Nunmber of pixels in each fragment struct command { uint8_t shader_id; uint16_t color; uint8_t currfrag; uint16_t* pixnb; Pixel **data; }; void AddPixel( int xp, int yp ) { if (xp >= 0 && xp < azrp_width && yp >= 0 && yp < azrp_height) { int currfrag = yp >> 4; uint16_t nbpixinfrag = NbPixels[ currfrag ]; TablePixels[ currfrag ][ nbpixinfrag ].x = xp; TablePixels[ currfrag ][ nbpixinfrag ].y = yp & 15; NbPixels[ currfrag ]++; } } void azrp_circle(int xc, int yc, int rad, int color) { prof_enter(azrp_perf_cmdgen); for(int i=0;i<14;i++) NbPixels[i]=0; int xmin = xc - rad; int xmax = xc + rad; int ymin = yc - rad; int ymax = yc + rad; // The circle is fully outside the screen if ((xmax < 0) || (xmin > azrp_width) || (ymax < 0) || (ymin > azrp_height)) { prof_leave(azrp_perf_cmdgen); return; } int ytop = max( xmin, 0 ); int ybot = min( xmax, azrp_height ); int frag_first = ytop >> 4; int frag_last = ybot >> 4; int frag_count = frag_last - frag_first + 1; struct command cmd; cmd.shader_id = AZRP_SHADER_CIRCLE; cmd.color = color; cmd.currfrag = frag_first; int x = 0; int y = rad; int d = rad - 1; while (y >= x) { AddPixel( xc+x, yc+y ); AddPixel( xc+y, yc+y ); AddPixel( xc-x, yc+y ); AddPixel( xc-y, yc+x ); AddPixel( xc+x, yc-y ); AddPixel( xc+y, yc-x ); AddPixel( xc-x, yc-y ); AddPixel( xc-y, yc-x ); if (d >= 2*x) { d = d - 2*x - 1; x++; } else if (d < 2*(rad-y)) { d = d + 2*y - 1; y--; } else { d = d + 2*(y - x - 1); y--; x++; } } cmd.pixnb = NbPixels; cmd.data = TablePixels; azrp_queue_command(&cmd, sizeof cmd, frag_first, frag_count); prof_leave(azrp_perf_cmdgen); } void azrp_shader_circle( void *uniforms, void *comnd, void *fragment ) { struct command *cmd = (struct command *) comnd; uint16_t *frag = (uint16_t *) fragment; uint16_t *nbPix = cmd->pixnb; uint16_t taille = nbPix[ cmd->currfrag ]; Pixel *pixData = cmd->data[ cmd->currfrag ]; for( int i=0; icurrfrag]; i++ ) { frag[ azrp_width * currFragPix[i].y + currFragPix[i].x ] = cmd->color; } cmd->currfrag++; }