293 lines
8.5 KiB
C++
293 lines
8.5 KiB
C++
#include "../config.h"
|
|
|
|
#include <azur/gint/render.h>
|
|
#include "MyAzurShaders.h"
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
|
|
#include <gint/rtc.h>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#define DARKSKY 0x2106
|
|
|
|
#define BLUE1 0x39EE
|
|
#define BLUE2 0x3310
|
|
#define BLUE3 0x64DF
|
|
|
|
#define PINK1 0x4147
|
|
#define PINK2 0x7211
|
|
#define PINK3 0xD3D7
|
|
|
|
#define GREEN1 0x31E7
|
|
#define GREEN2 0x4245
|
|
#define GREEN3 0x34AD
|
|
|
|
#define ORANGE1 0x61C6
|
|
#define ORANGE2 0x8AA7
|
|
#define ORANGE3 0xDB83
|
|
|
|
#define WHITE1 0x31A6
|
|
#define WHITE2 0x9CD3
|
|
#define WHITE3 0xFFFF
|
|
|
|
uint8_t AZRP_SHADER_STARFIELD = -1;
|
|
|
|
struct particle
|
|
{
|
|
int x, y, s, c, frag, off;
|
|
particle( int _x, int _y, int _s, int _c, int _f, int _o ) : x(_x), y(_y), s(_s), c(_c), frag(_f), off(_o) {};
|
|
};
|
|
|
|
struct star
|
|
{
|
|
int x, y, s, n, t;
|
|
star( int _x, int _y, int _s, int _n, int _t ) : x(_x), y(_y), s(_s), n(_n), t(_t) {};
|
|
star() {};
|
|
};
|
|
|
|
std::vector<particle*> pixels;
|
|
std::vector<star*> starfield;
|
|
|
|
|
|
static void azrp_shader_starfield_configure(void)
|
|
{
|
|
azrp_set_uniforms(AZRP_SHADER_STARFIELD, (void *)azrp_width);
|
|
}
|
|
|
|
|
|
__attribute__((constructor))
|
|
static void register_shader(void)
|
|
{
|
|
extern azrp_shader_t azrp_shader_starfield;
|
|
AZRP_SHADER_STARFIELD = azrp_register_shader(azrp_shader_starfield, azrp_shader_starfield_configure );
|
|
}
|
|
|
|
|
|
void azrp_starfield_init( uint8_t nbstars )
|
|
{
|
|
|
|
for(auto&s : starfield)
|
|
delete(s);
|
|
|
|
starfield.clear();
|
|
|
|
|
|
srand(rtc_ticks());
|
|
|
|
|
|
for(int i=0; i<nbstars; i++)
|
|
{
|
|
star *temp = new star();
|
|
temp->x = rand( ) % 394;
|
|
temp->y = rand( ) % 222;
|
|
temp->s = 1 + rand( ) % 3; // 1,2,3 : speed of the star
|
|
temp->n = 1 + rand( ) % 4; // 1,2,3,4 : size of the star
|
|
temp->t = 1 + rand( ) % 12; // 1..12 : colorcode of the star
|
|
starfield.push_back( temp );
|
|
}
|
|
|
|
|
|
for(auto& s : starfield)
|
|
{
|
|
uint16_t col1, col2, col3;
|
|
|
|
if (s->t==1 || s->t==2)
|
|
{
|
|
col1 = BLUE1;
|
|
col2 = BLUE2;
|
|
col3 = BLUE3;
|
|
}
|
|
else if (s->t==3 || s->t==4)
|
|
{
|
|
col1 = PINK1;
|
|
col2 = PINK2;
|
|
col3 = PINK3;
|
|
}
|
|
else if (s->t==5 || s->t==6)
|
|
{
|
|
col1 = GREEN1;
|
|
col2 = GREEN2;
|
|
col3 = GREEN3;
|
|
}
|
|
else if (s->t==7 || s->t==8)
|
|
{
|
|
col1 = ORANGE1;
|
|
col2 = ORANGE2;
|
|
col3 = ORANGE3;
|
|
}
|
|
else
|
|
{
|
|
col1 = WHITE1;
|
|
col2 = WHITE2;
|
|
col3 = WHITE3;
|
|
}
|
|
|
|
|
|
|
|
particle *ptemp;
|
|
|
|
if (s->n==1 || s->n==2)
|
|
{
|
|
ptemp = new particle( s->x, s->y, s->s, col2, s->y/16, s->y&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+1, s->y, s->s, col2, s->y/16, s->y&15 );
|
|
pixels.push_back( ptemp );
|
|
|
|
ptemp = new particle( s->x, s->y+1, s->s, col2, (s->y+1)/16, (s->y+1)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+1, s->y+1, s->s, col2, (s->y+1)/16, (s->y+1)&15 );
|
|
pixels.push_back( ptemp );
|
|
}
|
|
else if (s->n==3)
|
|
{
|
|
ptemp = new particle( s->x, s->y, s->s, DARKSKY, s->y/16, s->y&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+1, s->y, s->s, col3, s->y/16, s->y&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+2, s->y, s->s, DARKSKY, s->y/16, s->y&15 );
|
|
pixels.push_back( ptemp );
|
|
|
|
ptemp = new particle( s->x, s->y+1, s->s, col3, (s->y+1)/16, (s->y+1)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+1, s->y+1, s->s, col2, (s->y+1)/16, (s->y+1)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+2, s->y+1, s->s, col3, (s->y+1)/16, (s->y+1)&15 );
|
|
pixels.push_back( ptemp );
|
|
|
|
ptemp = new particle( s->x, s->y+2, s->s, DARKSKY, (s->y+2)/16, (s->y+2)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+1, s->y+2, s->s, col3, (s->y+2)/16, (s->y+2)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+2, s->y+2, s->s, DARKSKY, (s->y+2)/16, (s->y+2)&15 );
|
|
pixels.push_back( ptemp );
|
|
}
|
|
else if (s->n==4)
|
|
{
|
|
ptemp = new particle( s->x+1, s->y, s->s, col1, s->y/16, s->y&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+2, s->y, s->s, col1, s->y/16, s->y&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+3, s->y, s->s, col1, s->y/16, s->y&15 );
|
|
pixels.push_back( ptemp );
|
|
|
|
ptemp = new particle( s->x, s->y+1, s->s, col1, (s->y+1)/16, (s->y+1)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+1, s->y+1, s->s, col2, (s->y+1)/16, (s->y+1)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+2, s->y+1, s->s, col2, (s->y+1)/16, (s->y+1)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+3, s->y+1, s->s, col2, (s->y+1)/16, (s->y+1)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+4, s->y+1, s->s, col1, (s->y+1)/16, (s->y+1)&15 );
|
|
pixels.push_back( ptemp );
|
|
|
|
ptemp = new particle( s->x, s->y+2, s->s, col1, (s->y+2)/16, (s->y+2)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+1, s->y+2, s->s, col2, (s->y+2)/16, (s->y+2)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+2, s->y+2, s->s, col3, (s->y+2)/16, (s->y+2)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+3, s->y+2, s->s, col2, (s->y+2)/16, (s->y+2)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+4, s->y+2, s->s, col1, (s->y+2)/16, (s->y+2)&15 );
|
|
pixels.push_back( ptemp );
|
|
|
|
ptemp = new particle( s->x, s->y+3, s->s, col1, (s->y+3)/16, (s->y+3)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+1, s->y+3, s->s, col2, (s->y+3)/16, (s->y+3)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+2, s->y+3, s->s, col2, (s->y+3)/16, (s->y+3)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+3, s->y+3, s->s, col2, (s->y+3)/16, (s->y+3)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+4, s->y+3, s->s, col1, (s->y+3)/16, (s->y+3)&15 );
|
|
pixels.push_back( ptemp );
|
|
|
|
ptemp = new particle( s->x+1, s->y+4, s->s, col1, (s->y+4)/16, (s->y+4)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+2, s->y+4, s->s, col1, (s->y+4)/16, (s->y+4)&15 );
|
|
pixels.push_back( ptemp );
|
|
ptemp = new particle( s->x+3, s->y+4, s->s, col1, (s->y+4)/16, (s->y+4)&15 );
|
|
pixels.push_back( ptemp );
|
|
}
|
|
// else
|
|
// {
|
|
// ptemp = new particle( s->x, s->y, s->s, col3, s->y/16, s->y&15 );
|
|
// pixels.push_back( ptemp );
|
|
// }
|
|
}
|
|
}
|
|
|
|
|
|
void azrp_starfield_close( void )
|
|
{
|
|
for(auto&p : pixels)
|
|
delete(p);
|
|
|
|
pixels.clear();
|
|
|
|
for(auto&s : starfield)
|
|
delete(s);
|
|
|
|
starfield.clear();
|
|
}
|
|
|
|
|
|
struct command {
|
|
uint8_t shader_id;
|
|
uint8_t current_frag;
|
|
uint8_t nbpixel;
|
|
particle **data;
|
|
};
|
|
|
|
|
|
void azrp_starfield( void )
|
|
{
|
|
prof_enter(azrp_perf_cmdgen);
|
|
|
|
int fragmin = 0;
|
|
int fragcount = (223 >> 4) + 1;
|
|
|
|
|
|
|
|
struct command *cmd = (struct command *) azrp_new_command(sizeof *cmd, fragmin, fragcount);
|
|
if(!cmd) {
|
|
prof_leave(azrp_perf_cmdgen);
|
|
return;
|
|
}
|
|
|
|
cmd->shader_id = AZRP_SHADER_STARFIELD;
|
|
cmd->current_frag = 0;
|
|
cmd->nbpixel = pixels.size();
|
|
cmd->data = pixels.data();
|
|
|
|
for(unsigned int i=0; i<pixels.size(); i++)
|
|
{
|
|
pixels[i]->x = (pixels[i]->x - pixels[i]->s) % 396;
|
|
pixels[i]->frag = pixels[i]->y / 16;
|
|
pixels[i]->off = pixels[i]->y & 15;
|
|
}
|
|
|
|
prof_leave(azrp_perf_cmdgen);
|
|
}
|
|
|
|
|
|
void azrp_shader_starfield( void *uniforms, void *comnd, void *fragment )
|
|
{
|
|
struct command *cmd = (struct command *) comnd;
|
|
uint16_t *frag = (uint16_t *) fragment;
|
|
|
|
for(int i=0; i<cmd->nbpixel; i++)
|
|
{
|
|
particle *currentpart = cmd->data[i];
|
|
|
|
if (cmd->current_frag == currentpart->frag)
|
|
{
|
|
frag[azrp_width * currentpart->off + currentpart->x] = currentpart->c;
|
|
}
|
|
}
|
|
cmd->current_frag++;
|
|
} |