FREE - 3D Text System based on Single Surface

Blitz3D Forums/Blitz3D Programming/FREE - 3D Text System based on Single Surface

Rob Pearmain(Posted 2003) [#1]
Hi,

I am almost complete in writing my 3D text system based on a single surface.

Image to download is here:

Download...

or right click on this image and save as "letters2.bmp"



Now, the problem is, this works fine when working with the camera at 0,0,0.

But, as soon as I move the camera, the letter dissapear.

In fact, even if i entityparent it, still it dissapears.

It is something to do with TForming the CAMERA and subtracting the vertexcoards from it, but my head hurts.

PLEASE SOLVE THIS FOR ME !!! ;-)

Many thanks

;      Standard, used for 3D Calculations
Type vector
	Field	x#
	Field	y#
	Field	z#
End Type

;   Mesh (or emitter) for lettersprites
Type text3D_lettermesh
	Field mesh%
	Field surface%
end type

;   Sprites
Type text3D_lettersprite
     field index%
     field pos.vector
end type

;   640x480
global nScale#=.005

Graphics3D 640,480,32,3

SetBuffer BackBuffer()

camera=CreateCamera()
cameraclscolor camera,255,0,0
CameraRange camera, 0.1, 1000

mylettermesh.text3D_lettermesh = Text3D_CreateLetterMesh("letters2.bmp")


scalemesh mylettermesh\mesh,.005,.005,1
PositionEntity mylettermesh\mesh,0,0,.1
;positionentity camera,0,0,-5
restore robdata

read x$
n%=0


for z%=1 to len(x$)
     if mid$(x$,z%,1) <> " "

     	for b%=0 to 23
	      myletter.text3D_lettersprite = Text3D_AddLetter(mylettermesh,n%,b%,0,rnd(0,255),rnd(0,255),rnd(0,255))
	      Text3D_SetLetter(mylettermesh,myletter,asc(mid$(x$,z%,1)))
       	      Text3D_PositionLetter mylettermesh,myletter,rnd(0,39),rnd(0,24)
	next

      end if
       n% = n% + 1
next


cube=createcube()
positionentity cube,0,0,3


While Not KeyHit(1)

   ;TurnEntity mylettermesh\mesh,0,0,.3

   nStart%=millisecs()

   ;if keyhit(57)
   nCount%=0
   for o.text3D_lettersprite = each text3D_letterSprite
       nCount%=nCount%+1
       r%=r%+1
       if r>255 then r=0
       Text3D_ColorLetter mylettermesh,o,rnd(0,255),rnd(0,255),rnd(0,255)
       Text3D_PositionLetter mylettermesh,o,rnd(0,39),rnd(0,23)
   next
   ;end if
   nStart%=millisecs()=nStart%
   turnentity cube,0,1,1
   UpdateWorld
   RenderWorld
   text 0,0,nCount%
   Flip

Wend
End

