3D Sprites - any gotchas?

Blitz3D Forums/Blitz3D Beginners Area/3D Sprites - any gotchas?

Jazz(Posted 2007) [#1]
Currently I'm just testing out a few bits and pieces to see if I can do what I want with the 3D sprites side of Blitz3D. To start with I used some code from the Code Archives to get it up and running. Anyway I seem to have hit a snag. I've created a square mesh which I intend to use as a background, coloured it red and placed it behind my sprite. However the sprite seems to blend with the red mesh as if alpha is set on the sprite (although it shouldn't be, and isn't as far as I can see). So it's a good bet I've done something to the original code that I shouldn't have. :) Please forgive the mess, this is just a test and an attempt to get it straight in my head as to how Blitz3D does certain things. I also apologise in advance to the guy I borrowed the code from and mangled.

Global WIDTH = 600
Global HEIGHT = 600
Global halfWIDTH = WIDTH/2
Global halfHEIGHT = HEIGHT/2

; Seed the random number generator
SeedRnd(MilliSecs())

; Program start
Graphics3D WIDTH,HEIGHT,16,2
;SetBuffer BackBuffer()

; Create and set camera
camera = CreateCamera()
camzoom#=1.0 ; this is default. Other values work as well.
CameraZoom camera,camzoom#
CameraRange camera,1,(halfWIDTH * camzoom#)+1000

; Starfield settings
Global StarsMinSpeed = 1
Global StarsMaxSpeed = 8
Global StarsTotal = 400
; Starfield data
Type StarData
Field X#
Field Y#
Field Speed#
Field Colour
End Type
Dim Starfield.StarData(StarsTotal)

; Load and setup our sprite
sprite=LoadSprite("PS1.bmp")
; if you want the sprite to be 48*48 Pixels:
ScaleSprite sprite,48/2,48/2
x# = 300
y# = 300

; Set the sprite start angle
ang#=90

; Initialise the starfield
InitStarField(StarsTotal,StarsMinSpeed,StarsMaxSpeed)
; Create test brush
brush = CreateBrush()
BrushColor brush,255,0,0
; Create a blank empty mesh
buffer = CreateMesh()
; Create blank surface which is attached to mesh
surface = CreateSurface(buffer,brush)
; Give the mesh and surface a shape - it's just a square
v0 = AddVertex(surface,-200,200,0)
v1 = AddVertex(surface,200,200,0)
v2 = AddVertex(surface,200,-200,0)
v3 = AddVertex(surface,-200,-200,0)
; Now add triangles to make it solid and visible
t0 = AddTriangle(surface,v0,v1,v2)
t1 = AddTriangle(surface,v0,v2,v3)
UpdateNormals buffer

; Set initial facing of player ship
RotateSprite sprite,ang
;EntityOrder sprite,-1
;EntityAlpha sprite,1

; Main loop
While KeyDown(1)=0
; Draw our red box which will become our background
PositionEntity buffer,x-halfWIDTH,halfHEIGHT-y,halfWIDTH * camzoom# + 50

; Draw the players ship
PositionEntity sprite,x-halfWIDTH,halfHEIGHT-y,halfWIDTH * camzoom#

; Turn left
If KeyDown(203)
ang = ang + 3
RotateSprite sprite,ang
; Turn right
ElseIf KeyDown(205)
ang = ang - 3
RotateSprite sprite,ang
EndIf

; Roll the angle value around
If ang < 0
ang = 360 + ang
ElseIf ang > 359
ang = ang - 360
EndIf

UpdateWorld
RenderWorld
; Draw starfield
; 2D commands should be drawn after updateworld/renderworld but before flip
DrawStarField(ang)
Flip
Wend
EndGraphics
End

; Initalise starfield
Function InitStarField(amount,min,max)
; Set starfield to initial values
For i = 0 To amount
; Initialise entry in array
Starfield.StarData(i) = New StarData
; Set fields in entry
Starfield(i)\X = Rand(0,GraphicsWidth())
Starfield(i)\Y = Rand(0,GraphicsHeight())
Starfield(i)\Speed = Rand(min,max)
; We want grey scale without having stars too dark to see.
; So we force the colour range into the 61 - 255 bracket.
c = Rand(60,195)
; Convert from RGB into argb for writepixel etc. and store in array
Starfield(i)\Colour = (c Or (c Shl 8) Or (c Shl 16) Or ($ff000000))
Next
End Function

; Starfield display routine
Function DrawStarField(direction#)
; We lock the screen buffer for drawing, to speed it all up
LockBuffer
; Update starfield array
For i = 0 To StarsTotal
; Move the star in the given direction and the given speed
X# = (Starfield(i)\X) - (Starfield(i)\Speed * Cos(direction))
Y# = (Starfield(i)\Y) + (Starfield(i)\Speed * Sin(direction))

; If star has moved off screen, relocate it
If X < 0
X = GraphicsWidth()
Y = Rand(0,GraphicsHeight())
ElseIf X >= GraphicsWidth()
X = 0
Y = Rand(0,GraphicsHeight())
EndIf
If Y < 0
Y = GraphicsHeight()
X = Rand(0,GraphicsWidth())
ElseIf Y >= GraphicsHeight()
Y = 0
X = Rand(0,GraphicsWidth())
EndIf

; Draw the star
WritePixelFast X,Y,Starfield(i)\Colour
; Update the starfield entry
Starfield(i)\X = X
Starfield(i)\Y = Y
Next
UnlockBuffer
End Function


thelizardking(Posted 2007) [#2]
well the default sprite loading is where black is totally transparent, white is totally visible, and the alpha is adjusted for each color in between. what you can do is do LoadSprite("PS1.bmp",4) which just sets black as transparent.


Jazz(Posted 2007) [#3]
Ok thanks, you hit the nail on the head. That's what was going on. Now I just have to clean the image up so that having black as transparent doesn't uglify it completely. :)


Dreamora(Posted 2007) [#4]
that or load it with flag 2 instead of flag 4