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:
Any help will be greatly appreciated.
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.