How to apply a ascii character to a cube

Blitz3D Forums/Blitz3D Beginners Area/How to apply a ascii character to a cube

Blitzplotter(Posted 2009) [#1]
I've been digging around in my folders and I know somewhere I figured this out before, but I cannot find it.

Can someone please remind me how to apply a particular ascii character to a cube after it has been created without having to created a bitmap in a paint program?

I would like to do it programmatically to save having to create a 100 different bit maps.

My goal is I'm making a game board with the numbers 1 to 100 superimposed on each different cube. So I suppose I ultimately want to be able to apply up to 3 characters i.e."100" to a cube.


Yasha(Posted 2009) [#2]
SetBuffer() is your friend...

Actually I'm not sure whether you can use standard drawing commands on a texture buffer, can't remember, but at any rate if you can't, you can always draw what you need to BackBuffer() and then CopyRect it over.


Ross C(Posted 2009) [#3]
Yeah, you can draw text or use any 2d command on any buffer. Only situtaion you can't do this, is when you lock a buffer. You can only use writepixel and read pixel (and copyrect?), until you unlock the buffer again.


PowerPC603(Posted 2009) [#4]
You can create a texture, set the buffer to that texture (SetBuffer TextureBuffer(Texture)) and use Text on it.
I know it can be done, because my game is doing that.


Blitzplotter(Posted 2009) [#5]
thanks for the replies folks, will try it later.


_PJ_(Posted 2009) [#6]
I am not sure, but I 'think' that using 100 frames of one textrue is ''better' than using 100 textrues each with one frame (???)

Here's an example:
The Text Size and font should be set up beforehand, but note that a small text size will be less texture memory used up but the text will look blocky whilst a large text size will look smoother, but take up more of the memory :)

Global Texture%=CreateTexture(StringWidth("100"),StringHeight("100"),0,100)
Global Cubes%[100]

Function BuildAndTextureCubes()
Local nCount%
For nCount%=0 To 99
Cubes%[nCount%]=CreateCube()
SetBuffer TextureBuffer(Texture%,nCount%)
Text GraphicsWidth() Shr True, GraphicsHeight() Shr True,Str(nCount%+1),True,True
SetBuffer BackBuffer()
EntityTexture Cubes[nCount%],Texture%,nCount%
Next
End Function



PowerPC603(Posted 2009) [#7]
When trying your example above, I get a variable type mismatch error on the line: "Cubes%[nCount%]=CreateCube()"

Removing the % from the array fixed it.


Nate the Great(Posted 2009) [#8]
I remember there were transparency problems with this and also some weird drawing bugs when drawing text to texture buffers. There was a work around somewhere but i have no idea where or what it was called...


_PJ_(Posted 2009) [#9]
When trying your example above, I get a variable type mismatch error on the line: "Cubes%[nCount%]=CreateCube()"

Removing the % from the array fixed it.


Sorry PowerPC603, and thanks for posting what fixes it - I just typed that out here rather than in Blitz so I didnt eeven try it... bad me!

Nate - I guess something related to how TTF fonts are scaled could do something like that? If it's only when drawing to textrue buffers, then maybe a two-step approach could be done building an Image first, writing text on that, and then copying the imagebuffer to the texture buffer? Remembering free the image after all's said & done (???)


Blitzplotter(Posted 2009) [#10]
@Malice, thanks for the func. Didn't quite get around to putting the numbers on, was having to much fun developing a make_game_board function, which I got carried away with and slapped in some stairs functionality.:
(I WILL be applying some numbers later though!)



A little snapshot of calling the function with 3,3 being passed with 25 madsteps being set within the function:-




Blitzplotter(Posted 2009) [#11]
found this as well:


; TextureBuffer Example 
; --------------------- 

Graphics3D 640,480 
SetBuffer BackBuffer() 

camera=CreateCamera() 

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

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

; Create texture of size 256x256 
tex=CreateTexture(256,256) 

; Set buffer - texture buffer 
SetBuffer TextureBuffer(tex) 

; Clear texture buffer with background white color 
ClsColor 255,255,255 
Cls 

; Draw text on texture 
font=LoadFont("arial",24) 
SetFont font 
Color 0,0,0 
Text 0,0,"This texture" 
Text 0,40,"was created using" : Color 0,0,255 
Text 0,80,"CreateTexture()" : Color 0,0,0 
Text 0,120,"and drawn to using" : Color 0,0,255 
Text 0,160,"SetBuffer TextureBuffer()" 

; Texture cube with texture 
EntityTexture cube,tex 

; Set buffer - backbuffer 
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 




Blitzplotter(Posted 2009) [#12]
@malice, I am attempting to use a version of your code to apply texture to a 100 separate ODE cubes. I save the 100 diffeterent ODE cubes memory locations into an array, and then loop through the 100 cubes applying the text on the texture to each cube, however I cannot understand why the final number of the loop index is being applied to all of the cubes:-






Blitzplotter(Posted 2009) [#13]
Hmm, confused I am... Tried applying a separate texture of 91 to the 91st cube outside of the loop index - and all 75 cubes also have 91 applied to them. I'm beginning to think I need a 100 textures......... In fact I think I've just learned the hardway if a texture is applied to anything in a game and updated - wherever that texture is will be updated also. Hmm.







_PJ_(Posted 2009) [#14]
I think see what's happening...

You are only ever defining one texture. 'text' This is fine if you wish to use a separate texture FRAME for each number, but you also only have a single frame.

So, even if you change the texture before applying to a new cube, EVERY INSTANCE of the texture is changed, including those already applied.

What you need is to add in something to ensure you aer actually using a different texture (or different texture frame) to each cube.

Try this:

; Create texture of size 256x256

Global FLAGS=1	;Malice				 			Added this because you need to specify the texture flags value before how many frames. 1=colour and is the default
tex=CreateTexture(256,256,FLAGS,100) ;Malice	This now gives the texture 100 frames

font=LoadFont("arial",96,1,0,0) 
SetFont font 
Color 0,0,0 

For countcubes=1 To 100

	;Malice										Moved the setbuffer and cls inside loop and removed duplicate for efficiency.
	; Draw text on texture 
	; Set buffer - texture buffer 
	;-Malice:									Added Second Parameter for frame reference (frames are counted from 0-99)
	SetBuffer TextureBuffer(tex,countcubes-1) 

	; Clear texture buffer with background white color 
	ClsColor 255,255,255 
	Cls 
	
	Text 0,80,"  "+countcubes : Color 255,125,255
	;Flip	-Malice								We don't need flip as we are only drawing to the texture buffer.

	;Malice										Again, added a second parameter for texture frame
	EntityTexture colorthis(countcubes),tex,countcubes-1		
Next

;	Malice										Setbuffer back to backbuffer OUTSIDE of loop for efficiency.
SetBuffer BackBuffer()




Blitzplotter(Posted 2009) [#15]
@Malice, thankyou for the extra clarification, it is appreciated.


Blitzplotter(Posted 2009) [#16]
Just implemented the code, works a treat:




jfk EO-11110(Posted 2009) [#17]
As Nate said, doing 2D Stuff on a Texturebuffer fails on a number of machines. It might work on yours, but not on the one of your customer. Drawing to the backbuffer and then Copyrect to the texturebuffer always works.


_PJ_(Posted 2009) [#18]
In lieu of jfk's post, just in case, here's a modified version of my code that copies the tetures from the backbuffer as suggested:

Overall it will be slightly slower, but assuming these cubes and their twxtures are all generated prior to 'gameplay' actually begins, it shouldn't be an issue.

; Create texture of size 256x256

Global FLAGS=1	;Malice				 			Added this because you need to specify the texture flags value before how many frames. 1=colour and is the default
tex=CreateTexture(256,256,FLAGS,100) ;Malice	This now gives the texture 100 frames

font=LoadFont("arial",96,1,0,0) 
SetFont font 
SetBuffer BackBuffer()
Color 0,0,0 
ClsColor 255,255,255
Cls

;First loop to wtrite out 0 - 99 on the backbuffer all together to save constantly re-drawing etc.
For countcubes=1 To 100
	SetBuffer TextureBuffer(tex,countcubes)	; Malice: Not entirely sure if these are req'd but 
	Cls						;         Just in case, clear the texture buffers in white.
	SetBuffer BackBuffer()
	Text 0+StringWidth(Str(countcubes)),0,Str(countcubes),True,True
Next
	
;second loop to copy the relevant text from the backbuffer onto the texture frame buffers
For countcubes=1 To 100
	xx=StringWidth(countcubes)
	yy=StringHeight(countcubes)
	CopyRect 0+xx,0,xx,yy,128-(xx Shr True),128-(yy Shr True) ,BackBuffer(),TextureBuffer(tex,countcubes-1)
	;Flip	-Malice								We don't need flip as we need to keep the back buffer	
	;Malice										Again, added a second parameter for texture frame
	EntityTexture colorthis(countcubes),tex,countcubes-1		
Next

;	Malice										Setbuffer to back buffer is already done.




PowerPC603(Posted 2009) [#19]
As Nate and jfk already said, avoid trying to use 2D drawing commands directly onto a texture.
First create an image (or use the backbuffer to draw on), draw your text or any 2D stuff you want to see on your texture, and finally Copyrect the image to your texture.

I've had lots of troubles when trying to write text directly onto a texture.

On my laptop it worked fine, but on the pc, the text didn't show up.
I had a sprite with a texture on it, but the text didn't show up.
It only showed up when editing another texture (for use on another model), but only for 1 frame before disappearing again.

After changing the code to draw to an image first, everything worked fine.

Also masking a texture didn't work when the text was directly written to the texture, even on the laptop.

Again, using an image first, then CopyRect it to the texture and after that, using a MaskTexture function from the code-archives, gave the texture proper masking.


Blitzplotter(Posted 2010) [#20]
Thank you for the extra pointers, I'd simply resigned myself to thinking it would not work on the laptop.