function Text3D_SetLetter(mylettermesh.text3D_lettermesh,myletter.text3D_lettersprite,nAsc%)

      nAsc% = nAsc% - 33
      ny% = nAsc%/8
      nx% = nAsc% - (ny%*8)
      u# = nx% * .125
      v# = ny% * .125

      VertexTexCoords(mylettermesh\surface,myletter\index,u#,v#)
      VertexTexCoords(mylettermesh\surface,myletter\index+1,u#+.125,v#)
      VertexTexCoords(mylettermesh\surface,myletter\index+2,u#+.125,v#+.125)
      VertexTexCoords(mylettermesh\surface,myletter\index+3,u#,v#+.125)


end function

function Text3D_CreateLetterMesh.text3d_lettermesh(strTexture$)

	 t.text3D_lettermesh = new text3D_lettermesh

	 t\mesh = createmesh()
	 t\surface = createsurface(t\mesh)

	 Tex=LoadTexture(strTexture$,4)
         brush=CreateBrush()
         BrushFX brush,3
	 BrushTexture brush,tex
         PaintMesh t\mesh,brush
	 freebrush brush
	 freetexture tex

	 return t



end function

function Text3D_AddLetter.text3D_lettersprite(t.text3D_lettermesh,x#,y#,z#,r%=255,g%=255,b%=255)

   ;nOffset#=.5
   mytempletter.text3D_lettersprite = new text3D_lettersprite
   ;X# = X# - 20
   ;Y#=(14-(Y#*1.25))
   i%=AddVertex(t\surface,x#-1+nOffset#,y#+1+nOffset#,0, 0,0)
   AddVertex t\surface,x#+1+nOffset#,y#+1+nOffset#,0, .125,0
   AddVertex t\surface,x#+1+nOffset#,y#-1+nOffset#,0, .125,.125
   AddVertex t\surface,x#-1+nOffset#,y#-1+nOffset#,0, 0,.125

   AddTriangle t\surface,i%+0,i%+1,i%+2
   AddTriangle t\surface,i%+0,i%+2,i%+3

   UpdateNormals t\mesh
   mytempletter\index = i%

   Text3D_ColorLetter(t,mytempletter,r,g,b)
   mytempletter\pos = new vector
   Text3D_PositionLetter(t,mytempletter,rnd(0,39),rnd(0,24))



   return mytempletter

 end function

function Text3D_ColorLetter(t.text3D_lettermesh,l.text3D_lettersprite,r%,g%,b%,gradient%=false)

	 vertexcolor t\surface,l\index,255,255,255
	 vertexcolor t\surface,l\index+1,255,255,255
	 vertexcolor t\surface,l\index+2,r%,g%,b%
	 vertexcolor t\surface,l\index+3,r%,g%,b%

end function

 
Function Text3D_PositionLetter (t.text3D_lettermesh,l.text3D_lettersprite, x#,y#)

            l\pos\x = x#
   l\pos\y = y#
   l\pos\z = 0

    	 nOffset#=.5*nScale
    	 X# = X# - 20
   	 Y#=(14-(Y#*1.25))

	 x#=x#*nScale
    	 y#=y#*nScale
	 nInc#=nScale

	VertexCoords t\surface,l\index,x-nInc+nOffset,y+nInc+nOffset, 0
	VertexCoords t\surface,l\index+1,x+nInc+nOffset,y+nInc+nOffset, 0
	VertexCoords t\surface,l\index+2,x+nInc+nOffset,y-nInc+nOffset, 0
	VertexCoords t\surface,l\index+3,x-nInc+nOffset,y-nInc+nOffset, 0



End Function

.robdata
data "0123456789012345678901234567890123456789"




IPete2(Posted 2003) [#2]
Rob,

Why not use a second camera with the text on it? Similar to that fix which prevents entities shaking when they are at great distances from 0,0,0 - do you see what I mean?

Hope this is a good idea...

IPete2.


jfk EO-11110(Posted 2003) [#3]
Personally I never go far away from 0,0,0 :) ... This is a cool new Tool! And also pretty compact. I would probably prefix all Varable Names individually etc., byside that it's great, so: thanks a lot!


Rob Pearmain(Posted 2003) [#4]
I will make it really polished and generic, I just want to fix the camera problem,

IPete2, interesting idea, will investigate. Any example code on how to do a second camera?


IPete2(Posted 2003) [#5]
Rob,

Search for 'second camera' on the Blitz 3d forum, I found a few people's comments regarding the idea, I think one of the HUD's uses it, and I'll bet its around in the archives somewhere.

In the meantime I'll have a look in my own archive for any code relating to this idea, be back shortly.

(reply: okay, and stop calling me 'shortly'!)

IPete2.


IPete2(Posted 2003) [#6]
Aha Rob - I have found a clue...

"
I just completed the Swift HUD System... It's really neat. It's a whole system for drawing 2D overlays on top of your 3D scenes.


It works by creating a second camera and 3D meshes to go with it, and then rendering the view from it on top of your normal game camera.

This allows you to do whatever you want to your normal game camera without having to worry about messing up your HUD. It should solve any problems with tweening messing up HUDs for one thing. No longer do you need to parent meshes to your camera and watch as they shake because of tweening issues, or floating point inaccuracies. And need to zoom your game camera? No problem. The hud stays fixed right where it is.

Seperating the HUD into another camera does not cause any speed hit. And it allows you to do cool effects. Four example, you can rotate the camera to the left, and all your hud elements will tilt off the screen to the right. Simple and elegant. You can also change the zoom of the hud camera to make all the windows fly off the edges of the screen. Or make them shrink down to a speck and dissapear.


When you purchase my HUD system you get my new font systrm with it. (Anyone who previously purchased my font system is eligible for a free upgrade to my HUD system.) The two work together. So you can create great looking text that runs super fast at any size, with diffrent justification, and text wrapping to a specific pixel width."

End of Shawn Swift advert...


:)

IPete2.


Rob Pearmain(Posted 2003) [#7]
Cool, I have dones as you said, and yep, it works, awesome, here is the code, and many many thanks.

I will tidy up, make generic and document for all to use

;      Standard, used for 3D Calculations
Type vector
	Field	x#
	Field	y#
	Field	z#
End Type

;   Mesh (or emitter) for lettersprites
Type text3D_lettermesh
	Field mesh%
	Field surface%
	field ent%
end type

;   Sprites
Type text3D_lettersprite
     field index%
     field pos.vector
     field movex#
     field movey#
end type

;   640x480
global nScale#=.005

Graphics3D 640,480,32,0

SetBuffer BackBuffer()

camera=CreateCamera()
;cameraclscolor camera,255,0,0
CameraRange camera, 0.1, 0.2
CameraClsMode camera, False, False
EntityOrder camera, -1

mylettermesh.text3D_lettermesh = Text3D_CreateLetterMesh("letters2.bmp")

cube=createcube()
positionentity cube,0,0,3

maincamera=createcamera()
positionentity maincamera,0,0,-6

scalemesh mylettermesh\mesh,.005,.005,1
;PositionEntity mylettermesh\mesh,0,0,.1
;moveentity camera,0,0,-5

;for mycount = 1 to 2
restore robdata

read x$
n%=0


for z%=1 to len(x$)
     if mid$(x$,z%,1) <> " "

     	for b%=0 to 23
	      myletter.text3D_lettersprite = Text3D_AddLetter(mylettermesh,n%,b%,0,rnd(0,255),rnd(0,255),rnd(0,255))
	      Text3D_SetLetter(mylettermesh,myletter,asc(mid$(x$,z%,1)))
       	      Text3D_PositionLetter mylettermesh,myletter,rnd(0,39),rnd(0,24)
	next

      end if
       n% = n% + 1
next

;next


   nStart%=millisecs()
While Not KeyHit(1)

   ;TurnEntity mylettermesh\mesh,0,0,.3



   ;if keyhit(57)
   nCount%=0
   for o.text3D_lettersprite = each text3D_letterSprite
       nCount%=nCount%+1
       r%=r%+1
       if r>255 then r=0
       ;Text3D_ColorLetter mylettermesh,o,rnd(0,255),rnd(0,255),rnd(0,255)
       Text3D_PositionLetter mylettermesh,o,o\pos\x+o\movex,o\pos\y+o\movey
       if o\pos\y > 24 then o\movey=-o\MoveY
       if o\pos\y <0 then o\movey=-o\movey
       if o\pos\x <0 then o\movex=-o\movex
       if o\pos\x >39 then o\movex=-o\movex
   next
   ;end if
   if keydown(200)
      moveentity maincamera,0,0,.1
   end if
   if millisecs()-nStart% > 1000
      nFPS=nCounter
      nCounter = 0
      nStart=millisecs()
   end if
   turnentity cube,0,1,1
   UpdateWorld
   RenderWorld
   text 0,0,nCount%
   text 0,16,nFPS
   nCounter = nCounter + 1
   Flip

Wend
End

function Text3D_SetLetter(mylettermesh.text3D_lettermesh,myletter.text3D_lettersprite,nAsc%)

      nAsc% = nAsc% - 33
      ny% = nAsc%/8
      nx% = nAsc% - (ny%*8)
      u# = nx% * .125
      v# = ny% * .125

      VertexTexCoords(mylettermesh\surface,myletter\index,u#,v#)
      VertexTexCoords(mylettermesh\surface,myletter\index+1,u#+.125,v#)
      VertexTexCoords(mylettermesh\surface,myletter\index+2,u#+.125,v#+.125)
      VertexTexCoords(mylettermesh\surface,myletter\index+3,u#,v#+.125)


end function

function Text3D_CreateLetterMesh.text3d_lettermesh(strTexture$)

	 t.text3D_lettermesh = new text3D_lettermesh

	 t\ent = createpivot(camera)
	 moveentity t\ent,0,0,.1
	 t\mesh = createmesh(t\ent)
	 t\surface = createsurface(t\mesh)

	 Tex=LoadTexture(strTexture$,4)
         brush=CreateBrush()
         BrushFX brush,3
	 BrushTexture brush,tex
         PaintMesh t\mesh,brush
	 freebrush brush
	 freetexture tex

	 return t



end function

function Text3D_AddLetter.text3D_lettersprite(t.text3D_lettermesh,x#,y#,z#,r%=255,g%=255,b%=255)

   ;nOffset#=.5
   mytempletter.text3D_lettersprite = new text3D_lettersprite
   ;X# = X# - 20
   ;Y#=(14-(Y#*1.25))
   i%=AddVertex(t\surface,x#-1+nOffset#,y#+1+nOffset#,0, 0,0)
   AddVertex t\surface,x#+1+nOffset#,y#+1+nOffset#,0, .125,0
   AddVertex t\surface,x#+1+nOffset#,y#-1+nOffset#,0, .125,.125
   AddVertex t\surface,x#-1+nOffset#,y#-1+nOffset#,0, 0,.125

   AddTriangle t\surface,i%+0,i%+1,i%+2
   AddTriangle t\surface,i%+0,i%+2,i%+3

   UpdateNormals t\mesh
   mytempletter\index = i%

   Text3D_ColorLetter(t,mytempletter,r,g,b)
   mytempletter\pos = new vector
   Text3D_PositionLetter(t,mytempletter,rnd(0,39),rnd(0,24))
   mytempletter\movex=rnd(-.5,.5)
      mytempletter\movey=rnd(-.5,.5)


   return mytempletter

 end function

function Text3D_ColorLetter(t.text3D_lettermesh,l.text3D_lettersprite,r%,g%,b%,gradient%=false)

	 vertexcolor t\surface,l\index,255,255,255
	 vertexcolor t\surface,l\index+1,255,255,255
	 vertexcolor t\surface,l\index+2,r%,g%,b%
	 vertexcolor t\surface,l\index+3,r%,g%,b%

end function

 
Function Text3D_PositionLetter (t.text3D_lettermesh,l.text3D_lettersprite, x#,y#)

            l\pos\x = x#
   l\pos\y = y#
   l\pos\z = 0

    	 nOffset#=.5*nScale
    	 X# = X# - 20
   	 Y#=(14-(Y#*1.25))

	 x#=x#*nScale
    	 y#=y#*nScale
	 nInc#=nScale

	VertexCoords t\surface,l\index,x-nInc+nOffset,y+nInc+nOffset, 0
	VertexCoords t\surface,l\index+1,x+nInc+nOffset,y+nInc+nOffset, 0
	VertexCoords t\surface,l\index+2,x+nInc+nOffset,y-nInc+nOffset, 0
	VertexCoords t\surface,l\index+3,x-nInc+nOffset,y-nInc+nOffset, 0



End Function

.robdata
data "0123456789012345678901234567890123456789"




Rob(Posted 2003) [#8]
Cool... I use the single surface routines which I got with fontext from www.playerfactory.com

The cool thing about fontext is, you could easily use it with the above lib by rob since it's flexible.


Rob Pearmain(Posted 2003) [#9]
I made the Font texture above with Fontext.

Cool, now I have got this working I can eradicate all my 2D test functions in LunaC and gain quite a few frames


Binary_Moon(Posted 2003) [#10]
RobP - get rid of the updatenormals from the addletter function. It's not needed since you don't want lighting to affect the letters, and it gets rid of the pause when the code first starts.


Rob Pearmain(Posted 2003) [#11]
nice tip Ben.

Hey, just played with rotating the HUD, so cool. Thanks for everyones help