names of characters over there heads

Blitz3D Forums/Blitz3D Beginners Area/names of characters over there heads

how do I put the names of my network players over their heads..

is this some form of cameraproject?

I needed to know the same question. I still dont know but some people tried to help me. Heres a link: :)
(click on smile)

hi

yes basically use the concept on the camera project example.
The text apears centered but if you wish to be on top only adjust the Y component adding 1/2 of the object height or slightly more than that.

Probably you could adjust the size of the text based on the distance from the camera to make it smaller/bigger..

Juan

You could use a sprite and parent it to the character. Apply a texture with the name on it to the sprite.

To put in a name to a blitz created texture or a loaded texture, do this...
SetBuffer TextureBuffer(texture)

Text TextureWidth()/2,TextureHeight()/2,Name$

SetBuffer BackBuffer()


There's a great snippet of Code in the Archives (I think it's called Labels or similar) that does this via CameraProjectMode

CameraProjectMode only changes the camera from either Perspective, Orthographic, and Off. I think you're talking about CameraProject.

Yeah whatever :P

It's beemn a while, that's why I wasnt able to post the thing itself, but yes... it must have been CameraProject and ProjectedX / Y etc. :D
Thanks, Green Fire

ok it seems to be working...the only issue I have is that I want to know how to make it only show their names if you are close to their proximity...

hi again
as i suggested previously:

"Probably you could adjust the size of the text based on the distance from the camera to make it smaller/bigger.."

well not smaller/bigger if you prefer make it appear/dissapear.

use EntityDistance

Juan

Text is dog slow and mixing it with 3d is an issue on some cards. Resizing the text based on distance to the camera is just plain silly.

Use a sprite parented to the player and positioned above their heads with the name written on a texture - simple.

ok it seems to be working...the only issue I have is that I want to know how to make it only show their names if you are close to their proximity...


Use EntityDistance(), with something like:

If EntityDistance(Player\Entity,MainCamera) < 10
    Text ProjectedX(),ProjectedY(),Player\Name
EndIf

That's just a really rough example; obviously I have no idea how your code is arranged.

I totally agree with Stevie G, though; don't use Text(). It's slow. (Dog slow? Not all dogs are slow... ;D) Use sprites, since it'll also take care of the resizing-with-distance problem.

ok someone help me with this sprite thing..i created a sprite above their head....i finally scaled it down but I dont know how to place their name on the texture...

help please?

Like I said

Replace Name$ with the name
Replace texture with the texture
SetBuffer TextureBuffer(texture)

Text TextureWidth(texture)/2,TextureHeight(texture)/2,Name$

SetBuffer BackBuffer()


so i need to create a texture first?

Yea you can but you can probably use a loaded texture too. Creating a texture isn't that difficult/complex.

Name$ = Turds
Texture = CreateTexture(32,16)

SetBuffer TextureBuffer(Texture)
Text TextureWidth(Texture)/2,TextureHeight(Texture)/2,Name$
SetBuffer BackBuffer()


You'll have to change the size of the texture or the font to keep the words inside.

@ GIA_green_fire

I wouldnt recommend using text on a texture. blitz seems to have issues with writing text to textures via the text command :p go figure. sometimes it works sometimes it doesnt

I've heard about the Setbuffer Texturebuffer() method giving trouble on some systems. It might be what Nate is describing, maybe there are more similair issues. Never personally encountered them.
So instead of using SetBuffer TextureBuffer, you could better use CopyRect when you want to draw something onto a texture:
tex = createtexture(32, 16)
cls
text 0, 0, "fred"
copyrect 0, 0, 32, 16, 0, 0, backbuffer(), texturebuffer(tex)


Good point about 2D being slow, so if you go with the 3D sprite idea, then use :

EntityAlpha Sprite,(EntityDistance#(Camera,ParentCharacter)<Range#)


another thing worth being mentioned... blitz 1.99 has extemely slow sprites so make your own simple sprite system if you must use 1.99 If not then use 1.64 :)

The text on textures has never been a problem for me. I've used it in my Gorilla Map Editor and another program and it works just fine, never any problems at all, it appears the way it should. You might just have to give the texture a background color and the text a different color first though.

