So, question in the title. I don't know how to create infinite seamless background.
-
\$\begingroup\$ Some graphics engines support values outside of the [0..1] range for u,v coordinates. Maybe if you set the texture coordinates to (0,0), (0,5), (5,0), (5,5) you might get the texture repeated five times in the same rectangle, without having to draw multiple rectangles. The performance difference is likely marginal though. \$\endgroup\$– Panda PajamaJan 21, 2013 at 3:15
2 Answers
Well, I solved this.
You can wrap your texture with SamplerState
_spriteBatch.Begin(SpriteSortMode.Deferred, null, **SamplerState.LinearWrap**, null, null);
_spriteBatch.Draw(texture,startPosition, new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height), Color.White, 0, Vector2.Zero, 1f, SpriteEffects.None, 0);
_spriteBatch.End();
And you will draw a texture just once!
Thanks to David Gouveia
-
\$\begingroup\$ Just to be clear, it's the wrap part that matters. There's also
PointWrap
andAnisotropicWrap
. \$\endgroup\$ Nov 11, 2015 at 8:05 -
\$\begingroup\$ This works for changing the window size, but on maximizing the window the texture gets stretched. \$\endgroup\$ Aug 26, 2018 at 17:10
I don't think XNA supports such behavior directly (I might be wrong, though I'm pretty sure it's not the case). (EDIT: This can be done in XNA, see edwing's self-answer.) You can do this manually however.
The idea is simple: see how many rectangles identically sized to the texture fit into your parent rectangle. Then, draw that many rectangles inside of your parent rectangle. Also check if there is unoccupied space left while drawing (if the parent rectangle could not be evenly divided into texture rectangles). Do the math and see what sizes the divided texture rectangles should be.
Here's a rough drawing to get a better idea on the whole matter:
Some pseudo-code to get you started:
CompleteTextureRectsOnHorizontal = ParentWidth div TextureWidth //Integer division
CompleteTextureRectsOnVertical = ParentHeight div TextureHeight //Represents the number of textures that completely fit into the parent rectangle, vertically. The above is the same but horizontally.
ExtraOnHorizontal = ParentWidth - (CompleteTextureRectsOnHorizontal * TextureWidth) //Represents how much space exists between the last texture that fitted perfectly and the rectangle's rightmost bound (if this is 0, then all textures fitted perfectly, horizontally - there's no need to draw half a texture and whatnot).
ExtraOnVertical = ParentHeight - (CompleteTextureRectsOnHeight * TextureHeight) //Same as above, but vertically.
You should proceed by doing something like:
spriteBatch.Draw(Texture, new Rect(location.x, location.y, TextureWidth, TextureHeight);
for complete texture rects. Then, for the textures that don't really fit it completely, you draw like this:
spriteBatch.Draw(Texture, new Rect(location.x, location.y, ExtraOnHorizontal, TextureHeight); //For textures that fit in vertically, but not horizontally.
spriteBatch.Draw(Texture, new Rect(location.x, location.y, TextureWidth, ExtraOnVertical); //For textures that fit in horizontally, but not vertically.
spriteBatch.Draw(Texture, new Rect(location.x, location.y, ExtraOnHorizontal, ExtraOnVertical); //For textures that don't fit either way. This is normally the texture in the lower right corner of the parent rectangle.
Remember to update the location of each newly drawn texture rect, relative to the previously drawn texture (adding the texture's width to the previously drawn texture's X coordinate gives you your new texture rect's X coordinate, for example).
-
\$\begingroup\$ Let me know if you run into any issues. Just keep this in mind: you're drawing a 2-dimensional array (like a normal table) of textures inside of a rectangle, until you fill it up. \$\endgroup\$– user15805Jan 21, 2013 at 0:15
-
\$\begingroup\$ uh, i found another solution! Actually, there is one method XNA provide! \$\endgroup\$– edwingJan 21, 2013 at 12:10
-
1\$\begingroup\$ I added a note to point at edwing's answer - given that he's got the usual and more-correct method. But I won't down-vote this method because it's valid in some circumstances (eg: if you're using texture atlases and can't use a wrapping sampler). Although it's worth pointing out that you almost never need to perform the clipping yourself (as you have done here) - generally you'd just draw the whole tile and let the GPU clip it. \$\endgroup\$ Jan 21, 2013 at 13:19
-
\$\begingroup\$ I stand corrected then, I did not know of it. \$\endgroup\$– user15805Jan 21, 2013 at 14:52