HELP !!!! Single Surface Sprites and Texel Alignment

Blitz3D Forums/Blitz3D Programming/HELP !!!! Single Surface Sprites and Texel Alignment

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

I am continuing to develop my 2D Single Surface system using 3D.

All is working great except for one problem. If you run the example (Download the graphic below and save as letters2.bmp) I get a blank spot down the middle of the display.



All the other coardinates work fine, but I cannot fix this.

Help !!!

If you save the code below to a .bb and put the image below in the same directory.

you should get 20 columns and 15 rows of 32x32 letters. All is great except the line in the middle (should be a green line)



;      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

Dim cosine#(360)
Dim sine#(360)

For a=0 To 359
    cosine(a) = Cos(a)
    sine(a) = Sin(a)
Next
;   640x480
Graphics3D 640,480,32,0
		ClearTextureFilters()
		AntiAlias off
		WBuffer off
Global scaleadd#=0.0
Global scaledir#=1


SetBuffer BackBuffer()

HUD_Camera=CreateCamera()
CameraRange HUD_Camera, 1,1000

;CameraClsMode HUD_Camera, False, False
EntityOrder HUD_Camera, -1

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


;cube=CreateCube()
;PositionEntity cube,0,0,3

;maincamera=CreateCamera()
;PositionEntity maincamera,0,0,-6
;cameraclscolor mainCamera,255,255,0
;cameraviewport mainCamera,128,0,384,480
Restore robdata

;Cameraviewport HUD_Camera,0,0,480,384


Read x$
n%=0

Local nAngle%=0

For z%=1 To Len(x$)
     If Mid$(x$,z%,1) <> " "

     	For b%=0 To 19
	      myletter.text3D_lettersprite = Text3D_AddLetter(mylettermesh,4,Int(Rnd(0,30)),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)
       	      ;Text3D_PositionLetter mylettermesh,myletter,rnd(0,(640)),rnd(0,480),32,32,nAngle
       	      Text3D_PositionLetter mylettermesh,myletter,b*32,z*32,32,32,nAngle,0
	Next

      End If
       n% = n% + 1
Next

;next

;CreateSideBars(myLetterMesh)
nStart%=MilliSecs()
While Not KeyHit(1)

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

       
       		;nAngle = nAngle + 6
       
       If nAngle = 360 Then nAngle = 0

       ;scaleadd = scaleadd + scaledir
       If scaleadd=128 Or scaleadd=-0 Then
             scaledir=-scaledir
       End If
   ;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,32,32,nAngle,scaleadd
       Text3D_PositionLetter mylettermesh,o,o\pos\x,o\pos\y,32,32,nAngle,0

       If o\pos\y > GraphicsHeight() Then o\movey=-o\movey
       If o\pos\y <0 Then o\movey=-o\movey
       If o\pos\x <128 Then o\movex=-o\movex
       If o\pos\x >(512) 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
;   turnentity mylettermesh\mesh,0,0,.1
   UpdateWorld
   
   RenderWorld
   Text 0,0,nCount%
   Text 0,16,nFPS
   nCounter = nCounter + 1
;   nTemp=MilliSecs()
;   Color 0,0,0
;   Rect 0,0,128,480
;      Rect 512,0,128,480
;      nTemp = (MilliSecs()-nTemp)
;     Color 255,255,255
;      Text 0,0,nTemp
      Flip False
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(HUD_Camera)
	 MoveEntity t\ent,0,0,320
	 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# - 205
   ;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


   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=2;Rnd(-3,3)
   mytempletter\movey=Rnd(-3,3)


   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#,width#=1,height#=1, Angle%=0, scaleadd#=0)



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


	y# = y# + yOffset
	x# = x# + xoffset

	 y=((240-y) + (height/2))
   	 x=((x-320+width)-(width/2))
	 width#=((scaleadd+width#))
	 height#=((scaleadd+height#))
	 
	 width# = (width#/2)
	 height# = (height/2)

	 text3d_plotletter t,l,x,y,Angle,0 ,-width,height
	 text3d_plotletter t,l,x,y,Angle,1,width,height
	 text3d_plotletter t,l,x,y,Angle,2,width,-height
	 text3d_plotletter t,l,x,y,Angle,3,-width,-height