whats the best way to make it where you can only see the name, with a texture or is that not possible?

Use nsprite2 it is as simple as the following:



cameraproject camera,entityx(creatureentity),entityy(creatureentity)+creatureheight,entityz(creatureentity)

if projectedz() > 0 and projectedx()>=0 and projectedy()>=0 and projectedx()<=graphicswidth() and projectedy()<=graphicsheight() then 

ns_text projectedx(),projectedy(),creaturename$

endif 



ns_text is a command in the nsprite2 library.

What you are after is very easy to do.

here ya go..

Function LabelEntity (camera, entity, label$)
If EntityInView (entity, camera)
CameraProject camera, EntityX (entity), EntityY (entity), EntityZ (entity)
w = StringWidth (label$)
h = StringHeight (label$)
x = ProjectedX () - (w / 2) - 1
y = ProjectedY () - (h / 2) - 1
Color 0, 0, 0
Rect x, y, w + 2, h + 2, 1
Color 255, 255, 255
Text x, y, label$
EndIf
End Function

just put LabelEntity after renderworld and before flip as you doing with text command...enjoy..

I tried to make a simple example of how to do the name on texture thing and guess what, it didn't work, and I'm not completely sure why. I think it might have something to do with me not using sprites and using quads instead. I'll try to make an example using those soon.

Edit:
Here's the example, there's a sprite and a quad, both work.
One problem, the color for the shadow text for some reason turns black even if you put 255,255,255 so I had to put 254 for red.

Edit2: In the example I forgot to mention that the reason why nothing was showing, was because I tried using the flags 2 and 4, not at the same time though, but they made the texture totally disappear.

InitGraphics(800,600)

Global Light = CreateLight()
	
Global Camera = CreateCamera()
	PositionEntity Camera,0,2,-5
	RotateEntity Camera,20,0,0

Global Plane = CreatePlane()
	
Global Name$ = "GIA"

Global TurnPivot = CreatePivot()

Global Player = CreateCube(TurnPivot)
	PositionEntity Player,0,1,3
	ScaleEntity Player,.5,.5,.5
	EntityColor Player,255,0,0
	


Global Sprite = CreateSprite()
	ScaleSprite Sprite,.5,.25

Global Sprite2 = CreateQuad(.5,.25,0)
	ScaleMesh Sprite2,-1,1,1
	
Global SpriteTexture = CreateNameTexture(Name,1+16+32)
	EntityTexture Sprite,SpriteTexture
	EntityTexture Sprite2,SpriteTexture

EntityParent Sprite,Player
PositionEntity Sprite,1,MeshHeight(Player)/2+.5,0

EntityParent Sprite2,Player
PositionEntity Sprite2,-1,MeshHeight(Player)/2+.5,0

While Not KeyDown(1)
	
	If KeyDown(200) TranslateEntity Camera,0,0,.1
	If KeyDown(208) TranslateEntity Camera,0,0,-.1
	If KeyDown(203) TranslateEntity Camera,-.1,0,0
	If KeyDown(205) TranslateEntity Camera,.1,0,0
	
	TurnEntity TurnPivot,0,1,0
	TurnEntity Sprite2,0,DeltaYaw(Sprite2,Camera)*.8,0
	
	UpdateWorld
	RenderWorld
	
	Flip
	
Wend
End

