Jump to content
  • Advertisement
Sign in to follow this  
Seiko

MDX - Precise quad sizes?

This topic is 4622 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

A few days ago I had a texture mapping problem. In short I could not and can still not map a section of a 512x512 (32x32) texture to a quad using point sampling without texture alignment problems. After several days of painful debugging it seems that either my quad sizes are not accurate enough to allow explicit point sampling texture mapping or my transforms are inaccurate thus not showing the full 32x32 pixels of each quad. As I've tested by rendering the same texture (albeit with various textures taken from the 512x512 map) for each tile and as on many of the tiles the texture is perfect I'm thinking the actual texture mapping is fine and the problem must be with my geometry or view trasnforms. BTW, when I say corruption I mean I'm rendering a simple square texture that has a 1 pixel internal square border. I've left a 5 pixel boundary so it's not an edge problem and yet the 1 pixel border looses one of it's lines on certain tile positions. As it's the entire line, i.e. on one tile the top line might be missing it just seems that the pixels and texels are not aligned for certain quads? As such I'd like to know if it is possible to guarantee a perfect 32x32 pixel quad (2 tris) irrespective of position on screen. This is obviously in relation to a top down tiled map but with every 4th/5th row/column currently showing signs of texture corruption i.e. one pixel/texel isn't aligned I suspect that the precision of a (single vb.net) means that I'm not guaranteed a 32x32 quad for each of my tile positions. You can see the maths below and with both the x and y using decimals I wonder if this means that quad boundaries vary ever so slightly? update : pic here http://img8.picsplace.to/img8/1/problem_000.jpg Can someone please assist this newbie as I've lost countless hours on this and don't seem to be getting any closer to a solution. BTW, here are my constants, transforms and vertex construction code snippets.
  Private Const cInternalScreenWidth As Integer = 1024
  Private Const cInternalScreenHeight As Integer = 768
  Private Const cMapTileWidth As Integer = 32
  Private Const cMapTileHeight As Integer = 32
  Private Const cTilePerScreenWidth As Integer = CInt(cInternalScreenWidth / cMapTileWidth)
  Private Const cTilePerScreenHeight As Integer = CInt(cInternalScreenHeight / cMapTileHeight)
  Private Const cTextureWidthScale As Single = 10 / cTilePerScreenWidth
  Private Const cTextureHeightScale As Single = 10 / cTilePerScreenHeight
 
--------------------------------------------------------------------------------
 'Matrices
  .Transform.World = Matrix.Identity 

  .Transform.View = Matrix.LookAtLH(New Vector3(Xposition, Yposition, 9), New Vector3(Xposition, Yposition, 0), New Vector3(0.0F, 1.0F, 0.0F))

  .Transform.Projection = Matrix.PerspectiveFovLH(1, 1.0F, 0.0F, 5.0F)
 

--------------------------------------------------------------------------------
 'Tile Vertex calcualtions for the entire map
 'cTextureWidthScale = 0.3125       -- Noted here for convenience
 'cTextureHeightScale = 0.416666657 -- Noted here for convenience

 For RowLoop As Integer = 0 To TotalVerticalMapTiles - 1
      For ColumnLoop As Integer = 0 To TotalHorizontalMapTiles - 1
        With MapTiles(ColumnLoop, RowLoop)
        
          'Assign verts and textures Triangle 1
          .X(1) = 6 - ((ColumnLoop + 1) * cTextureWidthScale)
          .Y(1) = 6 - (RowLoop * cTextureHeightScale)
        
          .X(2) = .X(1)
          .Y(2) = 6 - ((RowLoop + 1) * cTextureHeightScale)
        
          .X(3) = 6 - (ColumnLoop * cTextureWidthScale)
          .Y(3) = .Y(1)
        
          'Triangle 2
          .X(4) = .X(3)
          .Y(4) = .Y(2)
        
          .X(5) = .X(3)
          .Y(5) = .Y(1)
        
          .X(6) = .X(1)
          .Y(6) = .Y(2)
        
        End With

        TileCount = TileCount + 1

      Next ColumnLoop
    Next RowLoop

-------------------------------------------------------------------------------
 'Texture Coordiantes mappings
 Dim TexturesPerRow As Single = CSng(TemplateTextureWidth / cMapTileWidth)
 Dim TexturesPerColumn As Single = CSng(TemplateTextureHeight / cMapTileHeight)
 Dim Alignment As Single = CSng(1 / (TemplateTextureWidth * 2))

 ReDim MapTextures(CInt(TexturesPerRow * TexturesPerColumn))
 Dim OffsetX,OffsetY As Single

 For TextureNumber As Integer = 1 To (CInt(TexturesPerRow * TexturesPerColumn))

      OffsetX = CSng(((TextureNumber - ((Int(TextureNumber / TexturesPerRow) * TexturesPerRow))) * (cMapTileWidth)) - (cMapTileWidth - 2)) - 1
      OffsetY = CSng((Int(TextureNumber / TexturesPerColumn)) * (cMapTileHeight)) + 1

      With MapTextures(TextureNumber)
        ReDim .tu(6)
        ReDim .tv(6)

        .tu(1) = ((OffsetX + (cMapTileWidth - 2)) / TemplateTextureWidth) - Alignment
        .tv(1) = (OffsetY / TemplateTextureHeight) - Alignment

        .tu(2) = .tu(1)
        .tv(2) = ((OffsetY + (cMapTileHeight - 2)) / TemplateTextureHeight) - Alignment

        .tu(3) = (OffsetX / TemplateTextureWidth) - Alignment
        .tv(3) = .tv(1)

        .tu(4) = .tu(3)
        .tv(4) = .tv(2)

        .tu(5) = .tu(3)
        .tv(5) = .tv(1)

        .tu(6) = .tu(1)
        .tv(6) = .tv(2)

      End With
    Next TextureNumber





