## Plasma Effect

Ophelius
Posts: 428
Joined: Feb 26, 2006 1:57

### Plasma Effect

Here's an attempt at some plasma. I just started learning about how to do this today, so it's unoriginal and unoptimized. You'll need the Allegro 4.0 dll if you haven't got it:
http://www.dlldll.com/downdll/7417.html

Code: Select all

`#include "Allegro.bi"DECLARE SUB Shift_Pal ()DIM SHARED AS INTEGER SCR_W = 500, SCR_H = 200DIM SHARED AS RGB Pal(0 to 255), Temp_ColDIM SHARED Buffer AS BITMAP PTRAllegro_Init ()Install_KeyboardIF SET_GFX_MODE(0, SCR_W, SCR_H, 0, 0) <> 0 then endBuffer = Create_Bitmap(SCR_W, SCR_H)dim as integer i, x, y, Style'Generate Palette'set entire pal to blackfor i = 0 to 255    Pal(i).R = 0    Pal(i).G = 0    Pal(i).B = 0next ifor i = 0 to 63    Pal(i).R = 0    Pal(i).G = i    Pal(i).B = inext ifor i = 0 to 63    Pal(64+i).R = 0    Pal(64+i).G = 63-i    Pal(64+i).B = 63-inext iSet_Palette @Pal(0)Style = 1do        Clear_Bitmap Buffer           for y = 0 to SCR_H - 1        for x = 0 to SCR_W - 1                        Select Case Style            Case 1                i = int( (32 + (32 * SIN( y / 16 ) ) ) +_                         (32 + (32 * SIN( x / 16 ) ) ) +_                         (32 + (32 * SIN( (SQR(x*x + y*y)) / 16 ) ) ) ) \ 3            Case 2                i = int( (32 + (32 * SIN( y * SQR(X)/ 128 ) ) ) +_                         (32 + (32 * SIN( x * SQR(Y)/ 128 ) ) ) +_                         (32 + (32 * SIN( (SQR(x*x + y*y)) /32 ) ) ) ) \ 3            END SELECT                        PutPixel Buffer, x, y, i                    next x    next y    Shift_Pal    Set_Palette @Pal(0)            Blit Buffer, Screen, 0, 0, 0, 0, Buffer->W, Buffer->H    loop until KEY(KEY_ESC)ENDSUB Shift_Pal ()        dim i as integer        Temp_Col.R = Pal(127).R    Temp_Col.G = Pal(127).G    Temp_Col.B = Pal(127).B    for i = 127 to 1 step -1        Pal(i).R = Pal(i-1).R        Pal(i).G = Pal(i-1).G        Pal(i).B = Pal(i-1).B    NEXT i    Pal(0).R = Temp_Col.R    Pal(0).G = Temp_Col.G    Pal(0).B = Temp_Col.B    END SUB`

If you have ideas how to make this look better, or more optimized, let me know. ;)

Ophelius
relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:
Palette switching is good. But the coolest looking plasmas are ones made in real-time.

http://qbcm.hybd.net/issues/4-1/#plasmas
Ophelius
Posts: 428
Joined: Feb 26, 2006 1:57
Thanks Rel, that helped a lot. I updated my code to use both palette shifting and plasma movement. The effect is really cool:

Code: Select all

`#include "Allegro.bi"DECLARE SUB Shift_Pal ()DIM SHARED AS INTEGER SCR_W = 500, SCR_H = 200DIM SHARED AS RGB Pal(0 to 255), Temp_ColDIM SHARED Buffer AS BITMAP PTRAllegro_Init ()Install_KeyboardIF SET_GFX_MODE(0, SCR_W, SCR_H, 0, 0) <> 0 then endBuffer = Create_Bitmap(SCR_W, SCR_H)dim as integer i, x, y, Style'Generate Palettefor i = 0 to 255    Pal(i).R = 0    Pal(i).G = 0    Pal(i).B = 0next ifor i = 0 to 63    Pal(i).R = 0    Pal(i).G = i    Pal(i).B = inext ifor i = 0 to 63    Pal(64+i).R = 0    Pal(64+i).G = 63-i    Pal(64+i).B = 63-inext iSet_Palette @Pal(0)dim c as integerdo        Clear_Bitmap Buffer           for y = 0 to SCR_H - 1        for x = 0 to SCR_W - 1                        i = ((32+(SIN((x)/32) * 32)) + (32+(COS((x+y+C)/16) * 32))+(32+(COS((SQR(y*y+x*x))/8) * 32))) / 3                        PutPixel Buffer, x, y, i                    next x    next y    C = (C+2) MOD 100    Shift_Pal    Set_Palette @Pal(0)    Blit Buffer, Screen, 0, 0, 0, 0, Buffer->W, Buffer->H    loop until KEY(KEY_ESC)ENDSUB Shift_Pal ()        dim i as integer        Temp_Col.R = Pal(127).R    Temp_Col.G = Pal(127).G    Temp_Col.B = Pal(127).B    for i = 127 to 1 step -1        Pal(i).R = Pal(i-1).R        Pal(i).G = Pal(i-1).G        Pal(i).B = Pal(i-1).B    NEXT i    Pal(0).R = Temp_Col.R    Pal(0).G = Temp_Col.G    Pal(0).B = Temp_Col.B    END SUB`

