# Inverted textures

I'm trying to draw textures aligned with this physics body whose coordinate system's origin is at the center of the screen. (XNA)Spritebatch has its default origin set to top-left corner. I got the textures to be positioned correctly, but I noticed my textures are vertically inverted. That is, an arrow texture pointing Up , when rendered points down. I'm not sure where I am going wrong with the math.

My approach is to convert everything in physic's meter units and draw accordingly.

        Matrix proj = Matrix.CreateOrthographic(scale * graphics.GraphicsDevice.Viewport.AspectRatio, scale, 0, 1);
Matrix view = Matrix.Identity;

effect.World = Matrix.Identity;
effect.View = view;
effect.Projection = proj;

effect.TextureEnabled = true;
effect.VertexColorEnabled = true;

effect.Techniques[0].Passes[0].Apply();
SpriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, DepthStencilState.Default, RasterizerState.CullNone, effect);

SpriteBatch.End();


       SpriteBatch.Draw(paddleTexture,
mBody.Position,
null,
Color.White,
0f,
new Vector2(16f, 16f),  // origin of the texture
0.1875f, SpriteEffects.None,   // width of box is 3*2 = 6 meters. texture is 32 pixels wide. to make it 6 meters wide in world space: 6/32 = 0.1875f
0);


The orthographic projection matrix seem fine to me, but I am obviously doing something wrong somewhere! Can someone please help me figure out what am i doing wrong here ?

Thanks

• Is scale negative? Do you do anything special in the vertex/pixel shader for the effect you're using (specifically how do you manipulate/use texture coordinates?) Also if you're using XNA4 don't you want to be passing the effect in to the Begin() call of the batch, rather than trying to invoke it manually? – Josh Feb 2 '11 at 17:39
• scale is usually anywhere from 50 to 150. Its never negative. I'm not doing anything extra than what I specified here. I create the effect only to use the projection matrix. I am using XNA4, and I do pass the effect as a parameter to Spritebatch.Begin(see last parameter); but when I did that..no texture showed up. I had to manually invoke to make the textures start appearing on the screen. – brainydexter Feb 2 '11 at 17:57
• Oh, I missed the Begin call. In XNA, texcoords of (0,0) are the top-left corner of the image. But it doesn't sound like you have sufficient control of the texcoords here to have messed that up. – Josh Feb 2 '11 at 18:00
• Yup. I don't understand how spritebatch handles the projection matrices in effect and I think that is where lies the answer to my problem. – brainydexter Feb 2 '11 at 18:04
• You could always check out the source code for the spritebatch (SpriteEffect) to see if it helps your understanding: create.msdn.com/en-US/education/catalog/sample/stock_effects – Joel Martinez Feb 9 '11 at 18:11

Look at the reference of Matrix.CreateOrthographic, and notice that it says this:

The viewable area of this orthographic projection is centered on 0,0,0. The x-axis of the area ranges from -width/2 to width/2. The y-axis of the area ranges from -height/2 to height/2.

So, in your case, the upper border of the screen has an Y coordinate of -scale/2 instead of 0, and the lower border is scale/2 instead of scale. And if you are drawing a quad of size (10,10) at the coordinates (0, 0), its point of origin will be at the center of the screen, but since your positive Y is downwards, you will see it inverted.

Your best choices are just to invert the second parameter so your Y axis points upwards, or define the orthographic matrix with Matrix.CreateOrthographicOffCenter so you can manually specify the world origin.

I think you should be able just invert things using your effects world matrix:

effect.World = Matrix.CreateScale(1, -1, 1);


Instead of using the identity, as you have now.

I hope this helps.

There's no need to manually create and assign your effect's transformation matrices. Spritebatch creates these for you. The simplest way is to create an effect with no vertex shader (unless you're doing something in there besides the expected world-view-projection), since SpriteBatch already has a vertex shader that will take care of the transformation. Then it will use your pixel shader.

Also, I'm not sure if the way you're currently doing it works correctly, but there is a different overload of spriteBatch.Begin that takes an Effect as a parameter. I'm not sure if SpriteBatch can properly assign to the current effect if you don't pass it in on Begin().