QuadOccludeMap
State = QuadOccludeMap(ThisMap, TheLevel, X1, Y1, X2, Y2, X3, Y3, X4, Y4)
 
Parameters:

    ThisMap = The Index of the map you wish to occlude
    TheLevel = The level within the map
    X1 = The X coordinate of Vertex 1
    Y1 = The Y coordinate of Vertex 1
    X2 = The X coordinate of Vertex 2
    Y2 = The Y coordinate of Vertex 2
    X3 = The X coordinate of Vertex 3
    Y3 = The Y coordinate of Vertex 3
    X4 = The X coordinate of Vertex 4
    Y4 = The Y coordinate of Vertex 4
Returns:

    State = The status of occlusion function
 

     The QuadOccludeMap() function checks if a Quad (4 sided polygon) region is occluding the equivalent area within a map level. The QuadOccludeMap function will clear this area on the selected map level, this helps reduce the amount of overdraw your game is performing. So the map occlusion commands help us even out the amount of rendering time our game is doing each update.

      For example, If we imagine a game scene with 2 or more map layers, then normally we'd draw them all over each other, regardless of what is actually visible in screen. So with three layers we're potentially drawing every pixel on the screen three times.

      With modern hardware, this may not be such of big deal (assuming a medium screen resolution), but what if you want your games to run older systems, or you just want to squeeze every drop of rendering performance you can ? - Well, then it's worth seeing if we can cull out any of the redundant background drawing by removing anything in the background that's being occluded by foreground graphics.

      We could do this by previously calculating the hard regions of the foreground. These might be stored in list for example, then before rendering the back layers, we mask those layers with out hard foreground region, using some of the map occlusion commands. This is remove any blocks in those that layers that would have been being drawn, but never visible to the player. You could do the same thing with sprites too. It's really up to you.

      The key to occlusion, is that when we remove the hidden background elements, this area has to be covered with something solid in the foreground. It doesn't work if the foreground area is translucent, this breaks the illusion, as the player can see both the foreground and the missing background segment.

      However, we don't want to get too excited and try to implement too much occlusion, As with all optimizations, there's a fine line between getting meaningful rendering performance gain, and losing that potential gain by adding bunch of clunky calculations in their place. So remember, we're trying to remove work from our game, not add more to it.




FACTS:


      * QuadOccludeMap will alter the level if any block is clearly within the bounds the commands region. If up to the user to restore this. See CopyLevel, CloneLevel

 
Example Source: Download This Example
;     -----------------------------------------------
;           --------->> SET UP <<------------
;     -----------------------------------------------
  
  
  SetFPS 100
  
  Method=1
  RectWidth=250
  RectHeight=200
  Angle#=45
  
  Dim vertx#(4)
  Dim verty#(4)
  
  
; create the random map from some circles
  Map,OriginalLevel=Build_Random_Map(32,32)
  
; request a free index of the level in this map
  Level=GetFreeMapLevel(Map)
  
; make a backdrop picture
  BackDrop=NewImage(800,600)
  RenderToImage Backdrop
  c1=RndRGB()
  c2=RndRGB()
  ShadeBox 0,0,800,600,c1,c1,c2,c2
  RenderToScreen
  
  
; create a camera to view the scene with
  Cam=NewCamera()
  CameraCls Cam,off
  
  
  
  