[Edited by - Seiko on November 24, 2005 8:38:27 AM]

Share this post


Link to post
Share on other sites
Advertisement
Have you already check this out: http://msdn.microsoft.com/library/en-us/directx9_c/Directly_Mapping_Texels_to_Pixels.asp?frame=true

Share this post


Link to post
Share on other sites
Quote:
Original post by Demirug
Have you already check this out: http://msdn.microsoft.com/library/en-us/directx9_c/Directly_Mapping_Texels_to_Pixels.asp?frame=true


Yep, that's why I think it's my geometry or projection. The fact that the same texture is ok on certain tiles suggests to me at least that the texture mapping is fine. Note too that the texture mapping are precalculated once only and then reused for the tiles. So my logic says if it is ok for one tile why not for another?

Share this post


Link to post
Share on other sites
I would assume a rounding problem with your vertex cords.

Have you tried working with pre transformed vertices? In the case of 2D with perfect texel to pixel mapping this is normally the better way.

Share this post


Link to post
Share on other sites
Quote:
Original post by Demirug
I would assume a rounding problem with your vertex cords.

Have you tried working with pre transformed vertices? In the case of 2D with perfect texel to pixel mapping this is normally the better way.


I did contemplate switching to pre transformed vertices but I really wanted to create a baseline using none transformed vertices as I use alot of matrices for the sprites movement and rotation. Although I could still no doubt use the matrices I was hoping to then bolster the engine with simplified lighting and shadowing techniques as my understanding progresses. Alas, I'm failing on the first task as I can't even control the precise quad size. (lol). I thought I could try and clamp values or something but I'm not really sure which values to clamp, round up or down!

Share this post


Link to post
Share on other sites
First off all you should make sure that your vertex cords are the problem. Can you render the tiles as wireframe and make a screenshot? This will make it possible to check the size of each tile. If they are not all 32*32 you can limit your search to the vertex cords.

As I don’t know the rest of your code it is possible that I am wrong but your matrix setup looks a little bit unusual for a 2D game.

Share this post


Link to post
Share on other sites
Quote:
Original post by Demirug
First off all you should make sure that your vertex cords are the problem. Can you render the tiles as wireframe and make a screenshot? This will make it possible to check the size of each tile. If they are not all 32*32 you can limit your search to the vertex cords.

As I don’t know the rest of your code it is possible that I am wrong but your matrix setup looks a little bit unusual for a 2D game.


My quads, including the wireframe lines are actually 36x35 pixels which you'd think would cause the problem but as I'm clamping the textures I thought I would see an area not covered or taken from an adajecent texel? If a single texel is applied to two pixels then I would have simply concluded that the texture mapping is incorrect due to the size but as I actually looose a texel it suggests to me that my transforms are the problem?

This really is a pain to get to the bottom of. BTW, thanks for the support!
:(

Share this post


Link to post
Share on other sites
Quote:
Original post by Demirug
Do you lost the texel inside the tile or on they edge?

Can post a screenshot that shows the problem?


Alas, I have no where to post a screen shot although I have now found out that my quad sizes are definately wrong in the areas with the texture problem. For the correctly textured tiles the quads are 36x35 however on the incorrect columns the quads are 37x35 thus the mapping gets a little skewed. This must be either my vertex construction or my projections? As for the textel loss or gain dependant on how I tweak my code it is well within the 32x32 texture area.

So how can I create a map of tiles that do not suffer from this imprecision?

Share this post


Link to post
Share on other sites
Usually I'm working in an ortho view when dealing with this problem but it may still work here. Generally, all of my 2D grapgics-objects have a few extra floating point memebers used for baising either the texture coordiantes, the vertex space coordiantes or even both. Generally these numbers are tiny say, 0.0005f Sometimes this does the trick, but the real problem is when I go to test on different hardrware. Nearly every card samples and rounds a different way and I'm still figuring a way around this. One way, belive it or not, is to use the baising along with bi-linear texture filtering. If the textures are designed well and the bais is just right, it seems to look pretty good on nearly every card.

Since you are working in perspective though, I really don't think there is any way that you can expect to properly map texles to pixels. Most hardware is concerned with speed, not accuracy.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!