diff --git a/CMakeLists.txt b/CMakeLists.txt index 855c84b..8d53632 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ set(SOURCES src/particles.cpp src/starfield.cpp src/pixelshader.cpp + src/pixellistshader.cpp # ... ) set(ASSETS_cg diff --git a/src/MyAzurShaders.h b/src/MyAzurShaders.h index 0984d65..9557aeb 100644 --- a/src/MyAzurShaders.h +++ b/src/MyAzurShaders.h @@ -1,4 +1,6 @@ - +#include "starfield.h" +#include void azrp_pixel(int x1, int y1, int color); +void azrp_pixellist(std::vector const &list, int fragnum ); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 45bafab..026489e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,6 +32,7 @@ bool screenshot = false; bool record = false; +bool textoutput = false; bool exitToOS = false; #define SCALE_PIXEL 1 @@ -42,25 +43,19 @@ bool exitToOS = false; #define NOBIAS (1-BIAS) std::vector MyParticles; -std::vector MyStars; +Starfield *MyStarField; uint8_t texttodraw=1; void Create_Starfield( void ) { - srand(rtc_ticks()); - - for(int i=0; i<100; i++) - { - Star *s = new Star( ); - MyStars.push_back( s ); - } + MyStarField = new Starfield(); } void Create_Explosion( void ) { - if(MyParticles.size()>=300) return; + if(MyParticles.size()>=150) return; srand(rtc_ticks()); @@ -78,7 +73,7 @@ void Create_Explosion( void ) static void update( float dt ) { // all update stuff depending on time will be done here - for(int i=0; iUpdate( dt ); @@ -90,8 +85,7 @@ static void update( float dt ) } } - for(auto&s : MyStars) - s->Update( dt ); + MyStarField->Update( dt ); } @@ -109,6 +103,8 @@ static void get_inputs( void ) if(keydown(KEY_7)) {screenshot = true; }; if(keydown(KEY_8)) {record = !record; }; + if(keydown(KEY_9)) {textoutput = true; }; + if(keydown(KEY_F1)) {texttodraw=0;} if(keydown(KEY_F2)) {texttodraw=1;} if(keydown(KEY_F3)) {texttodraw=2;} @@ -194,8 +190,7 @@ int main(void) for(auto& p : MyParticles) p->Render(); - for(auto& s : MyStars) - s->Render(); + MyStarField->Render(); azrp_update(); } @@ -226,15 +221,25 @@ int main(void) { usb_fxlink_videocapture(false); } - } + + if (textoutput && usb_is_open()) + { + char texttosend[1024]; + for(unsigned int i=0; iMyStars.size(); i++) + { + sprintf( texttosend, "Star %d : x=%d : y=%d : s=%d : c=%d", i, MyStarField->MyStars[i]->x, (int) MyStarField->MyStars[i]->y, MyStarField->MyStars[i]->size, MyStarField->MyStars[i]->color ); + usb_fxlink_text(texttosend, 0); + } + + textoutput = false; + } + } while (exitToOS==false); for(auto& p : MyParticles) delete(p); MyParticles.clear(); - for(auto& s : MyStars) delete(s); - MyStars.clear(); prof_quit(); diff --git a/src/pixellistshader.cpp b/src/pixellistshader.cpp new file mode 100644 index 0000000..a0b57a9 --- /dev/null +++ b/src/pixellistshader.cpp @@ -0,0 +1,54 @@ +#include +#include "MyAzurShaders.h" +#include "starfield.h" +#include + + +uint8_t AZRP_SHADER_PIXELLIST = -1; + + +__attribute__((constructor)) +static void register_shader(void) +{ + extern azrp_shader_t azrp_shader_pixellist; + AZRP_SHADER_PIXELLIST = azrp_register_shader(azrp_shader_pixellist); +} + + +void azrp_shader_pixellist_configure(void) +{ + azrp_set_uniforms(AZRP_SHADER_PIXELLIST, (void *)azrp_width); +} + + +struct command { + uint8_t shader_id; + uint16_t length; + Pixel * const *data; +}; + + +void azrp_pixellist(std::vector const &list, int fragnum ) +{ + prof_enter(azrp_perf_cmdgen); + + struct command cmd; + cmd.shader_id = AZRP_SHADER_PIXELLIST; + cmd.length = list.size(); + cmd.data = list.data(); + + azrp_queue_command(&cmd, sizeof cmd, fragnum, 1); + prof_leave(azrp_perf_cmdgen); +} + + +void azrp_shader_pixellist( void *uniforms, void *comnd, void *fragment ) +{ + struct command *cmd = (struct command *) comnd; + uint16_t *frag = (uint16_t *) fragment; + + for(int i = 0; i < cmd->length; i++) { + Pixel *pix = cmd->data[i]; + frag[azrp_width * pix->y + pix->x] = pix->c; + } +} \ No newline at end of file diff --git a/src/starfield.cpp b/src/starfield.cpp index c29725e..53fc556 100644 --- a/src/starfield.cpp +++ b/src/starfield.cpp @@ -5,6 +5,7 @@ #include #include +#include #include @@ -21,7 +22,15 @@ Star::Star( void ) sy = libnum::num( size ); + int colorrandom = rand() % 4; + color = 0xFFFF; +/* + if (colorrandom==0) color = 0xFFFF; + else if (colorrandom==1) color = 0xFFE0; + else if (colorrandom==2) color = 0xFB80; + else color = 0xF80D; +*/ } Star::~Star() @@ -30,50 +39,118 @@ Star::~Star() } -void Star::Update( float dt ) -{ - libnum::num a = libnum::num( dt / 12000.0f ); - y += sy * a; +void Star::Update( libnum::num dt ) +{ + //libnum::num a = libnum::num( dt / 12000.0f ); + //y += sy * a; + y+= sy * dt; - if (y > 224) + if (y >= 224) { x = rand() % 396; - y = 0; + y = libnum::num( 0 ); } } -void Star::Render( ) + + +Starfield::Starfield( ) { - if (size==1) + srand(rtc_ticks()); + + for(int i=0; i<100; i++) { - azrp_pixel( x, (int) y, color ); - } - else if (size==2) - { - azrp_pixel( x-1, (int) y-1, color ); - azrp_pixel( x-1, (int) y, color ); - azrp_pixel( x, (int) y-1, color ); - azrp_pixel( x, (int) y, color ); - } - else if (size==3) - { - azrp_pixel( x, (int) y-1, color ); - azrp_pixel( x-1, (int) y, color ); - azrp_pixel( x, (int) y, color ); - azrp_pixel( x+1, (int) y, color ); - azrp_pixel( x, (int) y+1, color ); - } - else if (size==4) - { - azrp_pixel( x-1, (int) y-1, color ); - azrp_pixel( x-1, (int) y, color ); - azrp_pixel( x-1, (int) y+1, color ); - azrp_pixel( x, (int) y-1, color ); - azrp_pixel( x, (int) y, color ); - azrp_pixel( x, (int) y+1, color ); - azrp_pixel( x+1, (int) y-1, color ); - azrp_pixel( x+1, (int) y, color ); - azrp_pixel( x+1, (int) y+1, color ); + Star *s = new Star( ); + MyStars.push_back( s ); } } +Starfield::~Starfield( ) +{ + for(auto& s : MyStars) + delete(s); + + for(auto& list : PixelListPerFragment) + { + for(auto& p : list) + delete(p); + list.clear(); + } + + MyStars.clear(); +} + +void Starfield::Update( float dt ) +{ + libnum::num a = libnum::num( dt / 50000.f ); + + for(auto& s : MyStars) + s->Update( a ); +} + +void Starfield::AddPixel( int x, int y, int c ) +{ + // check if the point is in the range screen + if(x >= azrp_width || x < 0 || y >= azrp_height || y < 0) + return; + + uint8_t current_frag = y >> 4; // each fragment is 16pixel high : so fragment number for the current point is y/16 or y>>4 + Pixel *MyPix = new Pixel( x, y & 15, c ); // consider the local offset of the point in the current fragment (y & 15) + PixelListPerFragment[ current_frag ].push_back( MyPix ); // add the pixel to the appropriate list +} + +void Starfield::Render( void ) +{ + for(auto& list : PixelListPerFragment) + { + for(auto& p : list) + { + delete(p); + } + list.clear(); + } + + for(auto& s : MyStars) + { + //TODO :The only considered case is for a small star 1x1 pixel + //TODO :Other sizes to be added right after this case + if (s->size==1) + { + AddPixel( s->x, (int) s->y, s->color ); + } + else if (s->size==2) + { + AddPixel( s->x, (int) s->y, s->color ); + AddPixel( s->x+1, (int) s->y, s->color ); + AddPixel( s->x, (int) s->y+1, s->color ); + AddPixel( s->x+1, (int) s->y+1, s->color ); + } + else if (s->size==3) + { + AddPixel( s->x+1, (int) s->y, s->color ); + AddPixel( s->x-1, (int) s->y+1, s->color ); + AddPixel( s->x, (int) s->y+1, s->color ); + AddPixel( s->x+1, (int) s->y+1, s->color ); + AddPixel( s->x+1, (int) s->y+2, s->color ); + } + else if (s->size==4) + { + AddPixel( s->x-1, (int) s->y-1, s->color ); + AddPixel( s->x-1, (int) s->y, s->color ); + AddPixel( s->x-1, (int) s->y+1, s->color ); + AddPixel( s->x, (int) s->y-1, s->color ); + AddPixel( s->x, (int) s->y, s->color ); + AddPixel( s->x, (int) s->y+1, s->color ); + AddPixel( s->x+1, (int) s->y-1, s->color ); + AddPixel( s->x+1, (int) s->y, s->color ); + AddPixel( s->x+1, (int) s->y+1, s->color ); + } + } + + + // call the PixelList shader with the appropriate lists + for(unsigned int i=0; i<14; i++) + //for(unsigned int i=0; i #include +#include +#include + class Star { public: Star(); ~Star(); - void Update( float dt ); - void Render(); + //void Update( float dt ); + void Update( libnum::num dt ); + uint16_t x; libnum::num y; @@ -19,4 +23,34 @@ class Star uint16_t color; }; +class Pixel +{ + public: + int x, y, c; + Pixel( int _x, int _y, int _c) + { + x = _x; + y = _y; + c = _c; + }; + ~Pixel() {}; +}; + +class Starfield +{ + public: + // the Star collection + std::vector MyStars; + // list of all pixels to be rendered by Azur pixel shader fragment by fragment + std::array,14> PixelListPerFragment; + + Starfield( ); + ~Starfield( ); + void Update( float dt ); + void Render( void ); + + private: + void AddPixel( int x, int y, int c ); +}; + #endif //STARS_H \ No newline at end of file