Sprite Masking problem

Blitz3D Forums/Blitz3D Programming/Sprite Masking problem

To Ross C (or anybody else who can help):

I tried implementing your algorithms from the link above, and they work, though I have a couple of questions:

1. Is it necessary to call prepare_texture() in this case, or is it unneccessary since no alpha information exists anyway?

2. Although the label is now properly transparent (woo hoo!) it's still shrunk to half its required size... This is odd, because it's the correct size when the texture mode is 48, and it shrinks when I use mode 52 to get masking. Any ideas what might be causing this?

Here's the new code, with your functions in place:

---

; This value is the oddball... I need Clamp U and Clamp V flags turned on, so it should be 16+32=48.
; When I turn on masking (4) and use a value of 52, it halves my text and adds a black box.

Global mode = 52 ; switch this between 48 and 52

Global camera_obj
Global light_obj
Global sphere_obj
Global sprite_obj
Global sphere2_obj

Global rot

Global scrap



; initialize graphics modes

Graphics3D maxx, maxy, 16, 1
SetBuffer BackBuffer()



; define camera and light

camera_obj = CreateCamera()
PositionEntity camera_obj, 0, 0, -10

light = CreateLight()
RotateEntity light, 45, 45, 0


; define spheres

sphere_obj = CreateSphere()

sphere2_obj = CreateSphere()
PositionEntity sphere2_obj, -1, -1.5, 5


; draw sphere's label on screen and copy it into texture
; define the label as being 256 pixels across and 32 down

scrap = CreateTexture (256, 32, mode)


; draw the text on this label, then use copyrect to put it in the texture buffer

Cls
Text 128, 0, "This is a sphere", 1
CopyRect 0, 0, 256, 32, 0, 0, BackBuffer(), TextureBuffer(scrap)


; create label sprite and texture it with "scrap"

label_obj = CreateSprite()
PositionEntity label_obj, 0, -1.5, 0
ScaleSprite label_obj, 4, 0.5
EntityTexture label_obj, scrap

; apply Ross C's function
prepare_texture(scrap)
texture_mask_colour(scrap, 0, 0, 0)


; draw the world

While Not KeyHit(1)

PositionEntity camera_obj, 0, 0, 0
RotateEntity camera_obj, 0, rot, 0
MoveEntity camera_obj, 0, 0, -10

RenderWorld()
Flip

If KeyDown(203) Then
rot = (rot-2) Mod 360
End If
If KeyDown(205) Then
rot = (rot+2) Mod 360
End If

Wend

;--------------------------------------------------------------------
; PREPARE_TEXTURE() created by Ross C |
; This function will clear a texture of all it's alpha information |
;--------------------------------------------------------------------
;parameters = texture : the texture you wish to clear alpha information from

Function prepare_texture(texture)

LockBuffer TextureBuffer(texture)

For loop=0 To TextureWidth(texture)
For loop1=0 To TextureHeight(texture)

RGB1=ReadPixelFast(loop,loop1,TextureBuffer(texture))
r=(RGB1 And $FF0000)Shr 16;separate out the red
g=(RGB1 And $FF00) Shr 8;green
b=RGB1 And $FF;and blue parts of the color
a=(RGB1 And $FF000000)Shr 24

a=255; remove any alpha information currently in the texture.

newrgb= (a Shl 24) Or (r Shl 16) Or (g Shl 8) Or b; combine the ARGB back into a number

WritePixelFast(loop,loop1,newrgb,TextureBuffer(texture)); write the info back to the texture
Next
Next

UnlockBuffer TextureBuffer(texture)

End Function


;---------------------------------------------------------------------
; TEXTURE_MASK_COLOUR created by Ross C |
; This function will mask the passed across RGB of the texture also |
; passed across. Do NOT pass across a value for flag if you only |
; want to mask an exact colour. |
;---------------------------------------------------------------------
;parameters = texture : the texture you wish to clear alpha information from
; = r1 : the red value to mask
; = g1 : the green value to mask
; = b1 : the blue value to mask
; = tolerance : the tolerance value. If set to 0, then the function will only mask the
; EXACT colours passed across. Higher value will mask values close to the colour.

Function texture_mask_colour(texture,r1,g1,b1,tolerance=0)


LockBuffer TextureBuffer(texture)

For loop=0 To TextureWidth(texture)
For loop1=0 To TextureHeight(texture)
RGB1=ReadPixelFast(loop,loop1,TextureBuffer(texture)) ; read the RGB value from the texture
r=(RGB1 And $FF0000)Shr 16;separate out the red
g=(RGB1 And $FF00) Shr 8;green
b=RGB1 And $FF;and blue parts of the color
a=(RGB1 And $FF000000)Shr 24 ; extract the alpha

If r>=r1-tolerance And r=<r1+tolerance And g=>g1-tolerance And g=<g1+tolerance And b=>b1-tolerance And b=<b1+tolerance Then; check RGB lies with the tolerance
;temp=((Abs(r-r1)+Abs(g-g1)+Abs(b-b1))/3.0)*4.0 ; alpha the values based on the tolerance value
a=0;temp

End If

newrgb= (a Shl 24) Or (r Shl 16) Or (g Shl 8) Or b ; combine the ARGB back into one value

WritePixelFast(loop,loop1,newrgb,TextureBuffer(texture)); write back to the texture
Next
Next
UnlockBuffer TextureBuffer(texture)

End Function