Take the 2-minute tour ×

I am drawing a rectangle with primitives in XNA. The width is:

width = GraphicsDevice.Viewport.Width 

and the height is

height = GraphicsDevice.Viewport.Height

I am trying to fit this rectangle in the screen (using different screens and devices) but I am not sure where to put the camera on the Z-axis. Sometimes the camera is too close and sometimes to far.

This is what I am using to get the camera distance:

//Height of piramid
float alpha = 0;
float beta = 0;
float gamma = 0;

alpha = (float)Math.Sqrt((width / 2 * width/2) + (height / 2 * height / 2));
beta = height / ((float)Math.Cos(MathHelper.ToRadians(67.5f)) * 2);
gamma = (float)Math.Sqrt(beta*beta - alpha*alpha);

position = new Vector3(0, 0, gamma);

Any idea where to put the camera on the Z-axis?

share|improve this question
What scenes is it too close for and what scenes it too far away? Your code looks like it should be producing consistent results. Also what projection are you using - perspective or parallel/orthographic? –  ChrisF Aug 30 '12 at 12:10
I'm using perspective with fov:PiOver4. Just want the primitive rectangle that I draw to fit the screen when I load the game (since its size is equal to the screen) –  alecnash Aug 30 '12 at 12:14
Can you post screen shots of the "too close" and "too far" cases? –  ChrisF Aug 30 '12 at 12:15
Lets say the rectangle is red. On a windows machine the whole screen becomes red and I have to zoom out a lot so that I can see tha background. On the windows phone its the other way around. The rectangle seems smaller so I see the background and I have to zoom in to fill the screen. –  alecnash Aug 30 '12 at 12:18
What is the purpose? A full screen effect? –  Andrew Russell Aug 30 '12 at 12:20
show 1 more comment

1 Answer

up vote 1 down vote accepted

The trick to doing this is to draw the rectangle directly in raster space. This is the space that the GPU works in when actually rendering stuff.

Normally your model starts in its own model space, you apply a world transform to get it into world space. You then apply a view transform to move the points in the world around the camera (to get the effect of the camera moving around the world). Then you apply a projection matrix to get all those points into the space that the GPU uses for drawing.

It just so happens that this space is always - no matter the screen size - from (-1,-1) in the bottom left corner of the viewport, to (1,1) in the top right (and from 0 to 1 on the Z axis for depth).

So the trick is to set all your matrices (world, view, project) to Matrix.Identity, and then draw a rectangle from (-1,-1,0) to (1,1,0). You probably also want to set DepthStencilState.None so that it doesn't affect the depth buffer.

An alternative method is to just use SpriteBatch and draw to a rectangle that is the same size as the Viewport.

share|improve this answer
I am going to try it out. A question though, why should the SpriteBatch have a different behavior than the primitive? –  alecnash Aug 30 '12 at 12:48
It doesn't. SpriteBatch has an implicit orthographic projection matrix that covers the screen (properly pixel aligned and everything). It transforms client space to raster space. After being transformed, the quad that SpriteBatch creates should land at coordinates as if you put it their directly. The reason I mention it is that it can a bit easier to simply throw together (particularly if you are already doing 2D work). –  Andrew Russell Aug 30 '12 at 13:51
the pyramid was a wrong approach. I just used the Tan and it worked. Also tested your solution and it works. –  alecnash Sep 6 '12 at 14:44
add comment

Your Answer