;	VertexCoords t\surface,l\index,x-(width#),y+height#, 0
;	VertexCoords t\surface,l\index+1,x+width#,y+height#, 0
;	VertexCoords t\surface,l\index+2,x+width#,y-height#, 0
;	VertexCoords t\surface,l\index+3,x-width#,y-height#, 0


End Function

Function text3d_plotletter(t.text3D_lettermesh,l.text3D_lettersprite,x#,y#,angle%,index%,width#,height#)

	      new_x# = x + (width * Cosine(angle) - height * Sine(angle))
	      new_y# = y + (height * Cosine(angle) + width * Sine(angle))
	  	
      VertexCoords t\surface,(l\index+index%),new_x,new_y,1


End Function

.robdata
Data "01234567890123456789"



Big&(Posted 2003) [#2]
It looks like its a rounding error with the texture filtering. Which is not your fault.

If you turn off the texture mask by replacing the 4 with a 1 in the load texture, it comes back.

This is due to the filtering rapping around the texture. If you had a double pixel green line around all the text, I doubt if you would have noticed it. So get rid of the green and you should be fine as all the letters have a border around them anyway.


Rob Pearmain(Posted 2003) [#3]
Thanks for your help. This does add issues for the future, in that transparency will not work with "4" turned off, but then again, for tiles i could have it set as 1, and for main characters I could have a transparent border which will solve the issue

Many, MANY thanks for your help


jondecker76(Posted 2003) [#4]
try adding or subtracting 0.5 to the coords (use floats). I know I've read somewhere that for some reason textures are stored with a .5 offset. I believe there was a post on these forums about it as well somewhere


sswift(Posted 2003) [#5]
JonD:
It's not subtract 0.5, it's subtract have a texel. 0.5 is half your TEXTURE.

Half a texel is (1.0 / TextureWidth#) * 0.5 (or / 2.0)


sswift(Posted 2003) [#6]
Oh and it's not because the textures in Blitz are aligned improperly, it is just a effect caused by how Bilinear filtering works. The coordinate 0,0 is the top left corner of the top left texel. Which also happens to be halfway between the CENTER of the top left texel and the lower right texel. And since bilinear filtering smoothly interpolates between the colors in the image, if you're halfway between the center of two pixels then your color, and your masking, is halfway between them as well. So if one is red and the other blue, and one is opaque and the other transparent then 0,0 will be 50% transparent, and purple.


Rottbott(Posted 2003) [#7]
sswift, might that explain why I get the texture from the bottom of a quad bleeding into the top (and left edge into the right)? Or is that more likely to be a mipmapping issue?


sswift(Posted 2003) [#8]
Yes it's bilinear filtering.

It's only a mipmapping issue if that happens when the object is in the distance.

Mipmap bleeding is most often a problem with rendering darkbasic-like terrains with several textures contained in one texture. Then such bleeding is most likely to be visible, and hardest to combat.

If your quad had only one texture reptition, ie, UV coordinates only from 0..1, then you can use UV clamp on the texture flags to fix that issue.


Rottbott(Posted 2003) [#9]
then you can use UV clamp

Aha! Of course! Why didn't I think of that!? Thanks :-)


skidracer(Posted 2003) [#10]
I can't see what you are doing wrong but it looks like a rounding issue in your code somewhere...


jondecker76(Posted 2003) [#11]
thanks for clearing that up swift - I just vaguely recalled having seen something on here to that affect so I thought I would help out


Rob Pearmain(Posted 2003) [#12]
loadtexture(tex,1) works a treat (Try the code and change the line) but with no transparency :(

loadtexture (tex,2) works ok-ish

loadtexture(tex,4) causes the above issue


skidracer(Posted 2003) [#13]
I would consider it fixed when all your green lines are single pixel and solid which they aren't with loadtexture(tex,1).


Rob Pearmain(Posted 2003) [#14]
That's probably due to the vertex coloring, if you comment out the line in the addletter function

 Text3D_ColorLetter(t,mytempletter,r,g,b)


It will give a better representation


skidracer(Posted 2003) [#15]
That fixes the color, however the texel misalignment is still evident with the double thick lines you are getting even with loadtexture(tex,1).

This seems to fix it:

Function Text3D_PositionLetter (t.text3D_lettermesh,l.text3D_lettersprite, x#,y#,width#=1,height#=1, Angle%=0, scaleadd#=0)
	 l\pos\x = x#
   l\pos\y = y#
   l\pos\z = 0

	y# = y# + yOffset
	x# = x# + xoffset

	 y=((240-y) + (height/2))
   	 x=((x-320+width)-(width/2))
	 width#=((scaleadd+width#))
	 height#=((scaleadd+height#))
	 
	 width# = (width#/2)
	 height# = (height/2)

	x=x-.5
	y=y-.5
	VertexCoords t\surface,l\index,x-(width#),y+height#, 0
	VertexCoords t\surface,l\index+1,x+width#,y+height#, 0
	VertexCoords t\surface,l\index+2,x+width#,y-height#, 0
	VertexCoords t\surface,l\index+3,x-width#,y-height#, 0
End Function



Rob Pearmain(Posted 2003) [#16]
* Embarrassed Rob :-( *

Thanks Skidracer, I owe you one, nice work