Text above players' head: transparancy

Blitz3D Forums/Blitz3D Programming/Text above players' head: transparancy

Jeroen(Posted 2003) [#1]
	DeleteChatBalloonFromPlayer(whichPlayerIDSaidIt)

	b.chatBalloon = New chatBalloon
	b\timeToLive = timeToLive
	b\entity = LoadSprite("images/chatBalloon.tga",2,theParent)
	b\textEntity = CreateSprite(b\entity)
	b\net_id = whichPlayerIDSaidIt
	

	
	img = CreateImage(128,64)
	SetBuffer ImageBuffer (img)
	ClsColor 255,255,255
	Cls
	Color 0,0,0
	drawText(x2d,y2d,128,64,theText$,4,0)	
	MaskImage img,0,0,0
	b\texture = CreateTexture(128,64,4)
	SetBuffer TextureBuffer(b\texture)
	DrawImage img,0,0
	SetBuffer BackBuffer()
	EntityTexture b\textEntity,b\texture
	Color 255,255,255
	
	; tekst op ballon
	MoveEntity b\textEntity,1.3,1.1,2
	HandleSprite b\textentity,-1,-1
	ScaleSprite b\textEntity,6,2.5
	SpriteViewMode b\textEntity,1
	; ballon
	MoveEntity b\entity,0,1,0
	HandleSprite b\entity,-1,-1
	ScaleSprite b\entity,8,4
	SpriteViewMode b\entity,1



What the above does: create a balloon texture, and place text on a second texture.(it is written to a texture).

The problem: I want the background of the second texture (text) to be transparant. Only the text needs to be shown.
As you can see, I tried masking, but I still get an opaque background.

Anyone?

Thanks!


Stevie G(Posted 2003) [#2]
The problem with creating your textures on the fly is that the alpha channel is apparently set to 255. I had the same problem and the following worked for me. Just stick it in your code after you've created the masked texture.

For x = 0 To TextureHeight
For y = 0 To TextureWidth
WritePixel x,y,0
Next
Next


jfk EO-11110(Posted 2003) [#3]
You have some Bugs in there, better use:

setbuffer texturebuffer(tex)
lockbuffer
For y = 0 To TextureHeight(tex)-1
For x = 0 To TextureWidth(tex)-1
WritePixelfast x,y,0
Next
Next
unlockbuffer

where "tex" is your Texturehandle.


Jeroen(Posted 2003) [#4]
okay, I don't have Blitz on this computer, but these sound like good suggestions; thanks jfk and Stevie G.
I'll look up what Lockbuffer does, the WritePixelFast seems logical now I look at it, I didn't know 'bout the 255 color thing :-D


Jeroen(Posted 2003) [#5]
	; make a new texture, and make it all WHITE
	b\texture = CreateTexture(128,64,4)
	SetBuffer TextureBuffer(b\texture) 
	LockBuffer 
	For y = 0 To TextureHeight(b\texture)-1 
		For x = 0 To TextureWidth(b\texture)-1 
		WritePixelFast x,y,$FFFFFFFF 
		; above, completely white?
		Next 
	Next 
	UnlockBuffer
	
	; draw the image, and place black text on it
	img = CreateImage(128,64)
	SetBuffer ImageBuffer (img)
	Color 0,0,0
	drawText(x2d,y2d,128,64,theText$,4,0)	
	MaskImage img,255,255,255 
	
	; draw the image, go back to normal buffer, set textcolor to 255
	DrawImage img,0,0
	SetBuffer BackBuffer()
	EntityTexture b\textEntity,b\texture
	Color 255,255,255


I still have troubles, I can't see anything except the balloon ansich. I added comments in the code, because somewhere I'm making mistakes (masking?)


Who was John Galt?(Posted 2003) [#6]
Got the same prob myself. Gotta rush out but reckon you have to do something like create texture, then redraw it using;

readpixelfast
writepixelfast(readpixelvalue and $FFFFFF)

to cut off the alpha values


Perturbatio(Posted 2003) [#7]
Wouldn't it be easier to have a base texture already created which you then just make a copy of and add the text on top?

*EDIT*
Either that or if it must be created dynamically, couldn't you use the Rect command to fill it in black?


Gabriel(Posted 2003) [#8]
Wouldn't it be easier to have a base texture already created which you then just make a copy of and add the text on top?


Yup, I do that. I load a totally transparent .tga texture and then start drawing on it.


Who was John Galt?(Posted 2003) [#9]
Perturbatio- YES to your first point. I think the problem with just using drawing commands to blank the thing is that they just mod the rgb values not the alpha values that sit on them (I may be wrong on this). The blitz docs recommend creating your textures in a standard image bank <createimage> then copying this to a texture bank with copyrect- apparently it may be the fastest option. Not sure what alpha values u end up with doing this.


Who was John Galt?(Posted 2003) [#10]
Function do_mask(texture,maskr=0,maskg=0,maskb=0)
	maskcol=(maskr Shl 16)+(maskg Shl 8)+maskb
	LockBuffer TextureBuffer(texture)
	For x=0 To TextureWidth(texture)-1
		For y=0 To TextureWidth(texture)-1
			pix=ReadPixelFast(x,y)
			If (pix And $FFFFFF)=maskcol WritePixelFast x,y,(pix Or $FF000000) Else WritePixelFast x,y,0
		Next
	Next
	UnlockBuffer TextureBuffer(texture)
End Function


Another alternative -
create texture, draw to it, then send it to the above function specifying the (r,g,b) value you want to be c-thru
(defaults to black 0,0,0)


CyBeRGoth(Posted 2003) [#11]
Using the above code I got weird results, changing

 If (pix And $FFFFFF)=maskcol WritePixelFast x,y,(pix Or $FF000000) Else WritePixelFast x,y,0 
to
 If (pix And $FFFFFF)=maskcol WritePixelFast x,y,0 Else WritePixelFast x,y,(pix Or $FF000000) 


Fixed it right up :)
Good work 0DFEx!


Who was John Galt?(Posted 2003) [#12]
Jees- I let you in on a bit of info about alpha values, now you become the master! Maybe I should start testing stuff properly. Thanx John. : )


CyBeRGoth(Posted 2003) [#13]
Noticed something else I forgot to mention
The code below reads and writes from the texture buffer, before there was an error

Test your code 0DFEx :P

[Code]
Function do_mask(texture,maskr=0,maskg=0,maskb=0)
maskcol=(maskr Shl 16)+(maskg Shl 8)+maskb
LockBuffer TextureBuffer(texture)
For x=0 To TextureWidth(texture)-1
For y=0 To TextureHeight(texture)-1
pix=ReadPixelFast(x,y,TextureBuffer(Texture))
If (pix And $FFFFFF)=maskcol WritePixelFast x,y,0,TextureBuffer(Texture) Else WritePixelFast x,y,(pix Or $FF000000),TextureBuffer(Texture)
Next
Next
UnlockBuffer TextureBuffer(texture)
End Function

[/Code]


Jeroen(Posted 2003) [#14]
Hey that is a great function!
And very useful in future applications!

Still, I have some problems. I am now using the "CyBeRGoth" version of the do_mask function :)

	b\texture=CreateTexture(128,64,4)
	SetBuffer TextureBuffer(b\texture)
	ClsColor 0,0,0
	Cls
	Color 5,5,5
	drawText(5,5,128,64,theText$,4,0)	
	do_mask(b\texture,0,0,0)
	Color 255,255,255


second try:

	b\texture=CreateTexture(128,64,4)
	SetBuffer TextureBuffer(b\texture)
	Color 5,5,5
	Text 0,0,"HELLO"	
	do_mask(b\texture,0,0,0)
	Color 255,255,255


Okay: so I create a texture. I tried CreateTexture(128,64,2) and CreateTexture(128,64,4)
Then I say: clear the area with BLACKness (second try I removed it). Then draw text with color 5,5,5.
Then mask the texture (make 0,0,0 transparent)
(ofcourse, and then I texture the entity)

But...I see nothing. Nada :(
What am I doing wrong here?


CyBeRGoth(Posted 2003) [#15]
Maybe try adding this step
 TempText=CreateImage(128,64)

This creates an imagebuffer (make it the same size as your texture.

Then when you want to put your text it in
SetBuffer ImageBuffer(TempText)
Color 5,5,5
Text 0,0,"HELLO"	
CopyRect 1,0,128,64,0,0,ImageBuffer(TempText),TextureBuffer(b\texture)
do_mask(b\texture)


That should work

I Think there is just a problem if you try and do it straight to the texture buffer, but this way you are copying from the temp imagebuffer to the texturebuffer.


Jeroen(Posted 2003) [#16]
Wooooaaah that worked like a charm!!! Thanks.

Unfortunately it slows the game down (flicker)


CyBeRGoth(Posted 2003) [#17]
Cool :)

You should only have to update the texture whenever the text changes in your game, not every time the game loops


Jeroen(Posted 2003) [#18]
Yes, I do :-)
When the user presses [ENTER] the texture is created on the fly (a text balloon above the players' head)


Who was John Galt?(Posted 2003) [#19]
I think you need a different method to do it in your main loop. Copying buffers and even plain old text commands can really slow stuff down. Create a texture before your main loop with all the letters of the alphabet on it.To display your text create a load of quads (one per letter) in a single surface textured with your alphabet, and modify the uv co-ords of the quads to display your message. I'm sure someone out there will already have done something similar. Anyone?


Jeroen(Posted 2003) [#20]
hmmm that sounds like a hard solution :)


Slider(Posted 2003) [#21]
Guys,

I can't get it to work! What's wrong with the following:

Graphics3D 640,480 
SetBuffer BackBuffer() 

camera=CreateCamera() 

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

cube=CreateCube() 
PositionEntity cube,0,0,5 

;;;;;;;;;;;
    
TempText=CreateImage(256,256)
texture=CreateTexture(256,256,4)

SetBuffer ImageBuffer(TempText)
ClsColor 0,0,0
Cls
Color 250,0,0
Rect 10,10, 100,100, 1
Color 255,255,255
Text 0,0,"TESTING..."	
CopyRect 0,0,256,256,0,0,ImageBuffer(TempText),TextureBuffer(texture)
do_mask(texture, 0,0,0)

;;;;;;;;;;;

EntityTexture cube,texture

SetBuffer BackBuffer()

While Not KeyDown( 1 ) 

  pitch#=0 
  yaw#=0 
  roll#=0 

  If KeyDown( 208 )=True Then pitch#=-1 
  If KeyDown( 200 )=True Then pitch#=1 
  If KeyDown( 203 )=True Then yaw#=-1 
  If KeyDown( 205 )=True Then yaw#=1 
  If KeyDown( 45 )=True Then roll#=-1 
  If KeyDown( 44 )=True Then roll#=1 

  TurnEntity cube,pitch#,yaw#,roll# 

  RenderWorld 
  Flip 

Wend 

End


Function do_mask(texture,maskr=0,maskg=0,maskb=0)
	maskcol=(maskr Shl 16)+(maskg Shl 8)+maskb
	LockBuffer TextureBuffer(texture)
	For x=0 To TextureWidth(texture)-1
		For y=0 To TextureHeight(texture)-1
			pix=ReadPixelFast(x,y,TextureBuffer(Texture))
			If (pix And $FFFFFF)=maskcol WritePixelFast x,y,0,TextureBuffer(Texture) Else WritePixelFast x,y,(pix Or $FF000000),TextureBuffer(Texture)
		Next
	Next
	UnlockBuffer TextureBuffer(texture)
End Function



Slider(Posted 2003) [#22]
The code inbetween the ;;;;;;;;; sections is the actual texture based stuff. Any help will do!?!

Why isn't the cube transparent? I want to see all 6 of the sides!


Paolo(Posted 2003) [#23]
It works this way,
do you need the texture to be masked? because that's the problem, if you use flags 1+2 then there is no problem, this way you don't even need the "do_mask()" function, I think :)

test this:


Graphics3D 640,480 

camera=CreateCamera() 
	CameraClsColor camera,50,50,50

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

cube=CreateCube() 
	PositionEntity cube,0,0,3
	EntityFX cube,1+16

;;;;;;;;;;;
texture=CreateTexture(256,256,1+2)

ClsColor 0,0,0
Cls
	For r=1 To 10
	Color Rand(100,255),Rand(100,255),Rand(100,255)
	Rect Rand(10,64),Rand(10,64),Rand(20,100),Rand(20,100),False
	Next

Color 255,255,255
	For t=1 To 20
	Text Rand(10,200),Rand(10,200),"TESTING..."	
	Next
	
CopyRect 0,0,256,256,0,0,BackBuffer(),TextureBuffer(texture)
;;;;;;;;;;;

EntityTexture cube,texture


While Not KeyDown( 1 ) 

  pitch#=0 
  yaw#=0 
  roll#=0 

  If KeyDown( 208 )=True Then pitch#=-1 
  If KeyDown( 200 )=True Then pitch#=1 
  If KeyDown( 203 )=True Then yaw#=-1 
  If KeyDown( 205 )=True Then yaw#=1 
  If KeyDown( 45 )=True Then roll#=-1 
  If KeyDown( 44 )=True Then roll#=1 

  TurnEntity cube,pitch#,yaw#,roll# 

  RenderWorld 
  Flip 

Wend 

End




Slider(Posted 2003) [#24]
Sorry, but the above code doesn't work! Any other suggestions?


Who was John Galt?(Posted 2003) [#25]
JPJones- your code worked, there was just nothing behind the object to see thru 2.

Try putting this before your 'Setbuffer backbuffer()' line:
EntityFX cube,16


Slider(Posted 2003) [#26]
0DFEx: Thanks!!!