2D Plasma type thingi
BlitzPlus Forums/BlitzPlus Programming/2D Plasma type thingi
| ||
LOL its me again. Im having one of those "hay how do they do that" type of few days. This time its one of those cool looking plasma things Iv done a little research on the net about it but cant really seem to nail anything down, so I thought stuff it ill just have a go. ; Plasma Test ; ; Yavin ; ; Teamrebellion.co.uk ; Graphics 200,200,16,2 SetBuffer BackBuffer() Cls Global temp_image temp_image=CreateImage(100,100) Global counter% counter=1 Dim lCos(360) For looper=1 To 360 lcos(looper)=Cos(looper) Next While Not KeyHit(1) Cls draw_plasma() DrawImage temp_image,0,0 Color 0,0,0 Text 1,1,"C"+counter Flip False Wend Function draw_plasma() ;LockBuffer For looper=1 To 200 For inner=1 To 200 Local r%,g%,a,b,c a=-Cos(looper)*looper b=Cos(looper)*looper c=-Cos(looper)*looper a=a-Sin(inner)*inner b=b+Sin(inner)*inner c=c-Sin(inner)*inner a=a+counter b=b+counter c=c+counter Color a,b,c Plot looper,inner Next Next ;UnlockBuffer ;SaveBuffer (BackBuffer(),"test.bmp") counter=counter+2:If counter=>1000 Then counter=0 End Function |
| ||
Oh yeah you will note some of that aint actually used. like the sin table. im still working away on it. If you run it you will see it looks ok, but its not as smoth as others I have seem and some times you see a hard edge.. so any help would be cool thanks. |
| ||
Very very cool indeed! I love these demo effects!! :) And welldone for it! Lets see some people help with this! :) |
| ||
Pretty cool :) a bit faster (but also slightly wrong). ; Plasma Test ; ; Yavin ; ; Teamrebellion.co.uk ; Graphics 200,200,16,2 SetBuffer BackBuffer() Cls Global temp_image temp_image=CreateImage(100,100) Global counter% counter=1 Dim lCos(360) For looper=1 To 360 lcos(looper)=Cos(looper) Next While Not KeyHit(1) Cls draw_plasma() DrawImage temp_image,0,0 Color 0,0,0 Text 1,1,"C"+counter Flip False Wend Function draw_plasma() ;LOCAL VARS Local argb Local NewBuffer = ImageBuffer(temp_image) LockBuffer NewBuffer For looper=1 To 200 For inner=1 To 200 Local r%,g%,a,b,c a=-Cos(looper)*looper b=Cos(looper)*looper c=-Cos(looper)*looper a=a-Sin(inner)*inner b=b+Sin(inner)*inner c=c-Sin(inner)*inner a=a+counter b=b+counter c=c+counter ;Color a,b,c ;Plot looper,inner argb=(c Or (b Shl 8) Or (a Shl 16) Or ($ff000000)) WritePixelFast looper,inner, argb, NewBuffer Next Next UnlockBuffer NewBuffer ;SaveBuffer (BackBuffer(),"test.bmp") counter=counter+2:If counter=>1000 Then counter=0 End Function |
| ||
*EDIT* figured it out, you're looping 200 times when the image is only 100 wide ; Plasma Test ; ; Yavin ; ; Teamrebellion.co.uk ; Graphics 200,200,16,2 SetBuffer BackBuffer() Cls Global temp_image temp_image=CreateImage(100,100) Global counter% counter=1 Dim lCos(360) For looper=1 To 360 lcos(looper)=Cos(looper) Next While Not KeyHit(1) Cls draw_plasma() DrawImage temp_image,0,0 Color 0,0,0 Text 1,1,"C"+counter Flip False Wend Function draw_plasma() ;LOCAL VARS Local argb Local NewBuffer = ImageBuffer(temp_image) LockBuffer NewBuffer For looper=1 To 100 For inner=1 To 100 Local r%,g%,a,b,c a=-Cos(looper)*looper b=Cos(looper)*looper c=-Cos(looper)*looper a=a-Sin(inner)*inner b=b+Sin(inner)*inner c=c-Sin(inner)*inner a=a+counter b=b+counter c=c+counter ;Color a,b,c ;Plot looper,inner argb=(c Or (b Shl 8) Or (a Shl 16) Or ($ff000000)) WritePixelFast looper,inner, argb, NewBuffer Next Next UnlockBuffer NewBuffer ;SaveBuffer (BackBuffer(),"test.bmp") counter=counter+2:If counter=>1000 Then counter=0 End Function |
| ||
my 2 eurocents: (b+);------------------------- ; hacky wacko plasma ; ; by CS^TBL ;------------------------- Global sw=ClientWidth(Desktop()) Global sh=ClientHeight(Desktop()) app=CreateWindow("",0,0,sw,sh,0,0) panel=CreatePanel(0,0,sw,sh,app) SetPanelColor panel,0,0,0 Global c=CreateCanvas(0,0,128,64,panel) SetGadgetLayout c,1,0,1,0 SetGadgetShape c,0,192*5/8,sw,sh*5/8 Global f,f2 SetBuffer CanvasBuffer(c) timer=CreateTimer(30) Repeat WaitEvent() If EventID()=$4001 plazma() FlipCanvas c EndIf If EventID()=$803 quit=True EndIf Until quit FreeTimer timer FreeGadget c End Function plazma() f=f+2 f2=f2-6 For x=-64 To 64 For y=0 To 64 px=Sin((f2+x*-5)+(f+y*5))*Sin((f2+x*-4)+(f+y*3))*16 py=Cos((f2+x*-8)+(f+y*-4))*Cos((x*5)+(f2+y*-2))*17 dx=x+px dy=y+py dx=dx dy=dy-32 d#=Sqr((dx*dx)+(dy*dy)) d#=d#*3 d#=255-d# If d#>255 Then d#=255 If d#<0 Then d#=0 ;d#=128+Sin(d#*3)*111 ; sinecolor b=(d#+px+(x*13))*.25 g=(d#-px+py+(y*6))*.5 r=(d#+py+(y*x/10))*1 If r<0 Then r=0 If g<0 Then g=0 If b<0 Then b=0 If r>255 Then r=255 If g>255 Then g=255 If b>255 Then b=255 Color r,g,b Rect (64+x)*1,y*1,1,1 Next Next End Function |
| ||
Now if only it could be made tileable...; Plasma Test ; ; Yavin ; ; Teamrebellion.co.uk ; Graphics 400,400,16,2 SetBuffer BackBuffer() Cls Global temp_image temp_image=CreateImage(200,200) Global counter% counter=1 Dim lCos(360) For looper=1 To 360 lcos(looper)=Cos(looper) Next While Not KeyHit(1) Cls draw_plasma() DrawImage temp_image,0,0 DrawImage temp_image,199,0 DrawImage temp_image,0,199 DrawImage temp_image,199,199 Color 0,0,0 Text 1,1,"C"+counter Flip False Wend Function draw_plasma() ;LOCAL VARS Local argb Local NewBuffer = ImageBuffer(temp_image) LockBuffer NewBuffer For looper=1 To 200 For inner=1 To 200 Local r%,g%,a,b,c a= -Cos(looper) * looper b= Cos(looper) * looper c= -Cos(looper) * looper a= a - Sin(inner) * inner b= b + Sin(inner) * inner c= c - Sin(inner) * inner a=a+counter b=b+counter c=c+counter Color a,b,c ;Plot looper,inner argb=(c Or (b Shl 8) Or (a Shl 16) Or ($ff000000)) ;Rect looper,inner,1,1,1 WritePixelFast looper,inner, argb, NewBuffer Next Next UnlockBuffer NewBuffer ;SaveBuffer (BackBuffer(),"test.bmp") counter=counter+2:If counter=>1000 Then counter=0 End Function |
| ||
Tile is easy.; Plasma Test ; ; Yavin ; ; Teamrebellion.co.uk ; Const gfx_width=640 Const gfx_height=480 Graphics 640,480,16,0 SetBuffer BackBuffer() Cls Const size=100 Global temp_image temp_image=CreateImage(size,size) Global display_image display_image=CreateImage(gfx_width,gfx_height) Global counter% counter=1 Dim pos(size,size) Dim lCos(360) For looper=1 To 360 lcos(looper)=Cos(looper) Next While Not KeyHit(1) Cls draw_plasma() render_screen() For x=0 To gfx_width Step 198 For y=0 To gfx_height Step 198 DrawImage display_image,x,y Next Next Flip Wend Function render_screen() DrawImage temp_image,0,0 flip_vert() DrawImage temp_image,99,0 flip_vert() flip_hor() DrawImage temp_image,0,99 flip_vert() DrawImage temp_image,99,99 CopyRect 0,0,200,200,0,0,BackBuffer(),ImageBuffer(display_image) End Function Function flip_vert() SetBuffer ImageBuffer(temp_image) LockBuffer For x=1 To ImageWidth(temp_image) For y=1 To ImageHeight(temp_image) pos(x,y)=ReadPixelFast(x,y,ImageBuffer(temp_image)) Next Next For x=ImageWidth(temp_image) To 1 Step -1 For y=ImageHeight(temp_image) To 1 Step -1 WritePixelFast(x,y,pos(ImageWidth(temp_image)-x,y),ImageBuffer(temp_image)) Next Next UnlockBuffer SetBuffer BackBuffer() End Function Function flip_hor() SetBuffer ImageBuffer(temp_image) LockBuffer For x=1 To ImageWidth(temp_image) For y=1 To ImageHeight(temp_image) pos(x,y)=ReadPixelFast(x,y,ImageBuffer(temp_image)) Next Next For x=ImageWidth(temp_image) To 1 Step -1 For y=ImageHeight(temp_image) To 1 Step -1 WritePixelFast(x,y,pos(x,ImageHeight(temp_image)-y),ImageBuffer(temp_image)) Next Next UnlockBuffer SetBuffer BackBuffer() End Function Function draw_plasma() ;LOCAL VARS Local argb Local NewBuffer = ImageBuffer(temp_image) LockBuffer NewBuffer For looper=1 To size For inner=1 To size Local r%,g%,a,b,c a= -Cos(looper) * inner b= Cos(looper) * inner c= -Cos(looper) * inner a= a + Sin(inner) * looper b= b - Sin(inner) * looper c= c + Sin(inner) * looper a=a+counter b=b+counter c=c+counter Color a,b,c ;Plot looper,inner argb=(c Or (b Shl 8) Or (a Shl 16) Or ($ff000000)) ;Rect looper,inner,1,1,1 WritePixelFast looper,inner, argb, NewBuffer Next Next UnlockBuffer NewBuffer ;SaveBuffer (BackBuffer(),"test.bmp") counter=counter+2:If counter=>1000 Then counter=0 End Function I still cant seem to get it looking right though, which has to be something to do with my sin cos maths. so anyone got any ideas ? |
| ||
No fair, CS, as you were/are part of The Black Lotus, if I'm interpreting your nick correctly! Nice though! |
| ||
yeah, tho I just was one of the the composer there. The NL coders were all asm/c++ gurus, and asm/c++ both look kinda like abacadabra to me, so their help wasn't of much use for me. The things that I know about coding and algos, are things that I developed/discovered on my own. This plasma is fairly simple, I did it over a year ago in B3d actually, just a month ago I decided to run it in a b+ canvas that I could stretch. Originally I didn't even intend to make a plasma but a spherical glow/flare.. some texgens call it an enviroment map. And I was like: hey, what if you mess some vars up here and there, and bingo, a plasma was born. :) btw, officially I'm still @ TBL, but the PC division is pretty dead now. |
| ||
CS yours is nice m8. I had to convert it back to B3D but its still not what im after. What im looking for is one more like the one I have done, but more fluid. if you check it you will see what I mean. |
| ||
I don't know if it exists in BlitzPlus, but in B3D there is a 2D example called cows and bees, that uses a plasma background, you could take a look at that for inspiration in fact, here's the code that draws the plasma from that example: dy=dy-1 ; replace with sheep coords musx=manx musy=many For x=0 To 640 Step 8 For y=2 To 395 Step 8 cv=Rnd(-2,2) cv=cv+Abs(x-musx)*Sin(y+(dy)) cv=cv+Abs(y-musy)*Cos((x+dy)+Sin((x+y))) cv=cv+Abs(x-musx) bv=Abs(x-musx)*(Sin(y)) bv=bv+Abs(y-musy)*Sin(x) bv=bv+(musx+musy)/12 bv=bv+(cv/12) cv=255-cv If bv<0 Then bv=0 If bv>255 Then bv=255 If cv>255 Then cv=255 cv=cv-100 If cv<0 Then cv=9 tv=cv+bv tv=tv*Sin(dy)*8 If tv<0 Then tv=0 If tv>255 Then tv=255 Color tv,bv,cv+(tv/3) ;Plot x,y Rect x,y,8,8,True Next Next |
| ||
![]() ; Plasma Test ; ; Yavin ; ; Teamrebellion.co.uk ; ;Code modified by Richard R Betson 11/10/03 ;Faster lookups added. ;Tiled with CopyRect For fullscreen FX. Global gw=320 Global gh=240 Graphics 640,480,16,2 SetBuffer BackBuffer() Cls Global temp_image temp_image=CreateImage(gw,gh) Global counter% counter=1 Dim lCos(360) For looper=1 To 360 lcos(looper)=Cos(looper) Next Dim aa(gw,gh) Dim bb(gw,gh) Dim cc(gw,gh) plasma_lu() Color 255,255,255 While Not KeyHit(1) draw_plasma() DrawImage temp_image,0,0 For ii=1 To gw CopyRect ii-1,0,1,gh,(gw*2)-ii,0,BackBuffer(),BackBuffer() Next For ii=1 To gh CopyRect 0,ii-1,(gw*2),1,0,(gh*2)-ii,BackBuffer(),BackBuffer() Next fps=fps+1 If fps_t<MilliSecs() fp$=" "+Str$(fps) fps2=fps fps_t=1000+MilliSecs() fps=0 EndIf Color 255,255,255 Text 10,15,"FPS: "+fp$ Flip False If KeyHit(2)=True SaveBuffer(FrontBuffer(),"pic.bmp") EndIf Wend Function draw_plasma() LockBuffer ImageBuffer(temp_image) For looper=1 To gw-1 For inner=1 To gh-1 Local r%,g%,a,b,c a=aa(looper,inner) b=bb(looper,inner) c=cc(looper,inner) a=a+counter b=b+counter c=c+counter WritePixelFast looper,inner,((c Shl 16) Or (b Shl 8 ) Or (a )),ImageBuffer(temp_image) Next Next UnlockBuffer ImageBuffer(temp_image) counter=counter+2:If counter=>1000 Then counter=0 End Function Function plasma_lu() For looper=1 To gw For inner=1 To gh Local r%,g%,a,b,c aa(looper,inner)=-Cos(looper)*looper bb(looper,inner)=Cos(looper)*looper cc(looper,inner)=-Cos(looper)*looper aa(looper,inner)=aa(looper,inner)-Sin(inner)*inner bb(looper,inner)=bb(looper,inner)+Sin(inner)*inner cc(looper,inner)=cc(looper,inner)-Sin(inner)*inner Next Next End Function >Added Look-up Table >Tiled/flipped 640 x 480 >FPS 58 fullscreen --- 43 Windowed Yavin, I modified this to run faster with a look-up table and a tiled/fliped screen using copyrect. Did it just for fun... ;) Good work Yavin :) PS: This seems to crash in B+ but works fine in B3D (mmmm...) L8r, |
| ||
There are no bounds checking for writepixelfast in blitz+ so your lines that looks like this: For looper=1 To gw For inner=1 To gh needs to be like this: For looper=0 To gw-1 For inner=0 To gh-1 What you are doing is drawing pixels from 1 to 320 and from 1 to 240, but the image you have created is 0-239 and 0-319. If you use WPF outside a buffer in blitz+ you are very likely to crash it and do other strange things because you are writing data to memory that has not been reserved. Always be sure that you keep within the screen/image buffer when using WPF or use some kind of manual bounds checking. |
| ||
zawran, Right! :) Forgot...Fixed... Runs slower in B+ - FPS 29 windowed, 33 fullscreen. Blitting would make it faster :) L8r, |
| ||
Runs at 51fps on my computer windowed, and 65fps fullscreen. I have a 2.4ghz, 512mb ram, Geforce4mx 64mb. |
| ||
Brilliant stuff & Welldone guys! :) |
| ||
Man I forgot all about this thread. lol glad I found it againc cos I lost my source. Thanks to those who added to it. |
| ||
How did you get on with this mate? |
| ||
FWIW, here's my plasma style effect from the title screen of my game Viper (link in sig).; Plasma effect written by Mark Tiffany for Viper menu screens. Global Plasma_Cycle Global Plasma_Width Global Plasma_Height Global Plasma_Image Const MAXSIN=256 Global LSinB Global Plasma_Speed=0 Global Plasma_On=True ;----------------------- TEST CODE ; Global SCREEN_WIDTH=640, SCREEN_HEIGHT=480 Graphics SCREEN_WIDTH,SCREEN_HEIGHT,16,2 SetBuffer BackBuffer() ClsColor 255,255,255 Cls PlasmaSetup() Repeat SetBuffer BackBuffer() PlasmaDraw() Flip False If KeyHit(1) Then Exit Forever End ;----------------------- END OF TEST CODE Global buffer_fmt,buffer_bank,buffer_offset_x,buffer_offset_y,buffer_base Global buffer_offset_x2,buffer_offset_x4,buffer_offset_x8 Global buffer_offset_y2,buffer_offset_y4,buffer_offset_y8 Global buffer_rowsize,buffer_rowsize2,buffer_rowsize4,mask Function PlasmaSetup() Plasma_Image=CreateImage(SCREEN_WIDTH,SCREEN_HEIGHT,1,4) buff=ImageBuffer(Plasma_Image) SetBuffer buff ClsColor 255,255,255 Cls LockBuffer(buff) buffer_fmt=LockedFormat(buff) buffer_bank=LockedPixels(buff) buffer_offset_y=LockedPitch(buff) If buffer_fmt=1 Then buffer_offset_x=4 buffer_base=17 mask=$40 ElseIf buffer_fmt=1 Then buffer_offset_x=4 buffer_base=17 mask=$20 ElseIf buffer_fmt=3 Then buffer_offset_x=3 buffer_base = 140 mask=$FF ElseIf buffer_fmt=4 Then buffer_offset_x=4 buffer_base = 140 mask=$FF End If UnlockBuffer(buff) LSinB = CreateBank(MAXSIN+1) For n=0 To MAXSIN If buffer_fmt<3 Then PokeByte LSinB,n,buffer_base + 6 * Sin(n*360.0/256.0) Else PokeByte LSinB,n, buffer_base + 50 * Sin(n*360.0/256.0) End If Next Plasma_Width = Ceil((SCREEN_WIDTH/8)+0.5)-2 Plasma_Height = Ceil((SCREEN_HEIGHT/8)+0.5)-2 buffer_offset_x2 = buffer_offset_x * 2 buffer_offset_x4 = buffer_offset_x * 4 buffer_offset_x8 = buffer_offset_x * 8 buffer_offset_y2 = buffer_offset_y * 2 buffer_offset_y4 = buffer_offset_y * 4 buffer_offset_y8 = buffer_offset_y * 8 buffer_rowsize = buffer_offset_x * SCREEN_WIDTH buffer_rowsize2 = buffer_rowsize * 2 buffer_rowsize4 = buffer_rowsize * 4 time=MilliSecs() PlasmaDraw() Plasma_Speed=MilliSecs()-time If Plasma_Speed>100 Then Plasma_On=False Else Plasma_On=True End If End Function Function PlasmaDraw() Local rgb Local base_r,base_g,base_b Local r,g,b If Plasma_On Then ; cycle If Plasma_Cycle > 254 Then Plasma_Cycle = 0 Else Plasma_Cycle = Plasma_Cycle + 1 End If buff=ImageBuffer(Plasma_Image) SetBuffer buff LockBuffer(buff) base_r=Plasma_Cycle base_g=192+Plasma_Cycle base_b=256-Plasma_Cycle For y = 0 To Plasma_Height offset = buffer_offset_y8 * y ioffset = offset y2=y Shl 1 r = base_r+y2 g = base_g+y2 b = base_b-y For x = 0 To Plasma_Width rr = PeekByte(LSinB,((r - x) And mask)) gg = PeekByte(LSinB,((g + x + x) And mask)) bb = PeekByte(LSinB,((b - x) And mask)) If buffer_fmt=1 Then rgb=(rr Shl 11) Or (gg Shl 5) Or bb rgb=(rgb Shl 16) Or rgb ElseIf buffer_fmt=2 rgb=(rr Shl 10) Or (gg Shl 5) Or bb rgb=(rgb Shl 16) Or rgb ElseIf buffer_fmt=3 rgb=(rr Shl 16) Or (gg Shl 8) Or bb ElseIf buffer_fmt=4 rgb=$7F000000 Or (rr Shl 16) Or (gg Shl 8) Or bb End If PokeInt buffer_bank,offset,rgb CopyBank buffer_bank,offset,buffer_bank,offset+buffer_offset_x,buffer_offset_x CopyBank buffer_bank,offset,buffer_bank,offset+buffer_offset_x2,buffer_offset_x2 CopyBank buffer_bank,offset,buffer_bank,offset+buffer_offset_x4,buffer_offset_x4 offset=offset+buffer_offset_x8 Next CopyBank buffer_bank,ioffset,buffer_bank,ioffset+buffer_offset_y,buffer_rowsize CopyBank buffer_bank,ioffset,buffer_bank,ioffset+buffer_offset_y2,buffer_rowsize2 CopyBank buffer_bank,ioffset,buffer_bank,ioffset+buffer_offset_y4,buffer_rowsize4 Next UnlockBuffer(buff) End If SetBuffer BackBuffer() DrawBlock Plasma_Image,0,0 End Function Hmmmmmm, I probably ought to have put a couple of comments in there! Ah well. |