So the problem seems to stem from my single surface code?
Which confuses me greatly as I don't see where I can optimise it. But then I'm not fantastic at this sort of thing.
;********************************************************
;* *
;* EngineTwo *
;* 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.
;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
Const TEXTURE_WIDTH# = 1024.0
Const TEXTURE_HEIGHT# = 1024.0
Const TILE_SIZE = 256
;sprite type
Type sprite
Field width ;width of sprite in pixels
Field height ;height of sprite in pixels
Field u1#,v1# ;top left texture coords
Field u2#,v2# ;bottom right texture coords
Field tile ;tile number of sprite (for use in deleting tiles)
Field id ;sprite id, using handle()
End Type
Type font
Field ttFont ;the truetype font handle
Field flags ;character flags
Field height ;height of the font
Field stored[222] ;tells if character is used
Field x#[222] ;x position
Field y#[222] ;y position
Field u1#[222] ;uv coords for top left, and bottom right
Field u2#[222]
Field v1#[222]
Field v2#[222]
Field width[222] ;width in pixels
End Type
Global mainTexture, mainSurface, mainBrush, mainCamera, mainLight, mainMesh
Global screenWidth, screenHeight, normalMeshX#, normalMeshY#, normalMeshZ#
Global fontBottom, nextFreeTile
Global tilesAcross, totalTiles
tilesAcross = (TEXTURE_WIDTH - 256) / TILE_SIZE
totalTiles = tilesAcross * (TEXTURE_HEIGHT / TILE_SIZE)
Dim tileUsed(111) ;111 tiles
fontBottom = 0
;Engine Initialisation
;Sets up EngineTwo for use
;x = width of screen
;y = height of screen
Function E2_initialiseEngine(x, y,z)
Graphics3D x,y,32,z
ClearTextureFilters
screenWidth = x
screenHeight = y
normalMeshX = ((screenWidth*-1)/2)-0.5
normalMeshY = ((screenHeight*-1)/2)+0.5
normalMeshZ = screenWidth/2
;load in texture
mainTexture = CreateTexture(TEXTURE_WIDTH, TEXTURE_HEIGHT, 1+2+16+32)
E2_initialiseTexture(mainTexture)
;create brush
mainBrush = CreateBrush()
BrushTexture mainBrush, mainTexture
;create camera
mainCamera = CreateCamera()
CameraZoom mainCamera, 1
CameraViewport mainCamera, 0, 0, screenWidth, screenHeight
;create light
AmbientLight 255,255,255
;create mesh
mainMesh = CreateMesh()
;create surface
mainSurface = CreateSurface(mainMesh)
;vertex colours and alpha
EntityFX mainMesh, 2+32
;position mesh so it can be seen
PositionEntity mainMesh, normalMeshX, normalMeshY, normalMeshZ
PositionEntity mainCamera, 0, 0, 0
;paint surface
PaintSurface mainSurface, mainBrush
End Function
;Texture Intialisation
;Turns a texture completely black, transparent
;texture = texture handle
Function E2_initialiseTexture(texture)
width = TextureWidth(texture)
height = TextureHeight(texture)
LockBuffer TextureBuffer(texture)
For a = 0 To height-1
For b = 0 To width-1
WritePixelFast b, a, $00000000, TextureBuffer(texture)
Next
Next
;place white, non-transparent pixel
WritePixelFast 0,0,$FFFFFFFF, TextureBuffer(texture)
UnlockBuffer TextureBuffer(texture)
End Function
;Texture Editing
;draws images to texture without disrupting alpha channels
;image = image handle of image to draw
;texture = texture handle
;x = x location to draw image
;y = y location to draw image
Function E2_editTexture(image, texture, x, y)
LockBuffer TextureBuffer(texture)
LockBuffer ImageBuffer(image)
width = ImageWidth(image)
height = ImageHeight(image)
For a = 0 To height-1
For b = 0 To width-1
colour = ReadPixelFast (b, a, ImageBuffer(image))
If (colour And $00FFFFFF) = $00000000 Then
WritePixelFast x+b, y+a, $00000000, TextureBuffer(texture)
Else
colour = (colour Or $FF000000)
WritePixelFast x+b, y+a, colour, TextureBuffer(texture)
End If
Next
Next
UnlockBuffer TextureBuffer(texture)
UnlockBuffer ImageBuffer(image)
End Function
;Adding a Tile
;Adds a graphics tile to the texture
;tilename$ = filename of the tile
Function E2_addTile(tilename$)
If nextFreeTile < totalTiles Then
image = LoadImage(tilename)
x = ((nextFreeTile Mod tilesAcross) * TILE_SIZE) + 256
y = (nextFreeTile / tilesAcross) * TILE_SIZE
E2_editTexture(image,mainTexture,x,y)
;update next free tile
tileUsed(nextFreeTile) = True
tile = nextFreeTile
a = 0
While (a < totalTiles)
If tileUsed(a) Then
a = a + 1
Else
nextFreeTile = a
a = totalTiles
End If
Wend
If nextFreeTile = tile Then nextFreeTile = totalTiles
Return tile
Else
Return -1
End If
End Function
;Removing a Tile
;Removes a previously added tile from the system
;tileNumber = number of tile to remove
Function E2_removeTile(tileNumber)
If tileNumber < totalTiles Then
tileUsed(tileNumber) = False
nextFreeTile = tileNumber
image = CreateImage(TILE_SIZE, TILE_SIZE)
SetBuffer ImageBuffer(image)
ClsColor 0,0,1
Cls
SetBuffer BackBuffer()
x = ((tileNumber Mod tilesAcross) * TILE_SIZE) + 256
y = (tileNumber / tilesAcross) * TILE_SIZE
E2_editTexture(image,mainTexture,x,y)
For this.sprite = Each sprite
If this\tile = tileNumber : Delete this : End If
Next
Return True
Else
Return False
End If
End Function
;Capturing a Sprite
;Captures a sprite from a tile and returns it
;tile = tile to capture sprite from
;x = x location of sprite in tile
;y = y location of sprite
;width = width of sprite
;height = height of sprite
Function E2_captureSprite.sprite(tile, x, y, width, height)
newSprite.sprite = New sprite
newSprite\width = width
newSprite\height = height
newSprite\tile = tile
x = x + 1 + ((tile Mod tilesAcross) * TILE_SIZE) + 256
y = y + 1 + ((tile / tilesAcross) * TILE_SIZE)
newSprite\u1 = (x) / TEXTURE_WIDTH
newSprite\v1 = (y) / TEXTURE_HEIGHT
newSprite\u2 = (x+width-1) / TEXTURE_WIDTH
newSprite\v2 = (y+height-1) / TEXTURE_HEIGHT
newSprite\id = Handle(newSprite)
Return newSprite
End Function
;Draw Sprite
;Draws a sprite to the screen
;this = sprite to be drawn
;xpos = x location to draw sprite
;ypos = y location
;xscale = multiplier to scale image
;yscale = multiplier
;angle = angle to rotate clockwise
;alpha = transparency
Function E2_drawSprite(this.sprite, xpos#, ypos#, xscale#, yscale#, angle#, alpha#)
ypos = -ypos
;get x and y distances from centre
angle = 360-angle
xdist# = (((this\width))/2.0)*xscale
ydist# = (((this\height))/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)
VertexColor mainSurface, v1, 255, 255, 255, alpha
VertexColor mainSurface, v2, 255, 255, 255, alpha
VertexColor mainSurface, v3, 255, 255, 255, alpha
VertexColor mainSurface, v4, 255, 255, 255, alpha
;add two triangles
t1 = AddTriangle(mainSurface, v1, v2, v4)
t2 = AddTriangle(mainSurface, v2, v3, v4)
End Function
;Draw Rectangle
;Draws a rectangle to the screen
;x = x location
;y = y location
;width = width of rectangle
;height = height of rectangle
;fill = filled
;rgb = colour values
;alpha = transparency
Function E2_Rect(x#, y#, width#, height#, fill = True, red, green, blue, alpha#)
y = -y
If fill Then
v1 = AddVertex(mainSurface, x, y, 0, 0.0, 0.0)
v2 = AddVertex(mainSurface, x+width-1, y, 0, 0.0, 0.0)
v3 = AddVertex(mainSurface, x+width-1, y-height+1, 0, 0.0, 0.0)
v4 = AddVertex(mainSurface, x, y-height+1, 0, 0.0, 0.0)
t1 = AddTriangle(mainSurface, v1, v2, v3)
t2 = AddTriangle(mainSurface, v1, v3, v4)
VertexColor mainSurface, v1, red, green, blue, alpha
VertexColor mainSurface, v2, red, green, blue, alpha
VertexColor mainSurface, v3, red, green, blue, alpha
VertexColor mainSurface, v4, red, green, blue, alpha
Else
T = 1
;top
v1 = AddVertex(mainSurface, x, y, 0, 0.0, 0.0)
v2 = AddVertex(mainSurface, x+width-1, y, 0, 0.0, 0.0)
v3 = AddVertex(mainSurface, x+width-1, y-T, 0, 0.0, 0.0)
v4 = AddVertex(mainSurface, x, y-T, 0, 0.0, 0.0)
;right
v5 = AddVertex(mainSurface, x+width-1, y, 0, 0.0, 0.0)
v6 = AddVertex(mainSurface, x+width-1, y-height+1, 0, 0.0, 0.0)
v7 = AddVertex(mainSurface, x+width-(T+1), y-height+1, 0, 0.0, 0.0)
v8 = AddVertex(mainSurface, x+width-(T+1), y, 0, 0.0, 0.0)
;bottom
v9 = AddVertex(mainSurface, x, y-height+1, 0, 0.0, 0.0)
v10 = AddVertex(mainSurface, x+width-1, y-height+1, 0, 0.0, 0.0)
v11 = AddVertex(mainSurface, x+width-1, y-height+(1-T), 0, 0.0, 0.0)
v12 = AddVertex(mainSurface, x, y-height+(1-T), 0, 0.0, 0.0)
;left
v13 = AddVertex(mainSurface, x, y, 0, 0.0, 0.0)
v14 = AddVertex(mainSurface, x+T, y, 0, 0.0, 0.0)
v15 = AddVertex(mainSurface, x+T, y-height+1, 0, 0.0, 0.0)
v16 = AddVertex(mainSurface, x, y-height+1, 0, 0.0, 0.0)
;triangles
t1 = AddTriangle(mainSurface, v1, v2, v3)
t2 = AddTriangle(mainSurface, v1, v3, v4)
t3 = AddTriangle(mainSurface, v5, v6, v7)
t4 = AddTriangle(mainSurface, v5, v7, v8)
t5 = AddTriangle(mainSurface, v9, v10, v11)
t6 = AddTriangle(mainSurface, v9, v11, v12)
t7 = AddTriangle(mainSurface, v13, v14, v15)
t8 = AddTriangle(mainSurface, v13, v15, v16)
;colouring
VertexColor mainSurface, v1, red, green, blue, alpha
VertexColor mainSurface, v2, red, green, blue, alpha
VertexColor mainSurface, v3, red, green, blue, alpha
VertexColor mainSurface, v4, red, green, blue, alpha
VertexColor mainSurface, v5, red, green, blue, alpha
VertexColor mainSurface, v6, red, green, blue, alpha
VertexColor mainSurface, v7, red, green, blue, alpha
VertexColor mainSurface, v8, red, green, blue, alpha
VertexColor mainSurface, v9, red, green, blue, alpha
VertexColor mainSurface, v10, red, green, blue, alpha
VertexColor mainSurface, v11, red, green, blue, alpha
VertexColor mainSurface, v12, red, green, blue, alpha
VertexColor mainSurface, v13, red, green, blue, alpha
VertexColor mainSurface, v14, red, green, blue, alpha
VertexColor mainSurface, v15, red, green, blue, alpha
VertexColor mainSurface, v16, red, green, blue, alpha
End If
End Function
;Load Font
;Loads a font into the system
;fontname$ = font filename
;size = size of font
;bold = enable bold
;italic = enable italics
;flags = characters used
Function E2_loadFont.font(fontname$, size, bold, italic, flags, smooth)
;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
this.font = New font
;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 255
;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
SetBuffer BackBuffer()
;check for fit
y = y + height
If (fontBottom + y) < 1024 Then
;success - write section to texture
imageTwo = CreateImage(256,y)
SetBuffer ImageBuffer(imageTwo)
DrawImage fontImage, 0, 0
E2_editTexture(imageTwo, mainTexture, 0, fontBottom+1)
SetBuffer BackBuffer()
;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]) / (TEXTURE_WIDTH+smooth)
this\v1[a] = (this\y[a]) / (TEXTURE_HEIGHT+smooth)
this\u2[a] = (this\x[a] + this\width[a]) / (TEXTURE_WIDTH+smooth)
this\v2[a] = (this\y[a] + height) / (TEXTURE_HEIGHT+smooth)
End If
Next
FreeImage fontImage
FreeImage imageTwo
fontbottom = fontbottom + y
this\ttFont = theFont
Return this
Else
Delete this
FreeImage fontImage
Return Null
End If
End Function
;Text
;Writes text on screen
;theText$ = text to be written
;textx = coordinate
;texty = coordinate
;xcent = centre horizontally
;bitmapFont = font to write in
;rgb = colour values
Function E2_text(theText$, textx#, texty#, xcent, bitmapFont.font, red, green, blue)
SetFont bitmapFont\ttFont
;centre vertically (automatic)
texty = -texty + (bitmapFont\height * 0.5)
;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
;ensure that spaces are accounted for
If char = -1 Then char = 94
;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], texty, 0, bitmapFont\u2[char], bitmapFont\v1[char])
v3 = AddVertex(mainSurface, textx+bitmapFont\width[char], texty-bitmapFont\height, 0, bitmapFont\u2[char], bitmapFont\v2[char])
v4 = AddVertex(mainSurface, textx, texty-bitmapFont\height, 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.25)
End If
Next
End Function
Function E2_clearSurface()
ClearSurface mainSurface
End Function
Function E2_updateWorld()
UpdateNormals mainMesh
RenderWorld
Flip
End Function
;Display Texture
;Debug routine to ensure texture is working
Function E2_displayTexture()
v1 = AddVertex(mainSurface, 0, TEXTURE_HEIGHT, 0, 0.0, 0.0)
v2 = AddVertex(mainSurface, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, 1.0, 0.0)
v3 = AddVertex(mainSurface, TEXTURE_WIDTH, 0, 0, 1.0, 1.0)
v4 = AddVertex(mainSurface, 0, 0, 0, 0.0, 1.0)
t1 = AddTriangle(mainSurface, v1, v2, v3)
t2 = AddTriangle(mainSurface, v1, v3, v4)
End Function