I am making a tile based game. Recently I moved to drawing tiles as primitives to speed up things and also allow for easier lighting (Vertex Shader).

I then took it a step further and made some calculations to "merge" together tiles into the same primitive to gain even more performance, and to get around UV texture problems I simply did this...

if (!top)
    //Adds the top vertices
    thisquad.Vertices[0] = new VertexPositionTexture(new Vector3(new Vector2(p.X, p.Y), 0), new Vector2(0, 0));
    thisquad.Vertices[1] = new VertexPositionTexture(new Vector3(new Vector2(Tile.Size + p.X, p.Y), 0), new Vector2(1, 0));
    top = true;
//Extends the bottom vertices
thisquad.Vertices[2] = new VertexPositionTexture(new Vector3(new Vector2(p.X, Tile.Size + p.Y), 0), new Vector2(0, currentquadtilecount));
thisquad.Vertices[3] = new VertexPositionTexture(new Vector3(new Vector2(Tile.Size + p.X, Tile.Size + p.Y), 0), new Vector2(1, currentquadtilecount));

With currentquadtilecount starting at 1, if a tile is floating on its own it will display the texture properly, but for every second tile that merges, the texture is flipped. As shown below...

Example Image

What am I doing wrong? Is this even the right way to do this??


  • \$\begingroup\$ And did it speed things up? I always found SpriteBatch to be very efficient when used correctly (probably more than a typical hand rolled version). And by the way you can do both vertex/pixel shaders and tile merging quite easily with the SpriteBatch too. \$\endgroup\$ – David Gouveia Dec 31 '11 at 12:21
  • \$\begingroup\$ E.g. For a vertex shader example with SpriteBatch check this. There's also a pixel shader version at the end which I left in for future reference. Basically pass the effect to SpriteBatch.Begin(). As for merging tiles together with SpriteBatch, read this (although it was written before XNA4 came out). Basically turn on TextureAddressMode.Wrap and use a source rectangle corresponding to the size you want the entire merged area to be. \$\endgroup\$ – David Gouveia Dec 31 '11 at 12:28
  • \$\begingroup\$ Oh yes it did! (I have a key to change between 2D and 3D drawing) With a full screen of tiles, 2D was running at 500fps. while 3D ran at 800-900fps. \$\endgroup\$ – FrenchyNZ Dec 31 '11 at 12:35
  • \$\begingroup\$ That's really cool then! I've read about this before, maybe I'll look into it sometime. :-) \$\endgroup\$ – David Gouveia Dec 31 '11 at 12:41
  • \$\begingroup\$ Yup! That Nuclex Framework looks quite interesting, I tried to do a similar thing (group batching) and found that building up the list of Vertices and Indices was much slower, so gave up on that idea. Feel free to ask for my source for my primitive drawing whenever. :) \$\endgroup\$ – FrenchyNZ Dec 31 '11 at 12:47

I'm almost sure this is because you're using TextureAddressMode.Mirror instead of TextureAddressMode.Wrap.

Change the value in the sampler state before rendering the primitives. I think it should be something like:

GraphicsDevice.SamplerStates[0].AddressU = TextureAddressMode.Wrap;
GraphicsDevice.SamplerStates[0].AddressV = TextureAddressMode.Wrap;
  • \$\begingroup\$ It is already .Wrap by default, and changing it to Mirror or Clamp does not work either.. ? \$\endgroup\$ – FrenchyNZ Dec 31 '11 at 12:29
  • \$\begingroup\$ Are you sure it's not being changed to Mirror somewhere between that point and when the primitives are finally drawn? Do a System.Diagnostics.Debug.WriteLine(GraphicsDevice.SamplerStates[0].AddressU); right before the line that actually draws the primitives. \$\endgroup\$ – David Gouveia Dec 31 '11 at 12:33
  • \$\begingroup\$ Ahh derp.. Found the problem... I was setting the UV Address mode WITHIN the Shader.. sampler TextureSampler = sampler_state { texture = <xTexture>; magfilter = LINEAR; minfilter = LINEAR; mipfilter = NONE; AddressU = wrap; AddressV = wrap;}; fixed it.. \$\endgroup\$ – FrenchyNZ Dec 31 '11 at 12:38
  • \$\begingroup\$ Glad you found it. That was going to be my next suggestion, because I wasn't sure if you were already using a shader or not. \$\endgroup\$ – David Gouveia Dec 31 '11 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.