News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Z-Sorting among sprites

Started by Draco9898, August 08, 2005, 06:04:05 PM

Previous topic - Next topic

Draco9898

In my game, I need sprites to be drawn in a certain order or else it looks very weird, but there are some issues...

Acording to the CaptureDepth rules, the item with the lowest  CaptureDepth number should be drawn before anything, no matter what...When drawing lots of sprites to the screen, however, this is CLEARLY not the case...

Update:
Not sure if this is broken or not considering I just found the DrawOrderedSprites command...Might be because what if you don't want to draw all the sprites? X_X

PlayBASIC Code: [Select]
Dim MyImage(20) 
For X=1 To 20
MyImage(X)=GetFreeImage(): CreateImage MyImage(X),40,40
RenderToImage MyImage(X)
BoxC 0,0,50,50,1,RndRGB()
RenderToScreen
Next X


Dim MYSprite(20)
For X=1 To 20
MYSprite(X)=GetFreeSprite(): CreateSprite MYSprite(X)
SpriteImage MYSprite(X),MYImage(X)
PositionSprite MYSprite(X),190+(10*X),10*X
Next X

CreateCamera 1
CameraClsColour 1,RGB(1,20,6)
CameraCls 1, 1

CaptureToScene: ClsScene

`THE TOP BOX SHOULD BE THE LAST Z-SORTED BOX because lowest numbers draw first....
`(Works, this is only images)
For X=1 To 20
CaptureDepth 20-X
DrawImage MYImage(X),190+(10*X),10*X,1
Next x
DrawCamera 1: Sync: WaitKey

Wait 1000

`This doesn't work, sprite based...
CaptureToScene: ClsScene
For X=1 To 20
CaptureDepth 20-X
DrawSprite MYSprite(X)
Next x
DrawCamera 1: Sync: WaitKey

Wait 1000

`This does work, but what if I don't wish to draw all sprites?
CaptureToScene: ClsScene
For X=1 To 20
CaptureDepth 20-X
DrawOrderedSprites
Next x
DrawCamera 1: Sync: WaitKey





Also, another issue, Why doesn't the 5th box in this code get drawn over every other box? (Even WITH DrawOrderedSprites!) I'm probably missing something here that makes this work, but ehhhh what would you do to update a sprites Z-depth without drawing it first?


PlayBASIC Code: [Select]
Dim MyImage(20) 
For X=1 To 20
MyImage(X)=GetFreeImage(): CreateImage MyImage(X),40,40
RenderToImage MyImage(X)
If X=5
BoxC 0,0,50,50,1,RGB(255,0,0)
Else
BoxC 0,0,50,50,1,RGB(255-x,255-x,255-x)
EndIf
RenderToScreen
Next X


Dim MYSprite(20)
For X=1 To 20
MYSprite(X)=GetFreeSprite(): CreateSprite MYSprite(X)
SpriteImage MYSprite(X),MYImage(X)
PositionSprite MYSprite(X),190+(10*X),10*X
Next X

CreateCamera 1
CameraClsColour 1,RGB(1,20,6)
CameraCls 1, 1

CaptureToScene: ClsScene

`Why can't I get the 5th box to show over everything?
CaptureToScene: ClsScene
For X=1 To 20
If X=5
CaptureDepth 1
Else
CaptureDepth 2
EndIf
DrawOrderedSprites
Next X
DrawCamera 1: Sync: WaitKey

Wait 1000

`This is what I needed.....
CaptureToScene: ClsScene
For X=1 To 20
If X=5
CaptureDepth 1
Else
CaptureDepth 3
EndIf
DrawImage MYImage(X),190+(10*X),10*X,1
Next x
DrawCamera 1: Sync: WaitKey



DualCore Intel Core 2 processor @ 2.3 ghz, Geforce 8600 GT (latest forceware drivers), 2 gigs of ram, WIN XP home edition sp2, FireFox 2.

"You'll no doubt be horrified to discover that PlayBasic is a Programming Language." -Kevin

kevin

#1
QuoteUpdate:
Not sure if this is broken or not considering I just found the DrawOrderedSprites command...Might be because what if you don't want to draw all the sprites? X_X

DrawOrderedSprites sorts upon the sprites internal Z position, then draws the set to the screen (or whatever the current surface is).   You can't affect this via changing the camera/scene setting.  There's two different solutions.  

 If you need to draw a set range of sprites, there's DrawSpriteRange, although i'm not sure if that supports capturing internally off the top of my. It may, it may not.

 if not, for the time being you'll have to draw the sprites solo (to the scene buffer).  Make sure you set their depth before capturing though.

There's various versions of positionSprite for positioning in space

