static gboolean process (GeglOperation *operation, GeglBuffer *output, const GeglRectangle *result, gint level) { PlasmaContext *context; gint depth; gint x, y; context = g_new (PlasmaContext, 1); context->o = GEGL_CHANT_PROPERTIES (operation); context->output = output; context->buffer = g_malloc (TILE_SIZE * TILE_SIZE * 3 * sizeof (gfloat)); context->using_buffer = FALSE; /* * The first time only puts seed pixels (corners, center of edges, * center of image) */ x = result->x + result->width; y = result->y + result->height; context->gr = g_rand_new_with_seed (context->o->seed); do_plasma (context, result->x, result->y, x-1, y-1, -1, 0); /* * Now we recurse through the images, going deeper each time */ depth = 1; while (!do_plasma (context, result->x, result->y, x-1, y-1, depth, 0)) depth++; gegl_buffer_sample_cleanup (context->output); g_rand_free (context->gr); g_free (context->buffer); g_free (context); return TRUE; }
void Plasma::operator ()(SDL_Surface * s) { m_pSurface = s; int x1 = 0; int y1 = 0; int x2 = s->w -1; int y2 = s->h -1; SDL_LockSurface( s ); if( x1 != x2 && y1 != y2 ) { do_plasma( x1, y1, x2, y2, -1, 0 ); int depth = 1; int scale_depth = 1; while( do_plasma( x1, y1, x2, y2, depth, scale_depth ) == false ) { depth++; } } SDL_UnlockSurface( s ); }
static gboolean do_plasma (PlasmaContext *context, gint x1, gint y1, gint x2, gint y2, gint plasma_depth, gint recursion_depth) { gfloat tl[3], ml[3], bl[3], mt[3], mm[3], mb[3], tr[3], mr[3], br[3]; gfloat tmp[3]; gint xm, ym; gfloat ran; if (G_UNLIKELY ((!context->using_buffer) && ((x2 - x1 + 1) <= TILE_SIZE) && ((y2 - y1 + 1) <= TILE_SIZE))) { gboolean ret; GeglRectangle rect; rect.x = x1; rect.y = y1; rect.width = x2 - x1 + 1; rect.height = y2 - y1 + 1; gegl_buffer_get (context->output, &rect, 1.0, babl_format ("R'G'B' float"), context->buffer, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); context->using_buffer = TRUE; context->buffer_x = x1; context->buffer_y = y1; context->buffer_width = x2 - x1 + 1; ret = do_plasma (context, x1, y1, x2, y2, plasma_depth, recursion_depth); context->using_buffer = FALSE; gegl_buffer_set (context->output, &rect, 0, babl_format ("R'G'B' float"), context->buffer, GEGL_AUTO_ROWSTRIDE); return ret; } xm = (x1 + x2) / 2; ym = (y1 + y2) / 2; if (plasma_depth == -1) { random_rgba (context->gr, tl); put_pixel (context, tl, x1, y1); random_rgba (context->gr, tr); put_pixel (context, tr, x2, y1); random_rgba (context->gr, bl); put_pixel (context, bl, x1, y2); random_rgba (context->gr, br); put_pixel (context, br, x2, y2); random_rgba (context->gr, mm); put_pixel (context, mm, xm, ym); random_rgba (context->gr, ml); put_pixel (context, ml, x1, ym); random_rgba (context->gr, mr); put_pixel (context, mr, x2, ym); random_rgba (context->gr, mt); put_pixel (context, mt, xm, y1); random_rgba (context->gr, mb); put_pixel (context, mb, xm, y2); return FALSE; } if (!plasma_depth) { if (x1 == x2 && y1 == y2) return FALSE; gegl_buffer_sample (context->output, x1, y1, NULL, tl, babl_format ("R'G'B' float"), GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE); gegl_buffer_sample (context->output, x1, y2, NULL, bl, babl_format ("R'G'B' float"), GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE); gegl_buffer_sample (context->output, x2, y1, NULL, tr, babl_format ("R'G'B' float"), GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE); gegl_buffer_sample (context->output, x2, y2, NULL, br, babl_format ("R'G'B' float"), GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE); ran = context->o->turbulence / (2.0 * recursion_depth); if (xm != x1 || xm != x2) { /* Left. */ average_pixel (ml, tl, bl); add_random (context->gr, ml, ran); put_pixel (context, ml, x1, ym); /* Right. */ if (x1 != x2) { average_pixel (mr, tr, br); add_random (context->gr, mr, ran); put_pixel (context, mr, x2, ym); } } if (ym != y1 || ym != x2) { /* Bottom. */ if (x1 != xm || ym != y2) { average_pixel (mb, bl, br); add_random (context->gr, mb, ran); put_pixel (context, mb, xm, y2); } if (y1 != y2) { /* Top. */ average_pixel (mt, tl, tr); add_random (context->gr, mt, ran); put_pixel (context, mt, xm, y1); } } if (y1 != y2 || x1 != x2) { /* Middle pixel. */ average_pixel (mm, tl, br); average_pixel (tmp, bl, tr); average_pixel (mm, mm, tmp); add_random (context->gr, mm, ran); put_pixel (context, mm, xm, ym); } return x2 - x1 < 3 && y2 - y1 < 3; } if (x1 < x2 || y1 < y2) { /* Top left. */ do_plasma (context, x1, y1, xm, ym, plasma_depth - 1, recursion_depth + 1); /* Bottom left. */ do_plasma (context, x1, ym, xm, y2, plasma_depth - 1, recursion_depth + 1); /* Top right. */ do_plasma (context, xm, y1, x2, ym, plasma_depth - 1, recursion_depth + 1); /* Bottom right. */ return do_plasma (context, xm, ym, x2, y2, plasma_depth - 1, recursion_depth + 1); } return TRUE; }
void plasma(enum action action, caca_canvas_t *cv) { static caca_dither_t *dither; static uint8_t *screen; static uint32_t red[256], green[256], blue[256], alpha[256]; static double r[3], R[6]; int i, x, y; switch(action) { case PREPARE: /* Fill various tables */ for(i = 0 ; i < 256; i++) red[i] = green[i] = blue[i] = alpha[i] = 0; for(i = 0; i < 3; i++) r[i] = (double)(caca_rand(1, 1000)) / 60000 * M_PI; for(i = 0; i < 6; i++) R[i] = (double)(caca_rand(1, 1000)) / 10000; for(y = 0 ; y < TABLEY ; y++) for(x = 0 ; x < TABLEX ; x++) { double tmp = (((double)((x - (TABLEX / 2)) * (x - (TABLEX / 2)) + (y - (TABLEX / 2)) * (y - (TABLEX / 2)))) * (M_PI / (TABLEX * TABLEX + TABLEY * TABLEY))); table[x + y * TABLEX] = (1.0 + sin(12.0 * sqrt(tmp))) * 256 / 6; } break; case INIT: screen = malloc(XSIZ * YSIZ * sizeof(uint8_t)); dither = caca_create_dither(8, XSIZ, YSIZ, XSIZ, 0, 0, 0, 0); break; case UPDATE: for(i = 0 ; i < 256; i++) { double z = ((double)i) / 256 * 6 * M_PI; red[i] = (1.0 + sin(z + r[1] * frame)) / 2 * 0xfff; blue[i] = (1.0 + cos(z + r[0] * (frame + 100))) / 2 * 0xfff; green[i] = (1.0 + cos(z + r[2] * (frame + 200))) / 2 * 0xfff; } /* Set the palette */ caca_set_dither_palette(dither, red, green, blue, alpha); do_plasma(screen, (1.0 + sin(((double)frame) * R[0])) / 2, (1.0 + sin(((double)frame) * R[1])) / 2, (1.0 + sin(((double)frame) * R[2])) / 2, (1.0 + sin(((double)frame) * R[3])) / 2, (1.0 + sin(((double)frame) * R[4])) / 2, (1.0 + sin(((double)frame) * R[5])) / 2); break; case RENDER: caca_dither_bitmap(cv, 0, 0, caca_get_canvas_width(cv), caca_get_canvas_height(cv), dither, screen); break; case FREE: free(screen); caca_free_dither(dither); break; } }
bool Plasma::do_plasma(int x1, int y1, int x2, int y2, int depth, int scale_depth) { Color tl, ml, bl, tm, mm, bm, tr, mr, br; int xm = ( x1 + x2 )/ 2; int ym = ( y1 + y2 )/ 2; if(depth == -1) { random_rbg(tl); random_rbg(ml); random_rbg(bl); random_rbg(tm); random_rbg(mm); random_rbg(bm); random_rbg(tr); random_rbg(mr); random_rbg(br); set_pixel(m_pSurface, x1, y1, tl); set_pixel(m_pSurface, x1, ym, ml); set_pixel(m_pSurface, x1, y2, bl); set_pixel(m_pSurface, xm, y1, tm); set_pixel(m_pSurface, xm, ym, mm); set_pixel(m_pSurface, xm, y2, bm); set_pixel(m_pSurface, x2, y1, tr); set_pixel(m_pSurface, x2, ym, mr); set_pixel(m_pSurface, x2, y2, br); return false; } if(depth == 0) { if(x1 == x2 && y1 == y2) return false; get_pixel(m_pSurface, x1, y1, tl); get_pixel(m_pSurface, x1, y2, bl); get_pixel(m_pSurface, x2, y1, tr); get_pixel(m_pSurface, x2, y2, br); int ran = (int)((256.0 / (2 * scale_depth)) * m_fTurbulance); if (xm != x1 || xm != x2) { // Left ml = average_color(tl, bl); add_random(ml, ran); set_pixel(m_pSurface, x1, ym, ml); if (x1 != x2) { // Right mr = average_color(tr, br); add_random(mr, ran); set_pixel(m_pSurface, x2, ym, mr); } } if (ym != y1 || ym != y2) { if (x1 != xm || ym != y2) { // Bottom Color mb = average_color(bl, br); add_random(mb, ran); set_pixel(m_pSurface, xm, y2, mb); } if (y1 != y2) { // Top Color mt = average_color(tl, tr); add_random(mt, ran); set_pixel(m_pSurface, xm, y1, mt); } } if (y1 != y2 || x1 != x2) { // Middle pixel Color tmp; mm = average_color(tl, br); tmp = average_color(bl, tr); mm = average_color(mm, tmp); add_random(mm, ran); set_pixel(m_pSurface, xm, ym, mm); } return x2 - x1 < 3 && y2 - y1 < 3; } //depth == 0 if (x1 < x2 || y1 < y2) { // Top left. do_plasma (x1, y1, xm, ym, depth - 1, scale_depth + 1); /* Bottom left. */ do_plasma (x1, ym, xm, y2, depth - 1, scale_depth + 1); /* Top right. */ do_plasma (xm, y1, x2, ym, depth - 1, scale_depth + 1); /* Bottom right. */ return do_plasma (xm, ym, x2, y2, depth - 1, scale_depth + 1); } return true; }
main (int argc, char **argv) { Uint32 video_flags; double r[3]; double R[6]; SDL_Surface *screen; SDL_Color colors[TONES*2]; unsigned char *t; time_t starttime; int i, state=0; /* Inizialize the SDL library */ if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); return 1; } /* randomized stuff */ srand(time(NULL)); { int c; for (c=0; c<3; c++) r[c]=((double)(rand()%1000+1))/300000; for (c=0; c<6; c++) R[c]=((double)(rand()%1000+1))/5000; } printf("Precalculating table...\n"); t = (unsigned char *)malloc(TABLEY*TABLEX); if ( t == NULL ) { fprintf(stderr, "Out of memory\n"); exit(1); } { int y; for (y=0 ; y<TABLEY ; y++) { int x; for (x=0 ; x<TABLEX ; x++) { double tmp=(((double)((x-(TABLEX/2))*(x-(TABLEX/2))+(y-(TABLEX/2))*(y-(TABLEX/2)))) *(PI/(TABLEX*TABLEX+TABLEY*TABLEY))); t[y*TABLEX+x]=(sin(sqrt(tmp)*12)+1)*TONES/6; } } } /* fire and forget... */ //atexit(SDL_Quit); video_flags = (SDL_SWSURFACE|SDL_HWPALETTE); screen=SDL_SetVideoMode(VIDEOX, VIDEOY, 8, video_flags); if ( screen == NULL ) { fprintf(stderr, "Couldn't initialize video mode: %s\n", SDL_GetError()); return 1; } SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE); SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); starttime=time(NULL); /* Main loop */ while (SDL_PollEvent(NULL)==0) { state++; { int c; for (c=0 ; c<TONES; c++) { colors[c].r=(sin(((double)c)/TONES*6*PI+r[0]*PI*state*PI)+1)*127; colors[c].g=(sin(((double)c)/TONES*6*PI+r[1]*state*PI)+1)*127; colors[c].b=(sin(((double)c)/TONES*6*PI+r[2]*state*PI)+1)*127; } SDL_SetColors(screen, colors, 0, TONES); } if (SDL_LockSurface(screen) <0 ) { continue; } do_plasma(screen, (sin(((double)state)*R[0])+1)/2, (sin(((double)state)*R[1])+1)/2, (sin(((double)state)*R[2])+1)/2, (sin(((double)state)*R[3])+1)/2, (sin(((double)state)*R[4])+1)/2, (sin(((double)state)*R[5])+1)/2, t); SDL_UnlockSurface(screen); SDL_Flip(screen); } printf("Frame rate: %g frames/sec\n",((double)state)/difftime(time(NULL),starttime)); return 0; }