Any specific reason for not using particles?
Instead of moving billboards, I would use a mesh like this:
Note: Use the flares in the PB textures folders for images for visuals..
viewtopic.php?f=36&t=70132&hilit=meshor the particle way:
Way back I made this demo called pouring rain. (Before I began to make 'things big' on a small scale).
Here it is - I've changed the particle's velocity command so the example works with 5.73.
Code:
;Simple example of pouring rain...
EnableExplicit
InitEngine3D()
InitSprite()
InitMouse()
InitKeyboard()
DeclareModule Rain
Declare.i SetResolution(Width.i = 1024, Height.i = 768)
Declare.i RunDemo()
EndDeclareModule
Module Rain
Structure RainData
id.i
mat.i
tex.i[2]
x.f
y.f
z.f
EndStructure
Structure _MeshData
mesh.i
id.i
mat.i
tex.i
id2.i
EndStructure
Structure _LampsData
pole._MeshData
arm._MeshData
light.i
EndStructure
Structure ObjectData
rain.RainData
splash.RainData
road._MeshData
street._MeshData
clouds._MeshData
List build._MeshData()
EndStructure
Declare.i DoPouringRain()
Declare.i DoStreetAndRoad()
Declare.i DoBuildings()
Declare.i DoClouds()
Declare.i CreateBuildingTexture()
Declare.i RandomI(min.i, Max.i, Res.i = 100000)
Declare.i CheckBuild()
Global Win.i, Scr.i, Cam.i, FS.i
Global ob.ObjectData
Procedure.i SetResolution(Width.i = 1024, Height.i = 768)
If FullScreen = #False
Win = OpenWindow(#PB_Any, 0, 0, Width, Height, "Pouring rain", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
Scr = OpenWindowedScreen(WindowID(Win), 0 ,0 , Width * DesktopResolutionX(), Height * DesktopResolutionY(), #False, 0, 0, #PB_Screen_SmartSynchronization)
EndIf
Cam = CreateCamera(#PB_Any, 0, 0, 100, 100)
MoveCamera(Cam, 0, 50, 220)
CameraBackColor(Cam, $323234)
Fog($323234, 250, 200, 2000)
EndProcedure
Procedure.i RandomI(min.i, Max.i, Res.i = 100000)
ProcedureReturn (Min + (Max - Min) * Random(Res) / Res)
EndProcedure
Procedure.i DoPouringRain()
With ob\rain
\id = CreateParticleEmitter(#PB_Any, 2000, 600, 2000, #PB_Particle_Box, 0, 0, 0)
\tex[0] = CreateTexture(#PB_Any, 2 , 12)
StartDrawing(TextureOutput(\tex[0]))
LineXY(1, 0, 1, 10, $FFFFFF)
StopDrawing()
\mat = CreateMaterial(#PB_Any, TextureID(\tex[0]))
ScrollMaterial(\mat, 3 ,0 ,#PB_Material_Animated)
ParticleMaterial(\id, MaterialID(\mat))
ParticleTimeToLive(\id, 4, 6)
ParticleVelocity(\id, #PB_Particle_MinimumVelocity, 200)
ParticleVelocity(\id, #PB_Particle_MaximumVelocity, 400)
ParticleVelocity(\id, #PB_Particle_Velocity, 300)
ParticleEmitterDirection(\id, 0, -1, 0)
ParticleSize(\id, 0.1, 150)
ParticleEmissionRate(\id, 1500)
ParticleSpeedFactor(\id, 4)
EndWith
With ob\splash
\id = CreateParticleEmitter(#PB_Any, 2000, 2000, 5, #PB_Particle_Box, 0, 12, 0)
\tex[0] = CreateTexture(#PB_Any, 8 , 10)
StartDrawing(TextureOutput(\tex[0]))
LineXY(4,10,2,2,$FFFFFF)
LineXY(4,10,4,2,$FFFFFF)
LineXY(4,10,6,2,$FFFFFF)
StopDrawing()
\mat = CreateMaterial(#PB_Any, TextureID(\tex[0]))
MaterialBlendingMode(\mat, #PB_Material_Color)
ParticleMaterial(\id, MaterialID(\mat))
ParticleTimeToLive(\id, 0.1, 0.1)
ParticleVelocity(\id, #PB_Particle_MinimumVelocity, 0.01)
ParticleVelocity(\id, #PB_Particle_MaximumVelocity, 0.01)
ParticleVelocity(\id, #PB_Particle_Velocity, 0.01)
ParticleEmitterDirection(\id, 0, 1, 0)
ParticleSize(\id, 5, 1)
ParticleEmissionRate(\id, 2700)
ParticleSpeedFactor(\id, 2)
EndWith
ProcedureReturn #True
EndProcedure
Procedure.i DoStreetAndRoad()
Protected tex.i
With ob\road
\mesh = CreatePlane(#PB_Any, 1000, 1000, 10, 10, 1, 1)
\tex = CreateTexture(#PB_Any, 512, 512)
StartDrawing(TextureOutput(\tex))
Box(0, 0, 512, 512, $484545)
For x = 0 To 10000
Plot(Random(511,1), Random(511,1), $737273)
Next x
Box(10,0,20,512, $C1C2BF)
Box(502,0,20,512, $C1C2BF)
For y = 0 To 9 Step 100
Box(256, y, 80, 200, $C1C2BF)
Next y
StopDrawing()
\mat = CreateMaterial(#PB_Any, TextureID(\tex))
ScaleMaterial(\mat, 0.01, 0.01)
MaterialFilteringMode(\mat, #PB_Material_Trilinear)
ScrollMaterial(\mat, 0.6,0, #PB_Material_Fixed)
ScrollMaterial(\mat, 0,-1, #PB_Material_Animated)
\id = CreateEntity(#PB_Any, MeshID(\mesh), MaterialID(\mat), 0, 0, 0)
ScaleEntity(\id, 10, 1, 10)
EndWith
With ob\street
\mesh = CreateCube(#PB_Any, 0.5)
\tex = CreateTexture(#PB_Any, 1000,1000)
StartDrawing(TextureOutput(\tex))
Box(0,0, 50, 1000, $978F8A)
Box(950, 0, 50, 1000, $978F8A)
Box(51,0, 900, 1000, $59554C)
StopDrawing()
\mat = CreateMaterial(#PB_Any, TextureID(\tex))
\id = CreateEntity(#PB_Any, MeshID(\mesh), MaterialID(\mat), -300, -20, 0)
ScaleEntity(\id, 700,100, 10000)
\id2 = CopyEntity(\id, #PB_Any)
MoveEntity(\id2, 300,-20,0)
EndWith
ProcedureReturn #True
EndProcedure
Procedure.i CreateBuildingTexture()
Protected tex.i, ColorGrey.i
tex = CreateTexture(#PB_Any, 512, 512)
StartDrawing(TextureOutput(tex))
ColorGrey = Random(100,40)
Box(0, 0, 512, 512, RGB(ColorGrey, ColorGrey, ColorGrey))
Box(0, 0, 512, 30, $8B9075)
For y = 60 To 460 Step 20
For x = 0 To 512 Step 20
ColorGrey = Random(255)
Box(x,y, 10, 10, RGB(ColorGrey, ColorGrey, ColorGrey))
Next x
Next y
Box(0, 480, 512, 32, $8B9075)
For x = 10 To 512 Step 80
Box(x, 484, 15, 30, $555555)
Next x
StopDrawing()
ProcedureReturn tex
EndProcedure
Procedure.i DoBuildings()
Protected scalex.i, scaley.i, scalez.i
For z = 0 To 5
AddElement(ob\build())
With ob\build()
\mesh = CreateCube(#PB_Any, 150)
\tex = CreateBuildingTexture()
\mat = CreateMaterial(#PB_Any, TextureID(\tex))
\id = CreateEntity(#PB_Any, MeshID(\mesh),MaterialID(\mat), -180, 100, 0-z*300)
\id2 = CopyEntity(\id, #PB_Any)
MoveEntity(\id2, 180, 100, 0-z*300)
EndWith
Next z
ProcedureReturn #True
EndProcedure
Procedure.i DoClouds()
Protected tex.i, Col.i
With ob\clouds
\mesh = CreatePlane(#PB_Any, 5000, 5000, 10, 10, 1, 1)
\tex = CreateTexture(#PB_Any, 1024, 1024)
StartDrawing(TextureOutput(\tex))
DrawingMode(#PB_2DDrawing_AlphaBlend)
For y = 0 To 4000
ypos = Random(922,101)
xpos = Random(922, 101)
For x = 0 To 200
Col.i = Random(100,40)
Plot(RandomI(xpos-100, xpos+100), RandomI(ypos-100, ypos+100),RGBA(Col,Col,Col, Random(150,50)))
Next x
Next y
StopDrawing()
tex = CreateTexture(#PB_Any, 1024, 1024)
StartDrawing(TextureOutput(tex))
DrawingMode(#PB_2DDrawing_AlphaBlend)
For y = 0 To 4000
xpos = Random(922, 101)
ypos = Random(922, 101)
For x = 0 To 200
Col.i = Random(100,40)
Plot(RandomI(xpos-100, xpos+100), RandomI(ypos-100, ypos+100),RGBA(Col,Col,Col, Random(150,50)))
Next x
Next y
StopDrawing()
\mat = CreateMaterial(#PB_Any, TextureID(\tex))
ScaleMaterial(\mat, 5, 5)
ScrollMaterial(\mat, -0.0002, 0.0002, #PB_Material_Animated)
AddMaterialLayer(\mat, TextureID(tex),#PB_Material_Add)
ScaleMaterial(\mat, 20, 20, 1)
ScrollMaterial(\mat, 0.0002, 0.0002, #PB_Material_Animated, 1)
\id = CreateEntity(#PB_Any, MeshID(\mesh), MaterialID(\mat), 0, 200, 200)
RotateEntity(\id, 180, 0, 0)
EndWith
ProcedureReturn #True
EndProcedure
Procedure.i CheckBuild()
ForEach ob\build()
If EntityZ(ob\build()\id,#PB_Absolute) > 180
MoveEntity(ob\build()\id, -180, 100, -1600, #PB_Absolute)
MoveEntity(ob\build()\id2, 180, 100, -1600, #PB_Absolute)
Else
MoveEntity(ob\build()\id, 0, 0, 1,#PB_Relative)
MoveEntity(ob\build()\id2, 0, 0, 1,#PB_Relative)
EndIf
Next
EndProcedure
Procedure.i RunDemo()
Quit = 0
ret = DoPouringRain()
ret = DoStreetAndRoad()
ret = DoBuildings()
ret = DoClouds()
Repeat
If FS = #False
Repeat
ev = WindowEvent()
If ev = #PB_Event_CloseWindow
Quit = 1
EndIf
Until ev = 0
EndIf
ret = CheckBuild()
RenderWorld()
ExamineKeyboard()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
EndProcedure
EndModule
Rain::SetResolution(1920,1080)
Rain::RunDemo()