[SOLVED] Weird behavior when tiling textures on 3D plane

Hello everybody, I have been following the guide on this page to create a 3d plane using coordinates instead of models. I have pretty much followed the guide exactly so I won’t paste my source code since it is listed there. The issue I am having is when I get to the part about rendering textures and tiling them by using a value greater than 1 for the texture coordinates.

Here is an image of the result I get when I set my texture “repetitions” as they are called in the guide to 3. This should tile the texture 3 times on each axis, for a total of 9 squares. As you can see, it is nearly right as the one square that is rendered correctly takes up 1/9th of the total plane.

I have checked and double checked to make sure I have all my coordinates set correctly, so I am not sure what could be causing this. As I said before, my code is nearly identical to the code on the page, with the only exception that I took out the DrawFloor() method and just did it directly in Draw(), and I moved the camera variables like cameraPosition and cameraLookAt to be class members so I can display their values on the UI.

If anybody has any insight into what may be going on, I would really appreciate it. I am fairly new to this sort of work as I have usually used prebuilt engines such as Unity, but I am very interested in starting from the ground up.

Look into SamplerState for the texture, AddressU and AddressV have to be right to enable the textures to repeat:


From DX9:


typedef enum D3D11_TEXTURE_ADDRESS_MODE {


Thank you both for your answers! I am going to start looking into SamplerState immediately.

@Alkher I am actually using OpenGL as I am developing on linux, is there an OpenGL equivalent? Looking further into the details in the page you linked, it definitely looks like this is exactly what I would have needed, if I were using DirectX, as this is exactly the effect I am currently getting.

I really appreciate both of your help!

EDIT: I have tried messing with SamplerState a little but but cannot seem to get it to have any change on my program. I am setting the first index in the Initialize() method like so,

GraphicsDevice.SamplerStates[0] = new SamplerState() { Filter = TextureFilter.Point, AddressU = TextureAddressMode.Wrap, AddressV = TextureAddressMode.Wrap };

Am I missing a step somewhere?

I believe it is the same values for opengl.
With monogame if i’m not wrong, all glsl is translated to hlsl before building an xnb.
May it be lost while translating ?
But it would be better to setup your sampler in your effect and not in C#

@Alkher Interesting, I feel like I may have bitten off a bit more than I was ready for with this, as I have never done work with OpenGL or shaders before. I am still going to push on though since this is the best way to learn.

When you say it would be best to setup the sampler in the effect are you talking about the BasicEffect that is defined near the start of the guide I posted? Is there another way to edit this effect as opposed to the C# code? Sorry if I’m not asking the right questions, as I said I am very new to this stuff.

EDIT: Sorry for the rapid posting. I have researched a bit more and it looks like I need to use .fx files to do shader programming. I am going to work on this a bit and get back with my results.

Alright! It took a lot of reading but I think I get the basics of shaders now. I have written a simple shader and am trying to test it, but notice some weird behavior. My quad was no longer appearing, but my text was still there. I removed the drawing code for text and now notice that the quad then renders correctly. Something about drawing from the sprite batch is making the quad disappear.

If I put the code to draw UI text AFTER the drawing code for the quad, it appears for a split second then disappears and only the text is show. I must be doing something wrong but I can’t seem to figure it out. Here is my code in Draw()


foreach (var pass in effect.CurrentTechnique.Passes)
graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, floorVerts, 0, 2);

spriteBatch.DrawString(font, “Camera Position”, new Vector2(10, 10), Color.White);
spriteBatch.DrawString(font, "X: " + cameraPosition.X, new Vector2(10, 25), Color.White);
spriteBatch.DrawString(font, "Y: " + cameraPosition.Y, new Vector2(10, 40), Color.White);
spriteBatch.DrawString(font, "Z: " + cameraPosition.Z, new Vector2(10, 55), Color.White);

spriteBatch.DrawString(font, “Camera Rotation”, new Vector2(10, 80), Color.White);
spriteBatch.DrawString(font, "X: " + MathHelper.ToDegrees((float)Math.Atan2(cameraPosition.Z - cameraLookAtVector.Z, cameraPosition.Y - cameraLookAtVector.Y)), new Vector2(10, 95), Color.White);
spriteBatch.DrawString(font, "Y: " + cameraLookAtVector.Y, new Vector2(10, 110), Color.White);
spriteBatch.DrawString(font, "Z: " + cameraLookAtVector.Z, new Vector2(10, 125), Color.White);


And yes, the code for calculating camera angles is sloppy and unfinished, I was using it primarily for testing.

EDIT: Sorry for this monster of a thread. I was able to solve this issue following the instructions on this page. I’m going to go ahead and mark this issue as resolved as I believe I have all the necessary knowledge to get going. Thanks @Alkher and @Kwyrky for getting me started! This has been a huge learning process and I’m sure there is much more to go.

I am not using SpriteBatch that often but I think it sets some values that you should change again before rendering your models.

Found this: https://blogs.msdn.microsoft.com/shawnhar/2010/06/18/spritebatch-and-renderstates-in-xna-game-studio-4-0/

So it seems SpriteBatch is using these values:

GraphicsDevice.BlendState = BlendState.AlphaBlend;
GraphicsDevice.DepthStencilState = DepthStencilState.None;
GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearClamp;

You might want to consider using maybe these values before rendering your models:

GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;