- Código: Seleccionar todo
- #include <iostream>
 #include <cmath>
 #include <list>
 #include <SDL/SDL.h>
 using namespace std;
 #define S_W 1024
 #define S_H 768
 #define bpp 2
 int pow(int n, int e) {
 if (e == 0) return 1;
 return n*pow(n, e-1);
 }
 double min(double a, double b) {
 if (a <= b) return a;
 return b;
 }
 void draw_circle3(int x, int y, int r, double alp0, SDL_Surface* s);
 void draw_circle3(int x, int y, int r, double alp0, SDL_Surface* s);
 class Atomo {
 public:
 Atomo(int x, int y);
 void update(double ax);
 void draw(SDL_Surface* screen);
 bool finished();
 int prior;
 private:
 double x, y, dy;
 double dx;
 double r, dr;
 double alpha, dalpha;
 };
 Atomo :: Atomo(int x, int y) {
 prior = rand();
 this->x = x+rand()%5-2; this->y = y+rand()%5-2;
 dx = rand()%10/10.0-0.5; dy = 4;
 alpha = 0.3 + rand()%10/100.0; dalpha = 0.015;
 r = 2 + rand()%3; dr = 2.5;
 }
 void Atomo :: update(double ax) {
 dx += ax + rand()%10/10.0-0.5;
 x += dx;
 y -= dy + rand()%3-1;
 alpha += dalpha + rand()%5/100;
 r += dr + rand()%3-1;
 }
 void Atomo :: draw(SDL_Surface* screen) {
 draw_circle3(x, y, r, alpha, screen);
 }
 bool Atomo :: finished() {
 return alpha >= 0.93 or x >= S_W or x < 0 or y < 0;
 }
 void put_pixel(SDL_Surface* screen, int row, int col, unsigned int color, double alp) {
 if (alp >= 1) return;
 Uint16 *pdest = (Uint16*)screen->pixels;
 pdest += screen->pitch/2*row;
 pdest += col;
 Uint16 c = *pdest;
 unsigned int r = (c&0x0000F800)>>11;
 unsigned int g = (c&0x000007E0)>>5;
 unsigned int b = (c&0x0000001F);
 unsigned int rgb_color = (int(r*alp + color*(1-alp))<<11) | (int(g*alp + ((color<<1)|1)*(1-alp))<<5) | (int(b*alp + color*(1-alp)));
 *pdest = rgb_color;
 }
 void draw_circle3(int x, int y, int r, double alp0, SDL_Surface* s) {
 int j = 0;
 for (int ii = 1; ii <= r and y+ii < S_H; ++ii)
 put_pixel(s, y+ii,x,31-(1-cos((M_PI/2)*(pow(ii,2)+pow(j,2))/double(pow(r,2))))*20, 0);
 for (int ii = 1; ii <= r and y+ii >= 0; ++ii)
 put_pixel(s, y-ii,x,31-(1-cos((M_PI/2)*(pow(ii,2)+pow(j,2))/double(pow(r,2))))*20, 0);
 for (int ii = 1; ii <= r and x-ii >= 0; ++ii)
 put_pixel(s, y,x-ii,31-(1-cos((M_PI/2)*(pow(ii,2)+pow(j,2))/double(pow(r,2))))*20, 0);
 for (int ii = 1; ii <= r and x+ii < S_W; ++ii)
 put_pixel(s, y,x+ii,31-(1-cos((M_PI/2)*(pow(ii,2)+pow(j,2))/double(pow(r,2))))*20, 0);
 put_pixel(s, y,x,31-(1-cos((M_PI/2)*(pow(j,2)+pow(j,2))/double(pow(r,2))))*25, 0);
 for ( j = 1; j <= r; ++j) {
 int i = sqrt(r*r-(j*j));
 for (int ii = 1; ii <= i and y+ii < S_H and x+j < S_W; ++ii)
 put_pixel(s, y+ii,x+j,31-(1-cos((M_PI/2)*(pow(ii,2)+pow(j,2))/double(pow(r,2))))*20, min((1-cos((M_PI/2)*(pow(ii,2)+pow(j,2))/double(pow(r,2))))*0.99 + alp0, 1));
 for (int ii = 1; ii <= i and y+ii < S_H and x-j >= 0; ++ii)
 put_pixel(s, y+ii,x-j,31-(1-cos((M_PI/2)*(pow(ii,2)+pow(j,2))/double(pow(r,2))))*20, min((1-cos((M_PI/2)*(pow(ii,2)+pow(j,2))/double(pow(r,2))))*0.99 + alp0, 1));
 for (int ii = 1; ii <= i and y-ii >= 0 and x+j < S_W; ++ii)
 put_pixel(s, y-ii,x+j,31-(1-cos((M_PI/2)*(pow(ii,2)+pow(j,2))/double(pow(r,2))))*20, min((1-cos((M_PI/2)*(pow(ii,2)+pow(j,2))/double(pow(r,2))))*0.99 + alp0, 1));
 for (int ii = 1; ii <= i and y-ii >= 0 and x-j >= 0; ++ii)
 put_pixel(s, y-ii,x-j,31-(1-cos((M_PI/2)*(pow(ii,2)+pow(j,2))/double(pow(r,2))))*20, min((1-cos((M_PI/2)*(pow(ii,2)+pow(j,2))/double(pow(r,2))))*0.99 + alp0, 1));
 }
 }
 int main(int argc, char** argv) {
 cerr << SDL_Init(SDL_INIT_VIDEO);
 SDL_Surface *screen = SDL_SetVideoMode(S_W, S_H, bpp*8, SDL_HWSURFACE);
 SDL_ShowCursor(SDL_DISABLE);
 list<Atomo*> atomos;
 
 SDL_FillRect(screen, &screen->clip_rect, 0xF800);
 SDL_Event event;
 bool salir = false;
 int frame;
 while(not salir) {
 SDL_FillRect(screen, &screen->clip_rect, 0xF800);
 int t0 = SDL_GetTicks();
 if (!(++frame%5)) {
 Atomo* patomo = new Atomo(S_W/2, S_H - 20);
 list<Atomo*>::iterator ita = atomos.begin();
 while (ita != atomos.end() and (*ita)->prior > patomo->prior)
 ++ita;
 atomos.insert(--ita, patomo);
 }
 list<Atomo*>::iterator ita = atomos.begin();
 while (ita != atomos.end()) {
 if ((*ita)->finished()) {
 delete *ita;
 ita = atomos.erase(ita);
 }
 else {
 (*ita)->update(0.2);
 (*ita)->draw(screen);
 ++ita;
 }
 }
 int t1 = SDL_GetTicks();
 while (SDL_PollEvent(&event)) {
 switch (event.type) {
 case SDL_KEYDOWN:
 switch (event.key.keysym.sym) {
 case SDLK_ESCAPE:
 salir = true;
 break;
 }
 break;
 case SDL_QUIT:
 salir = true;
 break;
 }
 }
 cerr << "\rt. blit: " << t1-t0 << " ";
 SDL_Flip(screen);
 SDL_Delay(2);
 }
 cerr << endl;
 SDL_Quit();
 }
Las cruces que salen no son un bug, sirven para comprobar el efecto alfa. El código no es una versión definitiva, es más bien para juguetear un poco.
Saludos.





 .
 .