Cannot edit Masked Textures

Blitz3D Forums/Blitz3D Programming/Cannot edit Masked Textures

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

I'm having a problem in editing or copying to a texture that has been flagged as "Masked". Having set the buffer to TextureBuffer(mainTexture), no images drawn appear on the texture (I have a function to output the current texture to a file to debug). The Line function works, but draws lines twice the size that I desire. CopyRect also does not work.

I'm creating a 2D in 3D single surface system. One of the features of the system will be the ability to load up a square graphics tile, which is added to the main texture so that its contents may be displayed on the surface (the user must load in the necessary data for the sprites contained therein).

Another feature is the creation of fonts in a similar fashion. The fonts are loaded as standard, and the required characters are drawn to an image which is then copied onto the main texture. Each character has its own u,v values for top left and bottom right so that they may be drawn to the surface.

The main texture is a 1024*1024 texture (I plan to expand this to 2048*1024, which is supported, but for testing the smaller texture is more suitable), with the Colour and Masked flags activated (1+4). A rectangular block, measuring from 0,0 to 255,1024 is used for storing the fonts. The rest of the texture is given up for square tiles of equal size.

Obviously, without the ability to edit the texture properly, the system cannot work. It's proving to be quite irritable. Yet I recall Anthony Flack used a similar technique of adding tiles to a texture (indeed, his comments are what I based the system on), so I know it is possible in some respect.

The full code for the engine is here:

;********************************************************
;*														*
;*	2D in 3D engine										*
;*	Initialisation and Routines							*
;*														*
;********************************************************

;NOTES
;the pixel 0,0 on the texture must be coloured white, for rectangle drawing
;the rectangle covering 0,1 to 256,1024 is reserved for fonts only.
;loadBitmapFont loads a normal font into the custom font type
;you must create a custom font type before using loadBitmapFont

;constants
Const SYMBOL_TYPE = 0
Const NUMERAL_TYPE = 1
Const UC_TYPE = 2
Const LC_TYPE = 3
Const UCS_TYPE = 4
Const LCS_TYPE = 5

;type creation
Type sprite
Field width			;sprite width, pixels
Field height		;sprite height, pixels
Field u1#, v1#		;top left texture
Field u2#, v2#		;bottom right texture
Field tile			;tile number
End Type

Type font
Field ttFont		;the truetype font handle
Field flags			;character flags
Field height		;height of the font
Field stored[221]	;tells if character is used
Field x[221]		;x position
Field y[221]		;y position
Field u1#[221]		;uv coords for top left, and bottom right
Field u2#[221]
Field v1#[221]
Field v2#[221]
Field width[221]	;width in pixels
End Type

Global mainTexture, mainSurface, mainBrush, mainCamera, mainLight, mainMesh
Global screenWidth, screenHeight
Global totalTiles, tileSize, nextFreeTile
Global fontBottom

Dim tileInUse(111)  ;true if tile is in use. 112 tiles maximum.

;Initialisation
Function initialiseEngine(x,y,depth,size)
	Graphics3D x,y,depth
	ClearTextureFilters
	
	screenWidth = x
	screenHeight = y
	tilesAcross = 1792/size
	tilesDown = 1024/size
	totalTiles = tilesAcross * tilesDown
	tileSize = size
	
	For a = 0 To 111 : tileInUse(a) = False : Next
	nextFreeTile = 0
	
	mainMesh = CreateMesh()
	PositionMesh mainMesh, screenWidth*-0.5, screenHeight*-0.5, screenWidth*-0.5
	mainSurface = CreateSurface(mainMesh)
	mainCamera = CreateCamera()
	mainLight = CreateLight()
	LightColor mainLight,255,255,255
	mainBrush = CreateBrush()
	mainTexture = LoadTexture("engineTexture.png",5)
	BrushTexture mainBrush,mainTexture
	BrushFX mainBrush, 2
	PaintSurface mainSurface,mainBrush
	SetBuffer TextureBuffer(mainTexture)
	Color 255,255,255
	Line 0,0,127,0
	Print TextureWidth(mainTexture)
	Print TextureHeight(mainTexture)
	SetBuffer BackBuffer()
End Function