PositionSprite  spriteindex,x,y
PositionSpriteX  spriteindex,x
PositionSpriteY  spriteindex,y
PositionSpriteZ  spriteindex,z
PositionSpriteXYZ  spriteindex,x,y,z    ; This one is prolly what you should be using


   
Example #1
PlayBASIC Code: [Select]
Dim MyImage(20)
For X=1 To 20
MyImage(X)=GetFreeImage(): CreateImage MyImage(X),40,40
RenderToImage MyImage(X)
BoxC 0,0,50,50,1,RndRGB()
RenderToScreen
Next X


Dim MYSprite(20)
For X=1 To 20
MYSprite(X)=GetFreeSprite(): CreateSprite MYSprite(X)
SpriteImage MYSprite(X),MYImage(X)
PositionSprite MYSprite(X),190+(10*X),10*X
Next X

CreateCamera 1
CameraClsColour 1,RGB(1,20,6)
CameraCls 1, 1

CaptureToScene: ClsScene

`THE TOP BOX SHOULD BE THE LAST Z-SORTED BOX because lowest numbers draw first....
`(Works, this is only images)
For X=1 To 20
CaptureDepth 20-X
DrawImage MYImage(X),190+(10*X),10*X,1
Next x
DrawCamera 1: Sync: WaitKey

Wait 1000

`This doesn't work, sprite based...
CaptureToScene: ClsScene
For X=1 To 20
;CaptureDepth 20-X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
PositionSpriteZ x,20-x
; you haven't set the Sprites Depth. Although Capture prolly should offset
; the draw sprite command also..
DrawSprite MYSprite(X)
Next x
DrawCamera 1: Sync: WaitKey

Wait 1000

` This does work, but what if I don't wish to draw all sprites?

; no, the loop doesn't really make any sense. As it's drawing and sorting
; ALL the sprites 20 times to the screen..

; The DrawAllSprites, DRawOrderedSprites commands draw the entire sprite list

; DrawAllSprites - Draws the sprites based upon their creation order
; DrawOrderedSprites - First pre-sorted the sprites on Z, then draws the list.
;

;CaptureToScene: ClsScene
;For X=1 To 20
;CaptureDepth 20-X
DrawOrderedSprites
;Next x
;DrawCamera 1:
Sync: WaitKey








QuoteAlso, another issue, Why doesn't the 5th box in this code get drawn over every other box? (Even WITH DrawOrderedSprites!) I'm probably missing something here that makes this work, but ehhhh what would you do to update a sprites Z-depth without drawing it first?

You haven't set the sprites Z Depth.    





Example #2

PlayBASIC Code: [Select]
Dim MyImage(20)
For X=1 To 20
MyImage(X)=GetFreeImage(): CreateImage MyImage(X),40,40
RenderToImage MyImage(X)
If X=5
BoxC 0,0,50,50,1,RGB(255,0,0)
Else
BoxC 0,0,50,50,1,RGB(255-x,255-x,255-x)
EndIf
RenderToScreen
Next X


Dim MYSprite(20)
For X=1 To 20
MYSprite(X)=GetFreeSprite(): CreateSprite MYSprite(X)
SpriteImage MYSprite(X),MYImage(X)
PositionSprite MYSprite(X),190+(10*X),10*X


; Your not Setting the Sprites Z Depth
If X=5
POsitionSpriteZ x,1
Else
POsitionSpriteZ x,2
EndIf



Next X

CreateCamera 1
CameraClsColour 1,RGB(1,20,6)
CameraCls 1, 1


;

;CaptureToScene: ClsScene

`Why can't I get the 5th box to show over everything?

;CaptureToScene: ClsScene
;For X=1 To 20
;If X=5
; CaptureDepth 1
;Else
; CaptureDepth 2
;EndIf
; DrawOrderedSprites
;Next X
;DrawCamera 1: Sync: WaitKey


; Drawing order sprites doesn't need a camera
DrawOrderedSprites


sync
waitkey
waitnokey

`This is what I needed.....
CaptureToScene: ClsScene
For X=1 To 20
If X=5
CaptureDepth 1
Else
CaptureDepth 3
EndIf
DrawImage MYImage(X),190+(10*X),10*X,1
Next x
DrawCamera 1: Sync: WaitKey







Draco9898

I see, I see, I didn't know there was a set sprite pos Z, my bad :)
DualCore Intel Core 2 processor @ 2.3 ghz, Geforce 8600 GT (latest forceware drivers), 2 gigs of ram, WIN XP home edition sp2, FireFox 2.

"You'll no doubt be horrified to discover that PlayBasic is a Programming Language." -Kevin