forked from Lephenixnoir/Azur
153 lines
3.1 KiB
C
153 lines
3.1 KiB
C
#include <azur/gint/render.h>
|
|
|
|
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; i<nbPix[cmd->currfrag]; i++ )
|
|
{
|
|
|
|
frag[ azrp_width * currFragPix[i].y + currFragPix[i].x ] = cmd->color;
|
|
}
|
|
|
|
cmd->currfrag++;
|
|
|
|
} |