;drawing 3D image
Function draw3DImage(this.sprite, xpos#, ypos#, xscale#, yscale#, angle#)
	;this			:sprite to be drawn to screen
	;xpos, ypos		:coordinates of world to place sprite
	;xscale, yscale	:scaling
	;angle			:angle of rotation
	
	
	;first, get the x and y distances from centre
	angle = 360-angle
	xdist# = (((this\width)-1)/2.0)*xscale
	ydist# = (((this\height)-1)/2.0)*yscale
	
	;rotate each vertex in turn
	x1# = (xdist*-1) * Cos(angle) - ydist * Sin(angle)
	y1# = (xdist*-1) * Sin(angle) + ydist * Cos(angle)
	
	x2# = xdist * Cos(angle) - ydist * Sin(angle)
	y2# = xdist * Sin(angle) + ydist * Cos(angle)
	
	x3# = xdist * Cos(angle) + ydist * Sin(angle)
	y3# = xdist * Sin(angle) - ydist * Cos(angle)
	
	x4# = (xdist*-1) * Cos(angle) + ydist * Sin(angle)
	y4# = (xdist*-1) * Sin(angle) - ydist * Cos(angle)
	
	
	;create the four vertices as part of the quad.
	v1 = AddVertex(mainSurface, xpos+x1, ypos+y1, 0, this\u1, this\v1)
	v2 = AddVertex(mainSurface, xpos+x2, ypos+y2, 0, this\u2, this\v1)
	v3 = AddVertex(mainSurface, xpos+x3, ypos+y3, 0, this\u2, this\v2)
	v4 = AddVertex(mainSurface, xpos+x4, ypos+y4, 0, this\u1, this\v2)
	
	;add two triangles
	t1 = AddTriangle(mainSurface, v1, v2, v4)
	t2 = AddTriangle(mainSurface, v2, v3, v4)
End Function

;draw a solid coloured rectangle
Function rectangle(x, y, width, height, red, green, blue)
	
	v1 = AddVertex(mainSurface, x			, y			, 0, 0, 0)
	v2 = AddVertex(mainSurface, x+width-1	, y			, 0, 0, 0)
	v3 = AddVertex(mainSurface, x+width-1	, y-height+1, 0, 0, 0)
	v4 = AddVertex(mainSurface, x			, y-height+1, 0, 0, 0)
	
	VertexColor mainSurface, v1, red, green, blue
	VertexColor mainSurface, v2, red, green, blue
	VertexColor mainSurface, v3, red, green, blue
	VertexColor mainSurface, v4, red, green, blue
	
	t1 = AddTriangle(mainSurface, v1, v2, v3)
	t2 = AddTriangle(mainSurface, v1, v3, v4)
End Function

;update screen
Function updateScreen()
	UpdateNormals(mainMesh)
	RenderWorld
	Flip
End Function

;clear screen
Function clearScreen()
	ClearSurface(mainSurface)
End Function

;add a tile to the system
Function addTile(tilename$)
	If nextFreeTile < totalTiles Then
	
		image = LoadImage(tilename)
		x = (nextFreeTile Mod tilesAcross) * tileSize
		y = (nextFreeTile / tilesAcross) * tileSize
		CopyRect 0,0,tileSize,tileSize,x,y,ImageBuffer(image),TextureBuffer(mainTexture)
		Cls
		
		;update next free tile
		tileInUse(nextFreeTile) = True
		tileUsed = nextFreeTile
		While (nextFreeTile = True) Or (nextFreeTile = totalTiles)
			nextFreeTile = nextFreeTile + 1
		Wend
				
		Return tileUsed
	Else
		Return -1
	End If
End Function

;remove a tile from the system
Function removeTile(tileNumber)
	If tileNumber < totalTiles Then
	
		tileInUse(tileNumber) = False
		
		For this.sprite = Each sprite
			If this\tile = tileNumber : Delete this : End If
		Next
	
		Return True
	Else
		Return False
	End If
End Function

;load in a bitmap font - normal font must already be loaded, and type created
Function loadBitmapFont(fontname$, size, bold, italic, flags, this.font)

	;flags guide
	;1 : symbols
	;2 : numerals
	;4 : upper case
	;8 : lower case
	;16: upper case special
	;32: lower case special
	
	;0 is default
	If flags = 0 Then flags = 63

	;load in font from disc as normal
	theFont = LoadFont(fontname$, size, bold, italic)
	this\flags = flags
	SetFont theFont
	
	;set buffer, clear screen
	fontImage = CreateImage(256,1024)
	SetBuffer ImageBuffer(fontImage)
	ClsColor 0,0,0
	Cls
	Color 255,255,255
	
	;start at 0,0
	x = 0
	y = 0
	
	;get character height
	height = FontHeight()
	this\height = height
	
	;go through every character in order
	charType = SYMBOL_TYPE		;stores type of character
	For character = 33 To 254
	
		;skip the unnecessary
		If character = 48 Then charType = NUMERAL_TYPE
		If character = 58 Then charType = SYMBOL_TYPE
		If character = 65 Then charType = UC_TYPE
		If character = 91 Then charType = SYMBOL_TYPE
		If character = 97 Then charType = LC_TYPE
		If character = 123 Then 
			character = 128
			charType = SYMBOL_TYPE
		End If
		If character = 129 Then character = 163
		If character = 164 Then character = 169
		If character = 170 Then
			character = 192
			charType = UCS_TYPE
		End If
		If character = 198 Then character = 199
		If character = 215 Then character = 216
		If character = 221 Then character = 222
		If character = 224 Then charType = LCS_TYPE
		If character = 230 Then character = 231
		If character = 247 Then character = 248
		If character = 253 Then character = 254
		
		If Mid(Bin(flags), 32-chartype, 1) = "1" Then
			
			;check for horizontal fit
			this\width[character-33] = StringWidth(Chr$(character))
			If (x + this\width[character-33] -1 ) > 256 Then
				y = y + height
				x = 0
			End If
			
			;write character to image
			Text x,y, Chr$(character)
			
			;store x and y values
			this\x[character-33] = x
			this\y[character-33] = y
			this\stored[character-33] = True
			x = x + this\width[character-33]
		Else
			this\stored[character-33] = False
		End If
		
	Next
	
	;check for fit
	y = y + height
	If (fontBottom + y) < 1024 Then
		;success
		CopyRect 0,0,256,y,0,fontBottom-1,ImageBuffer(fontImage),TextureBuffer(mainTexture)
		
		;sort out u,v coors For letters
		For a = 0 To 221
			If this\stored[a] = True Then
				this\y[a] = this\y[a] + fontBottom + 1
				this\u1[a] = this\x[a] / 2048.0
				this\v1[a] = this\y[a] / 1024.0
				this\u2[a] = (this\x[a] + this\width[a] - 1) / 2048.0
				this\v2[a] = (this\y[a] + height - 1) / 1024.0
			End If
		Next			
		FreeImage fontImage
		this\ttFont = theFont
		Return True
	Else
		Delete this
		FreeImage fontImage
		Return False
	End If
	
End Function

;write in bitmap font
Function displayText(theText$, textx#, texty#, xcent, ycent, bitmapFont.font, red, green, blue)

	SetFont bitmapFont\ttFont
	
	;centre vertically
	If ycent Then
		texty = texty + (height * 0.5)
	End If
	
	;centre horizontally
	If xcent Then
		textx = textx - (StringWidth(thetext) * 0.5)
	End If
	
	;go through each character in turn, drawing to screen
	For a = 1 To Len(theText)
	
		char = Asc(Mid(theText, a, 1)) - 33
		
		;check if character in font
		If bitmapFont\stored[char] Then
			
			;create the four vertices as part of the quad.
			v1 = AddVertex(mainSurface, textx, texty, 0, bitmapFont\u1[char], bitmapFont\v1[char])
			v2 = AddVertex(mainSurface, textx+bitmapFont\width[char]-1, texty, 0, bitmapFont\u2[char], bitmapFont\v1[char])
			v3 = AddVertex(mainSurface, textx+bitmapFont\width[char]-1, texty-bitmapFont\height+1, 0, bitmapFont\u2[char], bitmapFont\v2[char])
			v4 = AddVertex(mainSurface, textx, texty-bitmapFont\height+1, 0, bitmapFont\u1[char], bitmapFont\v2[char])
		
			;color the vertices
			VertexColor mainSurface, v1, red, green, blue
			VertexColor mainSurface, v2, red, green, blue
			VertexColor mainSurface, v3, red, green, blue
			VertexColor mainSurface, v4, red, green, blue
	
			;add two triangles
			t1 = AddTriangle(mainSurface, v1, v2, v4)
			t2 = AddTriangle(mainSurface, v2, v3, v4)
			
			;move cursor
			textx = textx + bitmapFont\width[char]
		
		Else
			textx = textx + (bitmapFont\height * 0.5)
		End If
	Next
End Function

;function to save the texture to disc for debugging purposes
Function debugTexture()
	theImage = CreateImage(1024,1024)
	SetBuffer TextureBuffer(mainTexture)
	
	GrabImage theImage, 0, 0
	SaveImage (theImage, "debugTexture.bmp")
End Function


Any help will be greatly appreciated.