It's a lot of fun trying new equations to see what comes up. Has anyone ever written a manual explaining a lot of the popular graphic tricks, stuff you would find in demos?(roto-zooming, palette tricks, etc). I would like to know more about these techniques.
Merick
Posts: 1038
Joined: May 28, 2007 1:52
Take a look at DBF, it's a demoscene forum with a section dedicated to FB: http://www.dbfinteractive.com/
relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:
Ophelius wrote:Thanks Rel, that helped a lot. I updated my code to use both palette shifting and plasma movement. The effect is really cool:

It's a lot of fun trying new equations to see what comes up. Has anyone ever written a manual explaining a lot of the popular graphic tricks, stuff you would find in demos?(roto-zooming, palette tricks, etc). I would like to know more about these techniques.

Here:
http://rel.betterwebber.com/index.php?a ... =Tutorials

Try to read "How to make Blobs(metaballs)" and "lensflares".
Ophelius
Posts: 428
Joined: Feb 26, 2006 1:57
I've studied the metaballs code and it's easier than it looks. You had a more complicated Plasma+metaball example too. I was stunned by the plasma in the background. How do you go about finding good equations for a plasma. Yours looks really complex. Do you just stumble on one by trying different numbers/forms, or is it based on some Physics(it looks like fluid dynamics)? I still have so much to learn. :(
relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:
Ophelius wrote:I've studied the metaballs code and it's easier than it looks. You had a more complicated Plasma+metaball example too. I was stunned by the plasma in the background. How do you go about finding good equations for a plasma. Yours looks really complex. Do you just stumble on one by trying different numbers/forms, or is it based on some Physics(it looks like fluid dynamics)? I still have so much to learn. :(

I just try to change equations until it looks good while being sure that the offsets and params are not over the scale that I gave the sin luts. It's easy to visualize trig funks since they are periodic in nature.

Here's an example I made for my daughter's Nintendo DS yesterday. Sorry its C++ but I could make it in FB later if you want.

Code: Select all

`/*NDS Translucent PlasmaRelminatorhttp://rel.betterwebber.com*/#include <nds.h>#include <stdio.h>#include <math.h>// some sine LUTsu8 lsin1;u8 lsin2;u8 lsin3;// RGB paletteu16 pal;    int main(void){      // constant sine divisor   const u8 K1 = 32;    const u8 K2 = 12;    const u8 K3 = 28;      // maximum values our dynamic plasmas can move   u16 KSIN1 = u8(K1 *(360/57.3f));    u16 KSIN2 = u8(K2 *(360/57.3f));    u16 KSIN3 = u8(K3 *(360/57.3f));                   // precalculate our luts   for (int i = 0; i< ((2048) - 1); i++)   {        lsin1[i] = sin(i/(float)K1) * 32+32;        lsin2[i] = sin(i/(float)K2) * 16+16;        lsin3[i] = sin(i/(float)K3) * 20+20;    }       // generate our 256 color palette   for (int i=0; i<256; i++)   {       u8 r = (u8)(abs(int(16 - 15 * sin(i * M_PI / 16.0f))));      u8 g = (u8)(abs(int(16 - 15 * sin(i * M_PI / 12.0f))));      u8 b = (u8)(abs(int(16 - 15 * sin(i * M_PI / 18.0f))));      pal[i] = RGB15(r,g,b);   }   irqInit();   irqEnable(IRQ_VBLANK);         //initialize the DS Dos-like functionality   consoleDemoInit();      iprintf("\x1b[1;1HTranslucent Plasma!");   iprintf("\x1b[2;1HFramebuffer madness!");   iprintf("\x1b[3;1HRelsoft");   iprintf("\x1b[4;1Hhttp://rel.betterwebber.com");   iprintf("\x1b[6;1HAnya Therese B. Lope");    //set frame buffer mode 0   videoSetMode(MODE_FB0);    //enable VRAM A for writting by the cpu and use    //as a framebuffer by video hardware   vramSetBankA(VRAM_A_LCD);    u8 rot;                  // translucent factor   u16 counter =0;            // frame counter   u16 a = 0, b = 0, ct = 0;   // movement deltas   u16 c;                  // palette color index      while(1)   {      // dynamically move our plasmas       a= (a + 1) % (KSIN1 + 1);      b = (b + 1) % (KSIN2 + 1);      ct = (ct + 1) % (KSIN3 + 1);            // offset 2nd plasma by a factor of 64 * 2 or (-64 to 64)      rot = 64 * (((counter & 1) == 1) | 1);            // inc frame      counter++;             //write to vram directly      short unsigned int *vram_offset = VRAM_A;            for (int ya = 0; ya<SCREEN_HEIGHT; ya++)      {         for (int xa = 0; xa <SCREEN_WIDTH-1; xa++)         {            rot = -rot;      // draw plasmas every other pixel            // calculate colors            c = (lsin1[xa + a + rot] + lsin2[ya + b + rot] +lsin3[1024+xa + ya - ct]);            c = (lsin1[xa + a + rot+c] + lsin2[ya + b + rot+c] +lsin3[1024+xa + ya - ct+c]);            // write to vram            *vram_offset++ = pal[c];         }         vram_offset++;      // magic      }            swiWaitForVBlank();   }    return 0;} `
Ophelius
Posts: 428
Joined: Feb 26, 2006 1:57
Thanks for that. I converted it to FB for you. Looks real cool. Though I don't know the DS's screen res and what the U8 and U16 meant, I had to improvise, so I think there might be issues with that. The palette was pretty dark, so you'll notice I multiplied it by 8 to get it brighter. I'm sure it's just some mistake in my conversion and wasn't your intention.

I was surprised I got it to work right away because I don't code in C, but it's very similar. I just guessed that % meant Mod and | meant Or, etc:

Code: Select all

`DIM AS INTEGER SCR_W = 320, SCR_H=200DIM LSIN1(2048) AS DOUBLEDIM LSIN2(2048) AS DOUBLEDIM LSIN3(2048) AS DOUBLE'constant sine divisorConst K1 = 32Const K2 = 12Const K3 = 28const PI = 3.141593        'maximum values our dynamic plasmas can moveDIM AS INTEGER KSIN1 = K1 *(360/57.3)DIM AS INTEGER KSIN2 = K2 *(360/57.3)DIM AS INTEGER KSIN3 = K3 *(360/57.3)                    'precalculate our lutsdim as integer iFor i = 0 to 2047    lsin1(i) = Sin(i/K1) * 32 + 32    lsin2(i) = Sin(i/K2) * 16 + 16    lsin3(i) = Sin(i/K3) * 20 + 20    next iSCREENRES SCR_W, SCR_H, 8 'generate our 256 Color PaletteDIM AS INTEGER r,g,bFor i = 0 to 255    r = 8*(Abs(Int(16 - 15 * Sin(i * PI / 16.0))))    g = 8*(Abs(Int(16 - 15 * Sin(i * PI / 12.0))))    b = 8*(Abs(Int(16 - 15 * Sin(i * PI / 18.0))))        palette i, r, g, b    Next iDIM AS INTEGER rot                              ' translucent factorDIM AS INTEGER counter =0                       ' frame counterDIM AS INTEGER d_a = 0, d_b = 0, d_ct = 0       ' movement deltasDIM AS INTEGER c                                ' Palette Color indexDIM AS INTEGER xa, yaWhile INKEY = ""        'dynamically move our plasmas         d_a= (d_a + 1) MOD (KSIN1 + 1)        d_b = (d_b + 1) MOD (KSIN2 + 1)        d_ct = (d_ct + 1) MOD (KSIN3 + 1)                'offset 2nd plasma by a factor of 64 * 2 Or (-64 To 64)        rot = 64 * (((counter AND 1) = 1) OR 1)                        For ya = 0 TO SCR_H - 1                        For xa = 0 to SCR_W-1                                        rot = -rot        'Draw plasmas every other pixel                                                'calculate colors                        c = (lsin1(xa + d_a + rot) + lsin2(ya + d_b + rot) + lsin3(1024+xa + ya - d_ct))                        c = (lsin1(xa + d_a + rot+c) + lsin2(ya + d_b + rot+c) + lsin3(1024+xa + ya - d_ct+c))                                                'SCREENLOCK  'don't know if this is necessary                        PSET (xa, ya), c                        'SCREENUNLOCK 'this either                Next xa                        Next ya                'inc frame        Counter+=1        WEND`
relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:
Nice!! I forgot to tell you that the DS has 16 bit of colors and its RGB15 ranges of only 0-31 per channel as opposed to FB's 32 bit mode where channels range from 0-255.

Anyways, here's a 32 bit version I coded last night.

Code: Select all

`''Plazma!!!''relminator''http://rel.betterwebber.comconst as integer SCR_WID = 256const as integer SCR_HEI = 192const as integer BPP = 32const as single PI = atn(1) * 4const as integer K1 = 22const as integer K2 = 32const as integer K3 = 58dim shared as integer ksin1,ksin2,ksin3    dim shared as uinteger ptr lsin1 dim shared as uinteger ptr lsin2dim shared as uinteger ptr lsin3lsin1 = new uintegerlsin2 = new uintegerlsin3 = new uinteger        for i as integer = 0 to 2048 - 1    lsin1[i] = sin((i-1024)/K1) * 120+120     lsin2[i] = sin((i-1024)/K2) * 64+64    lsin3[i] = sin((i-1024)/K3) * 164+164next i KSIN1 = int(K1 *(360/57.3))KSIN2 = int(K2 *(360/57.3))KSIN3 = int(K3 *(360/57.3))dim as uinteger ptr pal = new uintegerfor i as integer = 0 to 255    dim as ubyte r = cbyte(abs(INT(128 - 127 * SIN(i * PI / 32))))    dim as ubyte g = cbyte(abs(INT(128 - 127 * SIN(i * PI / 64))))    dim as ubyte b = cbyte(abs(INT(128 - 127 * SIN(i * PI / 128))))    pal[i]=rgb(r,g,b)next idim as integer a = 0, b = 0, ct = 0    dim as integer rot, counter =0screenres SCR_WID,SCR_HEI,BPP,2screenset 1, 0do    a = (a + 1) mod (KSIN1 + 1)    b = (b + 1) mod (KSIN2 + 1)    ct = (ct + 1) mod (KSIN3 + 1)        rot = 64 * (((counter AND 1) = 1) OR 1)   counter += 1       screenlock    Line (0, 0)-(SCR_WID, SCR_HEI), 0, BF        for y as integer = 0 to 191       for x as integer = 0 to 254                           rot = -rot                      dim as integer c = Lsin1[x+a] + Lsin2[y+b] + Lsin3[x+y-ct+1024]             c = Lsin1[x+a+rot+c] + Lsin2[y+b+rot+c] + Lsin3[x+y-ct+1024]                   c = c and 255          pset (x,y), pal[c]       next x    next y    screenunlock    sleep 1,1        ScreenCopyLoop While Inkey = ""delete[] lsin1delete[] lsin2delete[] lsin3delete[] palend`
joseywales72
Posts: 206
Joined: Aug 27, 2005 2:02
Location: Istanbul, Turkey
Hi,
Great effects... There is something strange though. Ophelius' translation compiles and works fine on my Linux (Arch 32, 2.6.33, Xorg 1.7.5) but Relsofts last one does not compile and gives this error.

Code: Select all

`/usr/lib/libsupc++.a(eh_personality.o): In function `__gxx_personality_v0':(.text.__gxx_personality_v0+0xba): undefined reference to `_Unwind_GetIPInfo'`

Any ideas?
Thanks.
Anil
Ophelius
Posts: 428
Joined: Feb 26, 2006 1:57
Could be because he's allocating memory for his Luts and Palette with the NEW function. I don't understand why he did that when a simple DIM would work fine. Is it speed increase Rel? So maybe that doesn't work in Linux.
relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:
Ophelius wrote:Could be because he's allocating memory for his Luts and Palette with the NEW function. I don't understand why he did that when a simple DIM would work fine. Is it speed increase Rel? So maybe that doesn't work in Linux.

As for the Linux bug, I have no idea. It's been 5 years since I last touched a Linux Distro.

Yeah, I usually use new and delete for speed. Dynamic Arrays in FB or anywhere has a few overheads on access.

BTW, to make it faster, ditch the pset and write directly to the buffer using screenptr+offset.
anonymous1337
Posts: 5494
Joined: Sep 12, 2005 20:06
Location: California
@joseywales: You need GCC to compile FB programs with certain features from now on.