;     ------------------------------------------------
;      --------->> MAIN LOOP OF PROGRAM <<----------
;     ------------------------------------------------
  
  
  Do
     
   ; Get the camera current position
     CamX=GetCameraX(cam)
     CamY=GetCameraY(cam)
     
   ; Get the mouse position
     MX=MouseX()+CamX
     MY=MouseY()+CamY
     
   ; Check if the Left Mouse is pressed ?
     If LeftMouseButton()
        RectWidth=Mod(RectWidth+1,400)
     EndIf
     
   ; Check if the Right Mouse is pressed ?
     If RightMouseButton()
        RectHeight=Mod(RectHeight+1,400)
     EndIf
     
     
   ; Check if the Middle Mouse Button is pressed ?
     If MidMouseButton()
        Angle#=WrapAngle(Angle#,1)
     EndIf
     
   ; Restore the Level to it's original state
     CloneLevel Map,OriginalLevel,Map,Level
     
     
   ; tell PB to capture the following drawing commands
     CaptureToScene
     
   ; clear the scene buffer so it's empty
     ClsScene
     
     
     
     Collision,Method$=DRawQuad(Map,Level,MX,MY,RectWidth,RectHeight,Angle#,Method)
     
     
     
   ; set the capture depth of the next item to a depth of
   ; 100 units
     CaptureDepth 100
     DrawImage BackDrop,CamX,CamY,false
     
   ; draw the map level
     CaptureDepth 10
     DrawMap map,Level,0,0
     
     
     
     CaptureDepth 5
     
     
   ; Test if the Circle Hits the Map blocks & clear them
     Collision=CircleOccludeMap(Map,Level,mx,my,radius)
     
     
     
     
   ; draw the Circle at this depth
     CircleC Mx,My,Radius,Filled,$ffffff
     CircleC Mx,My,Radius-1,false,$ffffff
     
     
   ; draw the scene with this camera
     DrawCamera cam
     
     
   ; Check if the Space key was pressed
     If SpaceKey()
      ; if so, change the collision method
        Method=1-Method
        FlushKeys
     EndIf
     
   ; check if the ENTER key was pressed
     If EnterKey()
      ; If so, toggle Debug mode on the map
        MapDebug Map,1-GetMapDebug(Map)
        FlushKeys
     EndIf
     
     
     
     
   ; check if the users wanted to move the camera
     If LeftKey()  Then     MoveCamera Cam,-2,0
     If RightKey() Then     MoveCamera Cam,2,0
     If UpKey()    Then     MoveCamera Cam,0,-2
     If DownKey()  Then     MoveCamera Cam,0,2
     
     SetCursor 0,0
     Ink $ffffff
     Print "Press SPACE to toggle solid/outline"
     Print "Mouse Buttons To Change Size"
     Print "Method: "+Method$
     Sync
  Loop
  
  
  
  
  
;     -------------------------------------------------
;       ------>> Draw Polygon With Occlusion <<-------
;     -------------------------------------------------
  
  
Psub DRawQuad(ThisMap,ThisLevel,X,Y,Width,Height,Angle#,Method)
  
  
  vertx#(0)=(Width/-2.0)
  verty#(0)=(Height/-2.0)
  
  vertx#(1)=(Width/2.0)
  verty#(1)=(Height/-2.0)
  
  vertx#(2)=(Width/2.0)
  verty#(2)=(Height/2.0)
  
  vertx#(3)=(Width/-2.0)
  verty#(3)=(Height/2.0)
  
  ca#=Cos(angle#)
  sa#=Sin(angle#)
  
  For lp=0 To 3
     xpos#=     vertx#(lp)
     ypos#=     verty#(lp)
     vertx#(lp)=Floor(x+((ca#*xpos#)-(sa#*ypos#)))
     vertY#(lp)=Floor(y+((ca#*ypos#)+(sa#*xpos#)))
  Next
  
  
  
  
  CaptureDepth 5
  
  Select Method
      Case 0
          Collision=TriangleOccludeMap(ThisMap,ThisLevel,vertx#(0),vertY#(0),vertx#(1),vertY#(1),vertx#(2),vertY#(2) )
          Collision+=TriangleOccludeMap(ThisMap,ThisLevel,vertx#(0),vertY#(0),vertx#(2),vertY#(2),vertx#(3),vertY#(3) )
          Name$="TriangleOccludeMap"
      Case 1
          Collision=QuadOccludeMap(ThisMap,ThisLevel,vertx#(0),vertY#(0),vertx#(1),vertY#(1),vertx#(2),vertY#(2),vertx#(3),vertY#(3) )
          Name$="QuadOccludeMap"
          
  EndSelect
  
; draw the outline in lines
  Line vertx#(0),vertY#(0),vertx#(1),vertY#(1)
  Line vertx#(1),vertY#(1),vertx#(2),vertY#(2)
  Line vertx#(2),vertY#(2),vertx#(3),vertY#(3)
  Line vertx#(3),vertY#(3),vertx#(0),vertY#(0)
  
  
  If Method<1
     Line vertx#(0),vertY#(0),vertx#(2),vertY#(2)
  EndIf
  
EndPsub Collision,Name$
  
  
  
  
;     -------------------------------------------------
;      --------->> Build Random Map Scene <<---------
;     -------------------------------------------------
  
  
Function Build_Random_Map(BlockWidth,BlockHeight)
  
  BackdropColour=$008f00
  
  screen=NewFXImage(2400,1600)
  RenderToImage screen
  Cls  BackdropColour
  CircleC 800,400,400,true,$8f8f8f
  CircleC 1700,400,400,true,$0f8faf
  
  For lp=0 To 200
     x=Rnd(2400)
     y=Rnd(1600)
     rx=RndRange(50,150)
     ry=RndRange(10,50)
     EllipseC x,y,rx,ry,true, BackdropColour
  Next
  
  
  
  Map=NewMap(50)
  
; Create 1024 FX BLocks for this map
  CreateMapGFX  Map,BlockWidth,BlockHeight,1024,_
  BackdropColour,2
  
  BlocksX=GetSurfaceWidth()/BlockWidth
  BlocksY=GetSurfaceHeight()/BlockWidth
  
  Level=NewLevel(Map,BlocksX,BlocksY)
  LevelTransparent Map,Level,0
  GetMapBlk Map,Tile,0,0
  
  Tile=1
  For ylp=0 To GetLevelHeight(map,level)-1
     Ypos=ylp*BlockHeight
     If Ypos+BlockHeight<=GetSurfaceHeight()
        For xlp=0 To GetLevelWidth(map,level)-1
           Xpos=xlp*BlockWidth
           GetMapBlk Map,Tile,Xpos,ypos
           
           If GetMapBlockTransparent(Map,Tile)>-1
              PokeLevelTile Map,Level,xlp,ylp,tile
              tile++
           EndIf
           If Tile=>GetMapBlocks(Map)
              ExitFor ylp
           EndIf
        Next
     EndIf
  Next
  
  RenderToScreen
  
; Turn Debug Map for this map
  MapDebug Map,on
  
EndFunction Map,Level
  
  
  
  
  
 
Related Info: CircleOccludeMap | EllipseOccludeMap | RectOccludeMap | TriangleOccludeMap :
 


(c) Copyright 2002 - 2024 - Kevin Picone - PlayBASIC.com