Function ShadowText(value$,x#,y#,red%=255,green%=255,blue%=255,shadow_red=20,shadow_green=20,shadow_blue=20,center_x=1,center_y=1)
	Color shadow_red,shadow_green,shadow_blue
	Text x+1,y,value,center_x,center_y
	Text x,y+1,value,center_x,center_y
	Text x+1,y+1,value,center_x,center_y
	
	Color red,green,blue
	Text x,y,value,center_x,center_y
End Function

Function InitGraphics(w = 1024, h = 768,title$="Blitz3D Program",exit_message$="")
	Graphics3D w, h, 32, 2
	SetBuffer BackBuffer()
	SeedRnd MilliSecs()
	
	If exit_message <> ""
		AppTitle title,exit_message
			Else
				AppTitle title
	EndIf
End Function

Function CreateNameTexture(name$,flags)
	Local Width% = StringWidth(name)*2
	Local Height% = StringHeight(name)*2
	Local texture = CreateTexture(Width,Height,flags)
	
	SetBuffer TextureBuffer(texture)
		Color 0,255,0
		Rect 0,0,TextureWidth(texture),TextureHeight(texture)*.1
		Rect 0,TextureHeight(texture)*.9,TextureWidth(texture),TextureHeight(texture)*.1
		
		Color 255,255,255
		ShadowText(name,TextureWidth(texture)*.5,TextureHeight(texture)*.5,254)
	SetBuffer BackBuffer()
	
	Return texture
End Function

Function CreateQuad(width#,height#,order%=-1,parent%=False)
	Local v0,v1,v2,v3
	Local Point,Surface
	
	If Not parent = False
		Point = CreateMesh(parent)
			Else
				Point = CreateMesh()
	EndIf
	
	If order <> 0
		EntityOrder Point,order
	EndIf
	
	EntityFX Point,1
	
	Surface = CreateSurface(Point)
	
	v0=AddVertex(Surface,-(width*.5),(height*.5),0 ,0,0)
	v1=AddVertex(Surface,(width*.5),(height*.5),0 ,1,0)
	v2=AddVertex(Surface,-(width*.5),-(height*.5),0 ,0,1)
	v3=AddVertex(Surface,(width*.5),-(height*.5),0 ,1,1)
	
	AddTriangle(Surface,v0,v1,v2)
	AddTriangle(Surface,v1,v3,v2)
	
	Return Point
End Function


Masked textures don't work when you use createtexture unless you put that texture through a masking function.

This is what I use - I'm sure I got it from the code archives ..

Function TEXTUREmask( texture , sr=240 , sg=0 , sb=240, st = 30 )

	TW = TextureWidth( texture )
	TH = TextureHeight( texture )
	SetBuffer TextureBuffer( texture )
	LockBuffer 
	For j = 0 To TH- 1
		For i = 0 To TW - 1
			argb = ReadPixelFast( i,j, TextureBuffer( texture ) )
			r = ( argb And $FF0000) Shr 16
			g = ( argb And $FF00 ) Shr 8  
			b = ( argb And $FF )  
			a = ( argb And $FF000000 ) Shr 24
			
			If ( r > sr-st And r < sr+st ) And  ( g > sg-st And g < sg+st ) And ( b > sb-st And b < sb+st )
				a = 0 
				r = 0
				g = 0
				b = 0
			Else
				a = 255
			EndIf
			argb = ( a Shl 24 ) Or ( r Shl 16 ) Or ( g Shl 8 ) Or b	
			WritePixelFast i , j , argb, TextureBuffer( texture )
		Next
	Next			
	UnlockBuffer
	SetBuffer BackBuffer()
		
End Function


I got one in my code archive entries too, if needed. Remember, texture don't use a mask colour like images do. It's the alpha value in each texel/pixel that matters on the texture.

:| I tried doing the two For.. Next loops to write the pixels before but when I did it, I didn't lock the buffers so maybe that's why it didn't work. I changed your masker to make it do exactly what I want, probably faster.

It just fills the texture before you add anything else to it. For some odd reason the text won't show up though but the two rects do.

TextureMaskFill Function
Function TextureMaskFill( texture )
	TW = TextureWidth( texture )
	TH = TextureHeight( texture )
	SetBuffer TextureBuffer( texture )
	LockBuffer 
	For j = 0 To TH - 1
		For i = 0 To TW - 1
			WritePixelFast i , j , 0, TextureBuffer( texture )
		Next
	Next
	UnlockBuffer
	SetBuffer BackBuffer()
End Function


Example
InitGraphics(800,600)

Global Light = CreateLight()
	
Global Camera = CreateCamera()
	PositionEntity Camera,0,2,-5
	RotateEntity Camera,20,0,0

Global Plane = CreatePlane()
	
Global Name$ = "GIA"

Global TurnPivot = CreatePivot()

Global Player = CreateCube(TurnPivot)
	PositionEntity Player,0,1,3
	ScaleEntity Player,.5,.5,.5
	EntityColor Player,255,0,0
	


Global Sprite = CreateSprite()
	ScaleSprite Sprite,.5,.25

Global Sprite2 = CreateQuad(.5,.25,0)
	ScaleMesh Sprite2,-1,1,1
	
Global SpriteTexture = CreateNameTexture(Name,1+2+16+32)
	EntityTexture Sprite,SpriteTexture
	EntityTexture Sprite2,SpriteTexture

EntityParent Sprite,Player
PositionEntity Sprite,1,MeshHeight(Player)/2+.5,0

EntityParent Sprite2,Player
PositionEntity Sprite2,-1,MeshHeight(Player)/2+.5,0

While Not KeyDown(1)
	
	If KeyDown(200) TranslateEntity Camera,0,0,.1
	If KeyDown(208) TranslateEntity Camera,0,0,-.1
	If KeyDown(203) TranslateEntity Camera,-.1,0,0
	If KeyDown(205) TranslateEntity Camera,.1,0,0
	
	TurnEntity TurnPivot,0,1,0
	TurnEntity Sprite2,0,DeltaYaw(Sprite2,Camera)*.8,0
	
	UpdateWorld
	RenderWorld
	
	Flip
	
Wend
End

Function ShadowText(value$,x#,y#,red%=255,green%=255,blue%=255,shadow_red=20,shadow_green=20,shadow_blue=20,center_x=1,center_y=1)
	Color shadow_red,shadow_green,shadow_blue
	Text x+1,y,value,center_x,center_y
	Text x,y+1,value,center_x,center_y
	Text x+1,y+1,value,center_x,center_y
	
	Color red,green,blue
	Text x,y,value,center_x,center_y
End Function

Function InitGraphics(w = 1024, h = 768,title$="Blitz3D Program",exit_message$="")
	Graphics3D w, h, 32, 2
	SetBuffer BackBuffer()
	SeedRnd MilliSecs()
	
	If exit_message <> ""
		AppTitle title,exit_message
			Else
				AppTitle title
	EndIf
End Function

Function CreateNameTexture(name$,flags)
	Local Width% = StringWidth(name)*2
	Local Height% = StringHeight(name)*2
	Local texture = CreateTexture(Width,Height,flags)
	
	TextureMaskFill(texture)
	
	SetBuffer TextureBuffer(texture)
		Color 0,255,0
		Rect 0,0,TextureWidth(texture),TextureHeight(texture)*.1
		Rect 0,TextureHeight(texture)*.9,TextureWidth(texture),TextureHeight(texture)*.1
		
		Color 254,254,0
		Text TextureWidth(texture)*.5,TextureHeight(texture)*.5,name,1,1
		;ShadowText(name,TextureWidth(texture)*.5,TextureHeight(texture)*.5,254)
	SetBuffer BackBuffer()
	
	Return texture
End Function

Function TextureMask( texture , sr=240 , sg=0 , sb=240, st = 30 )
	TW = TextureWidth( texture )
	TH = TextureHeight( texture )
	SetBuffer TextureBuffer( texture )
	LockBuffer 
	For j = 0 To TH - 1
		For i = 0 To TW - 1
			argb = ReadPixelFast( i,j, TextureBuffer( texture ) )
			r = ( argb And $FF0000) Shr 16
			g = ( argb And $FF00 ) Shr 8  
			b = ( argb And $FF )  
			a = ( argb And $FF000000 ) Shr 24
			
			If ( r > sr-st And r < sr+st ) And  ( g > sg-st And g < sg+st ) And ( b > sb-st And b < sb+st )
				
				a = 0 
				r = 0
				g = 0
				b = 0
			Else
				a = 255
			EndIf
			argb = ( a Shl 24 ) Or ( r Shl 16 ) Or ( g Shl 8 ) Or b
			WritePixelFast i , j , argb, TextureBuffer( texture )
		Next
	Next
	UnlockBuffer
	SetBuffer BackBuffer()
End Function

Function TextureMaskFill( texture )
	TW = TextureWidth( texture )
	TH = TextureHeight( texture )
	SetBuffer TextureBuffer( texture )
	LockBuffer 
	For j = 0 To TH - 1
		For i = 0 To TW - 1
			WritePixelFast i , j , 0, TextureBuffer( texture )
		Next
	Next
	UnlockBuffer
	SetBuffer BackBuffer()
End Function

Function CreateQuad(width#,height#,order%=-1,parent%=False)
	Local v0,v1,v2,v3
	Local Point,Surface
	
	If Not parent = False
		Point = CreateMesh(parent)
			Else
				Point = CreateMesh()
	EndIf
	
	If order <> 0
		EntityOrder Point,order
	EndIf
	
	EntityFX Point,1
	
	Surface = CreateSurface(Point)
	
	v0=AddVertex(Surface,-(width*.5),(height*.5),0 ,0,0)
	v1=AddVertex(Surface,(width*.5),(height*.5),0 ,1,0)
	v2=AddVertex(Surface,-(width*.5),-(height*.5),0 ,0,1)
	v3=AddVertex(Surface,(width*.5),-(height*.5),0 ,1,1)
	
	AddTriangle(Surface,v0,v1,v2)
	AddTriangle(Surface,v1,v3,v2)
	
	Return Point
End Function


The texture won't show up cos your mask function sets all the pixels alpha to zero which makes the whole texture invisible.

You aren't actually calling the mask function either?!

I normally colour the part I want masked in bright purple, draw what you need to it and call the mask function to alpha out the purple parts :

Function CreateNameTexture(name$,flags)
	Local Width% = StringWidth(name)*2
	Local Height% = StringHeight(name)*2
	Local texture = CreateTexture(Width,Height,flags)
	
	SetBuffer TextureBuffer(texture)
	
		Color 255,0,255
		Rect 0,0,TextureWidth( texture )-1, TextureHeight( texture ) - 1, 1
	
		Color 0,255,0
		Rect 0,0,TextureWidth(texture),TextureHeight(texture)*.1
		Rect 0,TextureHeight(texture)*.9,TextureWidth(texture),TextureHeight(texture)*.1
		
		Color 254,254,0
		Text TextureWidth(texture)*.5,TextureHeight(texture)*.5,name,1,1
		;ShadowText(name,TextureWidth(texture)*.5,TextureHeight(texture)*.5,254)
	SetBuffer BackBuffer()
	
	TextureMask( texture )
	
	Return texture
End Function


I also normally create the texture with flag 4 rather than 2 but it should still work.

Stevie

The TextureMaskFill is being called in this function.
Function CreateNameTexture(name$,flags)
	Local Width% = StringWidth(name)*2
	Local Height% = StringHeight(name)*2
	Local texture = CreateTexture(Width,Height,flags)
	
	TextureMaskFill(texture)
	
	SetBuffer TextureBuffer(texture)
		Color 0,255,0
		Rect 0,0,TextureWidth(texture),TextureHeight(texture)*.1
		Rect 0,TextureHeight(texture)*.9,TextureWidth(texture),TextureHeight(texture)*.1
		
		Color 254,254,0
		Text TextureWidth(texture)*.5,TextureHeight(texture)*.5,name,1,1
		;ShadowText(name,TextureWidth(texture)*.5,TextureHeight(texture)*.5,254)
	SetBuffer BackBuffer()
	
	Return texture
End Function


It's being called before anything is added. But it makes no sense that I can add rectangles and ovals but now the text doesn't work when it should.

Also, both flags 2 and 4 give the same result, I know their difference, but still...

thank you..works nicely


The TextureMaskFill is being called in this function.



Yes, but not the Texturemask function. Your 'TextureMaskFill' function is completely useless.

No it's not completely useless, it completely fills the texture with the alpha and I can actually read what the code is doing.

I understand yours is reading and writing pixels but I have no idea what that last variable is for "st=30".

Mine doesn't waste any time looking at pixels that aren't there yet.... hmmm that gives me an idea.. maybe I should try calling your function after I've put everything onto the texture... brb I'll try that.

Edit:
Nope, I tried adding it at the very end in my CreateNameTexture right after SetBuffer BackBuffer() but the text still doesn't show. It used to show. I don't know why it won't anymore.

OH, is the "st=30" for color tolerance? Not that it's gonna help, I was just noticing.