Hi,
as some of you might now from my other posts, i am new to darkbasic and all that 3d stuff
. As you might aswell know, i made a little project where boxes fall down and stack upon each other to get my hands on it and learn about 3d programming in dbpro.
i am now about done with that project thanks to the people helping me with my initial problems / questions. specially svenb
however i am sure i didnt do everything right and that theres still huge optimization potential within my coding. especiall towards the end, when my program renders more than 1000 cubes in the scene, i get some fps dropping for example.
therefore i'd like to post my code here, and hope that some of you can give me some advices on where i can optimize things.
thanks in advance, code below.
(i think it requires dbpro because i use types and other stuff, and you need to enable the "..." line split thing.)
REM Project: CubeSaver
REM Created: 04.01.2008 19:01:33
REM
REM ***** Main Source File *****
REM
REM Screen Setup -----------------------------------------------------
Sync On
Sync Rate 60
gosub _SetDisplayMode
HIDE MOUSE
REM ------------------------------------------------------------------
REM Types ------------------------------------------------------------
TYPE DropableBox
BoxExists AS INTEGER
ObjectID AS INTEGER
BoxColor AS DWORD
IsMoving AS INTEGER
PosX#
PosY#
PosZ#
ENDTYPE
REM ------------------------------------------------------------------
REM Constants & Global Variables -------------------------------------
REM Boxes ---------------------------------------------------------
DIM MovingBoxes() AS DropableBox
Boxes_Size# = 5
Boxes_InitialHeight# = 100
Boxes_FallSpeed# = .75
Boxes_LiftupSpeed# = 2
Boxes_Max = 1200
Boxes_BorderBoxColor = rgb(105,105,105)
Boxes_CreateRandInterval = 10
Boxes_LiftupRandInterval = 2
Boxes_LiftupIndex = 0
Boxes_MoveDirection = 0
temp = 0
REM Plain ---------------------------------------------------------
Plain_Size = 15
Plain_Color = rgb(255,255,255)
REM Camera --------------------------------------------------------
Camera_AutoOrbit = 1
Camera_AutoZoom = 1
Camera_Angle# = 0
Camera_Height# = 100
Camera_Distance# = 100
Camera_TargetDistance# = 100
Camera_MoveSpeed# = .25
Camera_ZoomSpeed# = .1
Camera_MaxTargetDistance# = 160
REM ------------------------------------------------------------------
REM Prepare the Scene ------------------------------------------------
gosub _PrepareScene
gosub _MakeBorder
REM ------------------------------------------------------------------
Randomize Timer()
SET TEXT FONT "Arial"
SET TEXT SIZE 14
INK rgb(255,255,255),0
REM Main Loop
REPEAT
if Camera_AutoOrbit = 1 then gosub _OrbitCamera
if Camera_AutoZoom = 1 then gosub _AutoZoomCamera
if Boxes_MoveDirection = 0
if rnd(Boxes_CreateRandInterval) = 0
if ARRAY COUNT(MovingBoxes()) < Boxes_Max
gosub _MakeCube
else
if (GetMovingCount() = 0) then Boxes_MoveDirection = 1
endif
endif
else
if rnd(Boxes_LiftupRandInterval) = 0
if Boxes_LiftupIndex <= ARRAY COUNT(MovingBoxes())
MovingBoxes(ARRAY COUNT(MovingBoxes())-Boxes_LiftupIndex).isMoving = 1
INC Boxes_LiftupIndex,1
endif
endif
if ARRAY COUNT(MovingBoxes()) > 0
gosub _CheckDestroy
else
Boxes_LiftupIndex = 0
Boxes_MoveDirection = 0
endif
endif
gosub _MoveCubes
TEXT 10,10, "cubes: "+ str$(GetExistingCount())
TEXT 10,20, "fps: "+ str$(SCREEN FPS())
CENTER TEXT SCREEN WIDTH() / 2,SCREEN HEIGHT() - 50,"C U B E S A V E R"
Sync
UNTIL ScanCode() <> NULL
REM ------------------------------------------------------------------
End
REM Sub OrbitCamera --------------------------------------------------
REM Handles the Camera Auto-Rotation
_OrbitCamera:
Camera_Angle# = wrapvalue(Camera_Angle# + Camera_MoveSpeed#)
camX# = newxvalue(0, Camera_Angle#, Camera_Distance#)
camY# = Camera_Height#
camZ# = newzvalue(0, Camera_Angle#, Camera_Distance#)
POSITION CAMERA camX#, camY#, camZ#
POINT CAMERA 0, 0, 0
return
REM ------------------------------------------------------------------
REM Sub AutoZoomCamera --------------------------------------------------
REM Handles the Camera Auto-Zoom
_AutoZoomCamera:
if Camera_TargetDistance# <> Int(Camera_Distance#+0.5)
if Camera_TargetDistance# > Camera_Distance# then Camera_Distance# = Camera_Distance# + Camera_ZoomSpeed#
if Camera_TargetDistance# < Camera_Distance# then Camera_Distance# = Camera_Distance# - Camera_ZoomSpeed#
else
if Camera_TargetDistance# = 1
Camera_TargetDistance# = Camera_MaxTargetDistance#
else
Camera_TargetDistance# = 1
endif
endif
return
REM ------------------------------------------------------------------
REM Sub PrepareScene -------------------------------------------------
REM Creates the Plain, Lighting, etc..
_PrepareScene:
autocam off
MAKE OBJECT PLAIN 1, (Plain_Size-1) * Boxes_Size#, (Plain_Size-1) * Boxes_Size#
ROTATE OBJECT 1, -90,0,0
FIX OBJECT PIVOT 1
COLOR OBJECT 1, Plain_Color
MAKE LIGHT 1
SET POINT LIGHT 1, 0, 100, 0
SHOW LIGHT 1
COLOR BACKDROP rgb(0,0,0)
return
REM ------------------------------------------------------------------
REM Sub MoveCubes ----------------------------------------------------
REM Moves all moving Cubes according to the current MoveDirection
_MoveCubes:
for i = 0 to ARRAY COUNT(MovingBoxes()) step 1
if MovingBoxes(i).IsMoving = 1
if Boxes_MoveDirection = 0
DEC MovingBoxes(i).PosY#, Boxes_FallSpeed#
REM Collision Detection with Plain -------------------------
if MovingBoxes(i).PosY# <= Boxes_Size#/2 then MovingBoxes(i).IsMoving=0:MovingBoxes(i).PosY# = Boxes_Size#/2
REM Collision Detection with other Cubes -------------------
for j=0 TO ARRAY COUNT(MovingBoxes()) STEP 1
if MovingBoxes(j).IsMoving = 0 AND MovingBoxes(i).ObjectID <> MovingBoxes(j).ObjectID
if MovingBoxes(j).PosX# = MovingBoxes(i).PosX# AND MovingBoxes(j).PosZ# = MovingBoxes(i).PosZ#
if MovingBoxes(i).PosY#-Boxes_Size# <= MovingBoxes(j).PosY#
MovingBoxes(i).IsMoving = 0
MovingBoxes(i).PosY# = MovingBoxes(j).PosY#+Boxes_Size#
endif
endif
endif
next j
else
INC MovingBoxes(i).PosY#, Boxes_LiftupSpeed#
endif
POSITION OBJECT MovingBoxes(i).ObjectID, MovingBoxes(i).PosX#, MovingBoxes(i).PosY#, MovingBoxes(i).PosZ#
endif
next i
return
REM ------------------------------------------------------------------
REM Sub CheckDestroy--------------------------------------------------
REM Checks for uplifting Boxes to reach initial Height and need destroy
_CheckDestroy:
for i = 0 to ARRAY COUNT(MovingBoxes()) step 1
if MovingBoxes(i).isMoving = 1
if MovingBoxes(i).PosY# >= Boxes_InitialHeight#
DELETE OBJECT MovingBoxes(i).ObjectID
MovingBoxes(i).IsMoving = 0
MovingBoxes(i).BoxExists = 0
endif
endif
next i
if GetExistingCount() = 0 then EMPTY ARRAY MovingBoxes()
return
REM Sub MakeCube -----------------------------------------------------
REM Creates a new Cube instance at random position
_MakeCube:
REPEAT
IsGoodRand = 1
tmp_x# = -(Plain_Size*Boxes_Size#)/2 + (rnd(Plain_Size-2)+1)*Boxes_Size#
tmp_z# = -(Plain_Size*Boxes_Size#)/2 + (rnd(Plain_Size-2)+1)*Boxes_Size#
for i = 0 TO ARRAY COUNT(MovingBoxes()) STEP 1
if MovingBoxes(i).IsMoving = 1 AND MovingBoxes(i).PosX# = tmp_x# AND MovingBoxes(i).PosZ# = tmp_z#
if MovingBoxes(i).PosY# >= Boxes_InitialHeight# - Boxes_Size#
IsGoodRand = 0
endif
endif
next i
UNTIL IsGoodRand = 1
ARRAY INSERT AT BOTTOM MovingBoxes()
MovingBoxes(ARRAY COUNT(MovingBoxes())).BoxExists = 1
MovingBoxes(ARRAY COUNT(MovingBoxes())).BoxColor = RGB(rnd(255),rnd(255),rnd(255))
MovingBoxes(ARRAY COUNT(MovingBoxes())).IsMoving = 1
MovingBoxes(ARRAY COUNT(MovingBoxes())).PosX# = tmp_x#
MovingBoxes(ARRAY COUNT(MovingBoxes())).PosZ# = tmp_z#
MovingBoxes(ARRAY COUNT(MovingBoxes())).PosY# = Boxes_InitialHeight#
MovingBoxes(ARRAY COUNT(MovingBoxes())).ObjectID = 2 + (Plain_Size+1)*4 + ARRAY COUNT(MovingBoxes())
CLONE OBJECT MovingBoxes(ARRAY COUNT(MovingBoxes())).ObjectID,2
POSITION OBJECT MovingBoxes(ARRAY COUNT(MovingBoxes())).ObjectID, MovingBoxes(ARRAY COUNT(MovingBoxes())).PosX#,...
MovingBoxes(ARRAY COUNT(MovingBoxes())).PosY#,...
MovingBoxes(ARRAY COUNT(MovingBoxes())).PosZ#
COLOR OBJECT MovingBoxes(ARRAY COUNT(MovingBoxes())).ObjectID, MovingBoxes(ARRAY COUNT(MovingBoxes())).BoxColor
SET OBJECT CULL MovingBoxes(ARRAY COUNT(MovingBoxes())).ObjectID,1
return
REM ------------------------------------------------------------------
REM Sub MakeBorder ---------------------------------------------------
REM Draws the Border around the Plain
_MakeBorder:
MAKE OBJECT CUBE 2, Boxes_Size#
COLOR OBJECT 2, Boxes_BorderBoxColor
POSITION OBJECT 2, -(Plain_Size*Boxes_Size#)/2,Boxes_Size#/2,(Plain_Size*Boxes_Size#)/2
for i=1 to Plain_Size step 1
INSTANCE OBJECT 2+i,2
POSITION OBJECT 2+i, -(Plain_Size*Boxes_Size#)/2 + i*Boxes_Size#,Boxes_Size#/2,(Plain_Size*Boxes_Size#)/2
next i
for j=1 to Plain_Size step 1
INSTANCE OBJECT 2+i+j,2
POSITION OBJECT 2+i+j, -(Plain_Size*Boxes_Size#)/2,Boxes_Size#/2,(Plain_Size*Boxes_Size#)/2 - j*Boxes_Size#
next i
for k=1 to Plain_Size step 1
INSTANCE OBJECT 2+i+j+k,2
POSITION OBJECT 2+i+j+k,(Plain_Size*Boxes_Size#)/2,Boxes_Size#/2,(Plain_Size*Boxes_Size#)/2 - k*Boxes_Size#
next k
for l=1 to Plain_Size step 1
INSTANCE OBJECT 2+i+j+k+l,2
POSITION OBJECT 2+i+j+k+l, -(Plain_Size*Boxes_Size#)/2 + l*Boxes_Size#,Boxes_Size#/2,-(Plain_Size*Boxes_Size#)/2
next l
temp = 2+i+j+k+l
return
REM Sub SetDisplayMode -----------------------------------------------
REM Set's the Display Mode to current Desktop Resolution
_SetDisplayMode:
load dll "user32.dll", 1
screen_width = call dll(1, "GetSystemMetrics", 0)
screen_height = call dll(1, "GetSystemMetrics", 1)
SET DISPLAY MODE screen_width, screen_height, 32
return
REM ------------------------------------------------------------------
REM Function GetExistingCount ----------------------------------------
Function GetExistingCount()
Result = 0
for i=0 to ARRAY COUNT(MovingBoxes())
if MovingBoxes(i).BoxExists = 1 then INC Result,1
next i
EndFunction Result
REM Function GetMovingCount ------------------------------------------
REM returns the Number of moving cubes
Function GetMovingCount()
Result = 0
for i=0 to ARRAY COUNT(MovingBoxes())
if MovingBoxes(i).IsMoving = 1 then INC Result,1
next i
EndFunction Result