Try my new website:
www.urcho.com
- the new SIMPLE social network
Sign up
|
287
members |
114
snippets
Search for:
ALL
POPULAR
File Controls
Multiplayer Code
2D Effects
3D Effects
Oldskool demos
Basic Functions
Maths/Physics
Sound
Tutorials
Misc
Username:
Password:
Sign up
Twirly special FX demo by big10p
[
back
]
Author:
Archive
| Viewed:
338
times | Language:
BlitzBasic 3D
| Category:
3D Effects
; ; Twirly Special FX demo by big10p (A.K.A. Chris Chadwick) 2003 ; Graphics3D 800,600,32 SetBuffer BackBuffer() WireFrame 0 AntiAlias 0 SeedRnd MilliSecs() Type twirly_layerT Field ent ; Layer star mesh entity. Field rot# ; Amount to rotate layer each update. Field clut_i% ; Index of layer's CLUT colour. End Type Type twirlyT Field tx#,ty# ; Demo-specific 2D twirly movement amounts. Field piv ; Control pivot - all layers are attached to this. Field hidden% ; Bool flag to indicate if Twirly is hidden. Field layer_bank ; Bank holding Handle() IDs of all layers. Field num_layers% ; Total number of Twirly layers. Field clut% ; clut_banks() index of Twirly's CLUT. Field max_clut_i% ; Bank index of last colour (RGB set) in CLUT. Field clut_cycle% ; CLUT cycle control. - left, 0 no cycle, + right. Field cycle_count% ; Count down to next CLUT cycle. End Type ; Create 2 starfield planes. Global tex1 = CreateTexture(128,128,4) make_tex(tex1) plane1 = CreatePlane() RotateEntity plane1,-90,0,0 PositionEntity plane1,0,0,10 EntityTexture plane1,tex1 Global tex2 = CreateTexture(128,128,4) make_tex(tex2) plane2 = CreatePlane() RotateEntity plane2,-90,0,0 PositionEntity plane2,0,0,11 EntityTexture plane2,tex2 Global frame_count% Global fps% Global slowest_fps% Global fps_timeout% Global frame_time% Global slowest_frame% Global frame_start% fps_timer = CreateTimer(60) slowmo% = False wiref% = False Global cam = CreateCamera() PositionEntity cam,0,0,-20 CameraZoom cam,1.4 light = CreateLight() Const END_OF_CLUT% = -1 Const END_OF_CLUT_LIST% = -2 Const MAX_CLUTS% = 100 Global num_cluts% = 0 Dim clut_banks(MAX_CLUTS-1) open_twirly() copy_clut_grad(1,5) ; Create some twirlies. For n = 1 To 3 tw1.twirlyT = create_preset_twirly(n) PositionEntity tw1\piv,Rnd(-5,5),Rnd(-5,5),-10 Next vp1# = 1 : vp2# = 1 ; --- Main loop --- While Not KeyHit(1) frame_start = MilliSecs() If KeyHit(28) Then slowmo = Not slowmo If KeyHit(14) Then wiref = Not wiref : WireFrame wiref For this.twirlyT = Each twirlyT CameraProject cam,EntityX(this\piv),EntityY(this\piv),EntityZ(this\piv) If ProjectedX() > 800 Or ProjectedX() < 0 Then this\tx=-this\tx If ProjectedY() > 600 Or ProjectedY() < 0 Then this\ty=-this\ty TranslateEntity this\piv,this\tx,this\ty,0 Next vp1 = vp1 - 0.003 vp2 = vp2 - 0.001 PositionTexture tex1,1,vp1 PositionTexture tex2,1,vp2 update_twirly() RenderWorld ;show_info() ;show_clut(10,80) frame_time = MilliSecs() - frame_start WaitTimer(fps_timer) Flip(1) If slowmo Then Delay 200 Wend close_twirly() ClearWorld End ; The Twirly CLUTS, defined in RGB sets. .twirly_clut_data Data 255,0,0 Data 0,255,0 Data 0,0,255 Data END_OF_CLUT Data 255,255,0 Data 0,255,0 Data 0,255,255 Data 0,0,255 Data 255,0,255 Data 255,0,0 Data END_OF_CLUT Data END_OF_CLUT_LIST ; ; Draws random coloured starfield onto text. ; Function make_tex(tex) SetBuffer TextureBuffer(tex) For y = 0 To 127 For x = 0 To 127 WritePixel x,y,$00000000 Next Next Color 255,255,255 For n = 1 To 200 r = Rand(0,255) Shl 16 g = Rand(0,255) Shl 8 b = Rand(0,255) WritePixel Rand(0,127),Rand(0,127),$ff000000 Or (r Or g Or b) Next ScaleTexture tex,30,30 SetBuffer BackBuffer() End Function ; ; Prepares the Twirly system ready for use. ; Function open_twirly() Local r%,g%,b% Local clut_size%[MAX_CLUTS-1] Local cs% = 0 ; Count CLUT entries and size. Restore twirly_clut_data Repeat Read r If r = END_OF_CLUT clut_size[num_cluts] = cs num_cluts = num_cluts + 1 cs = 0 Read r : If r = END_OF_CLUT_LIST Then Exit EndIf Read g Read b cs = cs + 1 Forever ; Create CLUT banks. Restore twirly_clut_data For i = 0 To num_cluts-1 clut_banks(i) = CreateBank((clut_size[i]*3)*4) For n = 0 To BankSize(clut_banks(i))-1 Step 12 Read r,g,b PokeInt clut_banks(i),n,r PokeInt clut_banks(i),n+4,g PokeInt clut_banks(i),n+8,b Next Read dummy ; Skip END_OF_CLUT terminator. Next End Function ; ; Closes down the Twirly system, freeing all resources. ; Function close_twirly() ; Kill all Twirlies. For this.twirlyT = Each twirlyT free_twirly(this) Next ; Free the CLUT banks. For i = 0 To num_cluts-1 FreeBank clut_banks(i) Next End Function ; ; Frees all resources used by a given twirly. ; ; Params: ; twirly - The twirly to be freed. ; Function free_twirly(twirly.twirlyT) ; Free all Twirly layer resources. For n = 0 To BankSize(twirly\layer_bank)-1 Step 4 layer.twirly_layerT = Object.twirly_layerT(PeekInt(twirly\layer_bank,n)) FreeEntity layer\ent Delete layer Next ; Free actual Twirly resources. FreeEntity twirly\piv FreeBank layer_bank Delete twirly End Function ; ; Creates a single layer twirly. See create_star_mesh() for params. ; Function create_twirly.twirlyT(radius#,points%,indent#,ratio%=True) twirly.twirlyT = New twirlyT twirly\piv = CreatePivot() RotateEntity twirly\piv,0,180,0 ; So we can point twirly at camera. twirly\num_layers = 1 twirly\hidden = False twirly\tx = Rnd(.01,.03) : If Rand(0,1) Then twirly\tx = -twirly\tx twirly\ty = Rnd(.01,.03) : If Rand(0,1) Then twirly\ty = -twirly\ty layer.twirly_layerT = New twirly_layerT twirly\layer_bank = CreateBank(4) PokeInt twirly\layer_bank,0,Handle(layer) ; Create initial twirly layer. layer\ent = create_star_mesh(radius,points,indent,ratio) EntityParent layer\ent,twirly\piv PositionEntity layer\ent,0,0,0,0 EntityFX layer\ent,1+4+8 Return twirly End Function ; ; Adds a layer to the specified, existing twirly. ; See create_star_mesh() for other params. ; Function add_twirly_layer(twirly.twirlyT,radius#,points%,indent#,ratio%=True) layer.twirly_layerT = New twirly_layerT bs = BankSize(twirly\layer_bank) ResizeBank twirly\layer_bank,bs+4 PokeInt twirly\layer_bank,bs,Handle(layer) ; Create twirly layer. layer\ent = create_star_mesh(radius,points,indent,ratio) PositionEntity layer\ent,0,0,Float(twirly\num_layers)*0.001 EntityParent layer\ent,twirly\piv,1 twirly\num_layers = twirly\num_layers + 1 EntityFX layer\ent,1+4+8 End Function ; ; Sequentially 'paints' all layers of a twirly with the given CLUT. ; ; Params: ; twirly - Twirly to be coloured with the specified CLUT. ; clut - Number of CLUT to colour twirly with. ; cycle - Specifies how to cycle the CLUT every time the twirly is updated: ; 0 (default) to not cycle the CLUT. ; -1 to cycle the CLUT to the left. ; 1 to cycle the CLUT to the right. ; dir - Direction to colour the twirly layers with: ; 0 (default) to colour layers from first-to-last. ; 1 to colour layers from last-to-first. ; Function set_twirly_clut(twirly.twirlyT,clut%,cycle%=0,dir%=0) clut_i% = 0 clut_size% = BankSize(clut_banks(clut)) cb = clut_banks(clut) If dir = 0 For n = 0 To twirly\num_layers-1 id = PeekInt(twirly\layer_bank,n*4) layer.twirly_layerT = Object.twirly_layerT(id) layer\clut_i = clut_i EntityColor layer\ent,PeekInt(cb,clut_i),PeekInt(cb,clut_i+4),PeekInt(cb,clut_i+8) clut_i = clut_i + 12 If clut_i = clut_size Then clut_i = 0 Next Else For n = twirly\num_layers-1 To 0 Step -1 id = PeekInt(twirly\layer_bank,n*4) layer.twirly_layerT = Object.twirly_layerT(id) layer\clut_i = clut_i EntityColor layer\ent,PeekInt(cb,clut_i),PeekInt(cb,clut_i+4),PeekInt(cb,clut_i+8) clut_i = clut_i + 12 If clut_i = clut_size Then clut_i = 0 Next EndIf twirly\clut = clut twirly\clut_cycle = cycle twirly\cycle_count = Abs(cycle) twirly\max_clut_i = clut_size-12 End Function ; ; Sets all layers of a twirly to use a given blend mode. ; Function set_twirly_blend(twirly.twirlyT,mode%) For n = 0 To BankSize(twirly\layer_bank)-1 Step 4 layer.twirly_layerT = Object.twirly_layerT(PeekInt(twirly\layer_bank,n)) EntityBlend layer\ent,mode Next End Function ; ; Sets all layers of a twirly to use a given alpha level. ; Function set_twirly_alpha(twirly.twirlyT,alpha#) For n = 0 To BankSize(twirly\layer_bank)-1 Step 4 layer.twirly_layerT = Object.twirly_layerT(PeekInt(twirly\layer_bank,n)) EntityAlpha layer\ent,alpha Next End Function ; ; Creates a copy of an existing CLUT with gradients between each colour. ; ; Params: ; clut - Number of CLUT to be copied. ; grads - Number of gradients to insert between each colour. ; grad_r - Each colour from the copied CLUT is faded to this colour. ; grad_g If not specified (default), colours fade to the next colour ; grad_b from the CLUT being copied. ; ; Returns: ; Index of new clut in clut_banks() array. ; Function copy_clut_grad(clut%,grads%,grad_r#=-1,grad_g#=-1,grad_b#=-1) old_clut = clut_banks(clut) old_size = BankSize(clut_banks(clut)) new_clut = CreateBank(old_size*(grads+1)) clut_banks(num_cluts) = new_clut num_cluts = num_cluts + 1 poke_i = 0 If grad_r=-1 Or grads=0 ; Create gradients between adjacent colours from the copied CLUT. grad_div = grads + 1 For i = 0 To old_size-1 Step 12 r1# = Float(PeekInt(old_clut,i)) g1# = Float(PeekInt(old_clut,i+4)) b1# = Float(PeekInt(old_clut,i+8)) ; Get colour to fade to. If i = old_size-12 ; Wraparound to first colour. r2# = Float(PeekInt(old_clut,0)) g2# = Float(PeekInt(old_clut,4)) b2# = Float(PeekInt(old_clut,8)) Else ; Use next colour in CLUT. r2# = Float(PeekInt(old_clut,i+12)) g2# = Float(PeekInt(old_clut,i+12+4)) b2# = Float(PeekInt(old_clut,i+12+8)) EndIf r_step# = (r2-r1)/grad_div g_step# = (g2-g1)/grad_div b_step# = (b2-b1)/grad_div ; Add original colour and gradients to new CLUT. For n = 0 To grads PokeInt new_clut,poke_i, Int(r1 + (n*r_step)) PokeInt new_clut,poke_i+4,Int(g1 + (n*g_step)) PokeInt new_clut,poke_i+8,Int(b1 + (n*b_step)) poke_i = poke_i + 12 Next Next Else ; Create gradients from copied CLUT colour to grad_r,grad_g,grad_b. For i = 0 To old_size-1 Step 12 r1# = Float(PeekInt(old_clut,i)) g1# = Float(PeekInt(old_clut,i+4)) b1# = Float(PeekInt(old_clut,i+8)) r_step# = (grad_r-r1)/grads g_step# = (grad_g-g1)/grads b_step# = (grad_b-b1)/grads ; Add original colour and gradients to new CLUT. For n = 0 To grads PokeInt new_clut,poke_i, Int(r1 + (n*r_step)) PokeInt new_clut,poke_i+4,Int(g1 + (n*g_step)) PokeInt new_clut,poke_i+8,Int(b1 + (n*b_step)) poke_i = poke_i + 12 Next Next EndIf Return num_cluts - 1 End Function ; ; Updates ALL non-hidden Twirlies. ; Function update_twirly() For this.twirlyT = Each twirlyT If Not this\hidden PointEntity this\piv,cam cb = clut_banks(this\clut) ; Twirly's CLUT cycle frequency management. do_cycle = False If this\clut_cycle this\cycle_count = this\cycle_count - 1 If this\cycle_count = 0 this\cycle_count = Abs(this\clut_cycle) do_cycle = True EndIf EndIf If do_cycle ; Update each layer attached to this twirly, cycling the CLUT. For n = 0 To BankSize(this\layer_bank)-1 Step 4 layer.twirly_layerT = Object.twirly_layerT(PeekInt(this\layer_bank,n)) TurnEntity layer\ent,0,0,layer\rot If this\clut_cycle < 0 ; Cycle CLUT to the left. clut_i = layer\clut_i + 12 If clut_i > this\max_clut_i Then clut_i = 0 Else ; Cycle CLUT to the right. clut_i = layer\clut_i - 12 If clut_i < 0 Then clut_i = this\max_clut_i EndIf layer\clut_i = clut_i EntityColor layer\ent,PeekInt(cb,clut_i),PeekInt(cb,clut_i+4),PeekInt(cb,clut_i+8) Next Else ; Update each layer attached to this twirly. For n = 0 To BankSize(this\layer_bank)-1 Step 4 layer.twirly_layerT = Object.twirly_layerT(PeekInt(this\layer_bank,n)) TurnEntity layer\ent,0,0,layer\rot Next EndIf End If Next End Function ; ; Creates a planar, star-shaped mesh. ; ; Params: ; radius - Radius of star in world units. ; points - Number of points the star should have. ; indent - Sets the 'depth' of the indent between the points of the star. ; ratio - True (default) to indicate that indent is a ratio of the radius ; e.g. 1=no indent (circle), .5=indent midway between point and centre. ; False to indicate that indent is an absolute size. ; ; Returns: ; The newly created star mesh. ; Function create_star_mesh(radius#=1.0,points%=5,indent#=0.5,ratio%=True) If ratio Then indent = radius * indent ; Convert indent to ratio of radius. mesh = CreateMesh() surf = CreateSurface(mesh) verts% = points * 2 vang# = 0 vang_step# = 360.0/Float(verts) ; Add verts for all star points & indents. For n = 0 To verts-1 If (n And 1) Then size# = indent Else size# = radius AddVertex(surf,Cos(vang)*size,Sin(vang)*size,0) VertexNormal surf,n,0,0,-1 vang = vang + vang_step Next ; Add centre vert. AddVertex(surf,0,0,0) VertexNormal surf,verts,0,0,-1 ; Make triangles. For n = 0 To verts-2 AddTriangle surf,n,verts,n+1 Next AddTriangle surf,verts-1,verts,0 Return mesh End Function ; ; Creates a twirly_type preset twirly. ; Function create_preset_twirly.twirlyT(twirly_type%) Select twirly_type Case 1 dir#=.01 For n = 1 To 30 If n=1 tw.twirlyT = create_twirly(n*.01,10,.2) Else add_twirly_layer(tw,n*.1,10,.1) EndIf set_layer_rotate(tw,n-1,dir*n) Next set_twirly_clut(tw,2,2,1) set_twirly_blend(tw,3) set_twirly_alpha(tw,.2) Return tw Case 2 dir#=.01 For n = 1 To 30 If n=1 tw.twirlyT = create_twirly(n*.01,5,.2) Else add_twirly_layer(tw,n*.1,10,.3) EndIf set_layer_rotate(tw,n-1,dir*n) dir = -dir Next set_twirly_clut(tw,2,2,1) set_twirly_blend(tw,3) set_twirly_alpha(tw,.2) Return tw Case 3 dir#=.01 For n = 1 To 30 If n=1 tw.twirlyT = create_twirly(n*.01,5,.2) Else add_twirly_layer(tw,n*.1,5,.3) EndIf set_layer_rotate(tw,n-1,dir*n) Next set_twirly_clut(tw,2,2,1) set_twirly_blend(tw,3) set_twirly_alpha(tw,.2) Return tw End Select End Function ; ; Hides a Twirly from view. Ignores if Twirly is already hidden. ; ; Params: ; twirly - The Twirly to hide from view. ; Function hide_twirly(twirly.twirlyT) If twirly\hidden = False HideEntity twirly\piv twirly\hidden = True End If End Function ; ; Makes a hidden Twirly visible. Ignores if Twirly is already visible. ; ; Params: ; twirly - The hidden Twirly to make visible. ; Function show_twirly(twirly.twirlyT) If twirly\hidden = True ShowEntity twirly\piv twirly\hidden = False End If End Function ; ; Sets a given twirly layer to an absolute rotation. ; Function rotate_twirly_layer(twirly.twirlyT,layer%,rot#) star.twirly_layerT = Object.twirly_layerT(PeekInt(twirly\layer_bank,layer*4)) RotateEntity star\ent,0,0,rot,1 End Function ; ; Sets how much a given twirly layer should rotate by every update. ; Function set_layer_rotate(twirly.twirlyT,layer%,rot#) star.twirly_layerT = Object.twirly_layerT(PeekInt(twirly\layer_bank,layer*4)) star\rot = rot End Function ; ; Debug function to visually display CLUT(s). ; ; Params: ; cx - Screen X coord to display CLUT at. ; cy - Screen Y coord to display CLUT at. ; clut - Number of CLUT to display. ; If not specified (default) then all CLUTS are displayed. ; Function show_clut(cx%=0,cy%=0,clut%=-1) Local cxs = cx Local cw = 10 Local ch = 10 Local gap = 0 If clut = -1 first_clut = 0 last_clut = num_cluts - 1 Else first_clut = clut last_clut = clut EndIf For n = first_clut To last_clut clut = clut_banks(n) For j = 0 To BankSize(clut)-1 Step 12 r = PeekInt(clut,j) g = PeekInt(clut,j+4) b = PeekInt(clut,j+8) Color r,g,b Rect cx,cy,cw,ch,1 cx = cx + cw + gap If (cx+cw-1)>=GraphicsWidth() Then cx=cxs:cy=cy+ch+gap Next cx = cxs cy = cy + ch + 4 Next Color 255,255,255 End Function ; ; Display debug info. ; Function show_info() If fps_timeout frame_count = frame_count + 1 If MilliSecs() > fps_timeout Then fps_timeout = MilliSecs() + 1000 fps = frame_count frame_count = 0 If fps < slowest_fps Or slowest_fps = 0 Then slowest_fps = fps EndIf If frame_time > slowest_frame Then slowest_frame = frame_time Color 0,255,0 Text 10,10," Triangles: " + TrisRendered() Color 255,255,0 Text 10,25," Millisecs: " + frame_time Text 10,40," Slowest: " + slowest_frame Color 0,255,255 Text 10,55," FPS: " + fps Text 10,70," Worst: " + slowest_fps Color 255,255,255 Else ; First call initialization. fps_timeout = MilliSecs() + 1000 EndIf End Function
Author Comments:
This was a special FX entity system I was working on about a year ago before I gave up on it after realizing that overlaying lots of blended layers on top of each other wasnt such a great idea (speed wise). Anyway, I guess Twirlies could still be used for certain things, like making a pretty screensaver, or something. Theyre pretty much infinately configurable as each can have its own user defined CLUT which can be cycled etc.
Login or
create an account
to comment on this snippet