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
#include "Allegro.bi"
DECLARE SUB Shift_Pal ()
DIM SHARED AS INTEGER SCR_W = 500, SCR_H = 200
DIM SHARED AS RGB Pal(0 to 255), Temp_Col
DIM SHARED Buffer AS BITMAP PTR
Allegro_Init ()
Install_Keyboard
IF SET_GFX_MODE(0, SCR_W, SCR_H, 0, 0) <> 0 then end
Buffer = Create_Bitmap(SCR_W, SCR_H)
dim as integer i, x, y, Style
'Generate Palette
'set entire pal to black
for i = 0 to 255
Pal(i).R = 0
Pal(i).G = 0
Pal(i).B = 0
next i
for i = 0 to 63
Pal(i).R = 0
Pal(i).G = i
Pal(i).B = i
next i
for i = 0 to 63
Pal(64+i).R = 0
Pal(64+i).G = 63-i
Pal(64+i).B = 63-i
next i
Set_Palette @Pal(0)
Style = 1
do
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)
END
SUB 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. ;)
#include "Allegro.bi"
DECLARE SUB Shift_Pal ()
DIM SHARED AS INTEGER SCR_W = 500, SCR_H = 200
DIM SHARED AS RGB Pal(0 to 255), Temp_Col
DIM SHARED Buffer AS BITMAP PTR
Allegro_Init ()
Install_Keyboard
IF SET_GFX_MODE(0, SCR_W, SCR_H, 0, 0) <> 0 then end
Buffer = Create_Bitmap(SCR_W, SCR_H)
dim as integer i, x, y, Style
'Generate Palette
for i = 0 to 255
Pal(i).R = 0
Pal(i).G = 0
Pal(i).B = 0
next i
for i = 0 to 63
Pal(i).R = 0
Pal(i).G = i
Pal(i).B = i
next i
for i = 0 to 63
Pal(64+i).R = 0
Pal(64+i).G = 63-i
Pal(64+i).B = 63-i
next i
Set_Palette @Pal(0)
dim c as integer
do
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)
END
SUB 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.
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.
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. :(
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.
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:
DIM AS INTEGER SCR_W = 320, SCR_H=200
DIM LSIN1(2048) AS DOUBLE
DIM LSIN2(2048) AS DOUBLE
DIM LSIN3(2048) AS DOUBLE
'constant sine divisor
Const K1 = 32
Const K2 = 12
Const K3 = 28
const PI = 3.141593
'maximum values our dynamic plasmas can move
DIM 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 luts
dim as integer i
For 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 i
SCREENRES SCR_W, SCR_H, 8
'generate our 256 Color Palette
DIM AS INTEGER r,g,b
For 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 i
DIM AS INTEGER rot ' translucent factor
DIM AS INTEGER counter =0 ' frame counter
DIM AS INTEGER d_a = 0, d_b = 0, d_ct = 0 ' movement deltas
DIM AS INTEGER c ' Palette Color index
DIM AS INTEGER xa, ya
While 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
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.
''Plazma!!!
''relminator
''http://rel.betterwebber.com
const as integer SCR_WID = 256
const as integer SCR_HEI = 192
const as integer BPP = 32
const as single PI = atn(1) * 4
const as integer K1 = 22
const as integer K2 = 32
const as integer K3 = 58
dim shared as integer ksin1,ksin2,ksin3
dim shared as uinteger ptr lsin1
dim shared as uinteger ptr lsin2
dim shared as uinteger ptr lsin3
lsin1 = new uinteger[2048]
lsin2 = new uinteger[2048]
lsin3 = new uinteger[2048]
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+164
next 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 uinteger[256]
for 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 i
dim as integer a = 0, b = 0, ct = 0
dim as integer rot, counter =0
screenres SCR_WID,SCR_HEI,BPP,2
screenset 1, 0
do
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
ScreenCopy
Loop While Inkey = ""
delete[] lsin1
delete[] lsin2
delete[] lsin3
delete[] pal
end
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.
/usr/lib/libsupc++.a(eh_personality.o): In function `__gxx_personality_v0':
(.text.__gxx_personality_v0+0xba): undefined reference to `_Unwind_GetIPInfo'
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.
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.