forked from Lephenixnoir/Azur
added azrp_filledcircle shader
This commit is contained in:
parent
4f97d9e40c
commit
69a7ece6f9
|
@ -0,0 +1,8 @@
|
|||
Polygon shader
|
||||
Filled polygon shader
|
||||
|
||||
Ellipse shader
|
||||
Filled ellipse shader
|
||||
|
||||
Better font shader
|
||||
|
|
@ -77,6 +77,7 @@ if(AZUR_GRAPHICS_GINT_CG)
|
|||
src/gint/shaders/line.c
|
||||
# Circle shader
|
||||
src/gint/shaders/circle.c
|
||||
src/gint/shaders/filledcircle.c
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -211,6 +211,8 @@ void azrp_line( int x1, int y1, int x2, int y2, uint16_t color );
|
|||
/* azrp_circle() : Draw a circle with clipping to the screen resolution with a center (xc,yc) and a radius rad */
|
||||
void azrp_circle( int xc, int yx, uint16_t rad, uint16_t color );
|
||||
|
||||
/* azrp_filledcircle() : Draw a filled circle with clipping to the screen resolution with a center (xc,yc) and a radius rad */
|
||||
void azrp_filledcircle( int xc, int yx, uint16_t rad, uint16_t color );
|
||||
|
||||
/* See below for more detailed image functions. Dynamic effects are provided
|
||||
with the same naming convention as gint. */
|
||||
|
@ -223,8 +225,11 @@ 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);
|
||||
|
||||
void azrp_shader_circle_configure(void);
|
||||
void azrp_shader_filledcircle_configure(void);
|
||||
|
||||
//---
|
||||
// Performance indicators
|
||||
|
|
|
@ -37,7 +37,7 @@ struct command {
|
|||
uint16_t DataPixelsY[14*TABLE_WIDTH]; // 14 fragments each able to store as much pixels as width
|
||||
};
|
||||
|
||||
void AddPixel( int16_t xp, int16_t yp, struct command *cmd )
|
||||
void AddPixelCircle( int16_t xp, int16_t yp, struct command *cmd )
|
||||
{
|
||||
if (xp >= 0 && xp < azrp_width && yp >= 0 && yp < azrp_height)
|
||||
{
|
||||
|
@ -95,14 +95,14 @@ void azrp_circle(int xc, int yc, uint16_t rad, uint16_t color)
|
|||
|
||||
while (x <= y)
|
||||
{
|
||||
AddPixel( xc+x, yc+y, &cmd );
|
||||
AddPixel( xc+y, yc+x, &cmd );
|
||||
AddPixel( xc-x, yc+y, &cmd );
|
||||
AddPixel( xc-y, yc+x, &cmd );
|
||||
AddPixel( xc+x, yc-y, &cmd );
|
||||
AddPixel( xc+y, yc-x, &cmd );
|
||||
AddPixel( xc-x, yc-y, &cmd );
|
||||
AddPixel( xc-y, yc-x, &cmd );
|
||||
AddPixelCircle( xc+x, yc+y, &cmd );
|
||||
AddPixelCircle( xc+y, yc+x, &cmd );
|
||||
AddPixelCircle( xc-x, yc+y, &cmd );
|
||||
AddPixelCircle( xc-y, yc+x, &cmd );
|
||||
AddPixelCircle( xc+x, yc-y, &cmd );
|
||||
AddPixelCircle( xc+y, yc-x, &cmd );
|
||||
AddPixelCircle( xc-x, yc-y, &cmd );
|
||||
AddPixelCircle( xc-y, yc-x, &cmd );
|
||||
|
||||
if (m > 0)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
#include <azur/gint/render.h>
|
||||
|
||||
uint8_t AZRP_SHADER_FILLEDCIRCLE = -1;
|
||||
|
||||
__attribute__((constructor))
|
||||
static void register_shader(void)
|
||||
{
|
||||
extern azrp_shader_t azrp_shader_filledcircle;
|
||||
AZRP_SHADER_FILLEDCIRCLE = azrp_register_shader(azrp_shader_filledcircle);
|
||||
}
|
||||
|
||||
void azrp_shader_filledcircle_configure(void)
|
||||
{
|
||||
azrp_set_uniforms(AZRP_SHADER_FILLEDCIRCLE, (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;
|
||||
}
|
||||
|
||||
//---
|
||||
|
||||
#define TABLE_WIDTH
|
||||
|
||||
struct command {
|
||||
uint8_t shader_id;
|
||||
uint16_t color;
|
||||
uint8_t curr_frag;
|
||||
int16_t DataFilling[2*224]; // Each line of the screen can have a xmin and a xmax value
|
||||
};
|
||||
|
||||
void AddPixelFilledCircle( int16_t xpmin, int16_t xpmax, int16_t yp, struct command *cmd )
|
||||
{
|
||||
if (yp >= 0 && yp < azrp_height)
|
||||
{
|
||||
if (xpmin>=0) cmd->DataFilling[2*yp] = xpmin;
|
||||
else cmd->DataFilling[2*yp] = 0;
|
||||
|
||||
if (xpmax<azrp_width) cmd->DataFilling[2*yp+1] = xpmax;
|
||||
else cmd->DataFilling[2*yp+1] = azrp_width-1;
|
||||
}
|
||||
}
|
||||
|
||||
void azrp_filledcircle(int xc, int yc, uint16_t rad, uint16_t color)
|
||||
{
|
||||
prof_enter(azrp_perf_cmdgen);
|
||||
|
||||
|
||||
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( ymin, 0 );
|
||||
int ybot = min( ymax, azrp_height-1 );
|
||||
|
||||
int frag_first = ytop / azrp_frag_height;
|
||||
int frag_last = ybot / azrp_frag_height;
|
||||
int frag_count = frag_last - frag_first + 1;
|
||||
|
||||
|
||||
struct command cmd;
|
||||
cmd.shader_id = AZRP_SHADER_FILLEDCIRCLE;
|
||||
cmd.color = color;
|
||||
cmd.curr_frag = frag_first;
|
||||
|
||||
// reset the point counters in each cell of the table
|
||||
for( int i = 0; i < 224; i++ )
|
||||
{
|
||||
cmd.DataFilling[2*i] = -1; // reset with value equels -1
|
||||
cmd.DataFilling[2*i+1] = -1; // reset with value equals -1
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
int y = rad;
|
||||
int m = 5 - 4*rad;
|
||||
|
||||
while (x <= y)
|
||||
{
|
||||
AddPixelFilledCircle( xc-x, xc+x, yc-y, &cmd );
|
||||
AddPixelFilledCircle( xc-y, xc+y, yc-x, &cmd );
|
||||
AddPixelFilledCircle( xc-x, xc+x, yc+y, &cmd );
|
||||
AddPixelFilledCircle( xc-y, xc+y, yc+x, &cmd );
|
||||
|
||||
if (m > 0)
|
||||
{
|
||||
y--;
|
||||
m -= 8*y;
|
||||
}
|
||||
x++;
|
||||
m += 8*x + 4;
|
||||
}
|
||||
|
||||
azrp_queue_command(&cmd, sizeof cmd, frag_first, frag_count);
|
||||
prof_leave(azrp_perf_cmdgen);
|
||||
}
|
||||
|
||||
void azrp_shader_filledcircle( void *uniforms, void *comnd, void *fragment )
|
||||
{
|
||||
struct command *cmd = (struct command *) comnd;
|
||||
uint16_t *frag = (uint16_t *) fragment;
|
||||
|
||||
int16_t* data = (int16_t *) cmd->DataFilling;
|
||||
int BaseAdress = cmd->curr_frag * azrp_frag_height * 2;
|
||||
|
||||
for( int i = 0; i < azrp_frag_height; i++ )
|
||||
{
|
||||
int16_t Xmin = data[ BaseAdress + 2*i ];
|
||||
int16_t Xmax = data[ BaseAdress + 2*i+1 ];
|
||||
|
||||
if (Xmin!=-1 && Xmax !=-1)
|
||||
for (int j=Xmin ; j<=Xmax ; j++)
|
||||
frag[ azrp_width * i + j ] = cmd->color;
|
||||
}
|
||||
|
||||
cmd->curr_frag++;
|
||||
}
|
Loading…
Reference in New Issue