Sign in to follow this  

Orthographic Projection, width/height

This topic is 1118 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello GameDev.net, first post here and hopefuly won't be my last ;).

 

I am required by college to use XNA and C# to produce a game for my graded unit, I am in the process of creating some utility classes to make it a little easier and one thing I am trying to get working is an Orthographic Camera.

 

I want to be able to define a camera with custom viewport width/height, however all I seem to be getting is well, weird results.

 

With this:

projection = Matrix.CreateOrthographic(viewportWidth, viewportHeight, near, far);

Assuming width and height are the same as the window, so 800x600, all I get is a very very very small little viewport at the top left hand side of the screen. If I pass in values of 2x2 I get the same result I would have without changing the batches projection matrix.

 

What am I doing wrong here? I even tried creating a view matrix and combining them:

view = Matrix.CreateLookAt(position, new Vector3(0, 0, 0), direction);
combined = projection * view;

Position is just 0, 0, 0, direction is 

Vector3.Up;

I am a little lost with this :S

 

Share this post


Link to post
Share on other sites


[view matrix] Position is just 0, 0, 0,...

 

To generate a view matrix requires determination of both the camera position and the direction the camera is to face. With the position and focus point the same, the direction the camera is to face is indeterminate. Provide some distance between the camera and the origin.

 


Assuming width and height are the same as the window, so 800x600

 

Don't confuse view with viewport. That is, the width and height for ortho matrix generation should be in world units.

 

E.g., you have a sphere of radius 5 units at the origin. For the view matrix, place the camera at (10, 0, 0) [10 units along the +X axis], looking at the origin (0,0,0). For the projection matrix, to generally view the entire sphere with some distance to each side, set the width and height to 20 units, with near and far planes something like 2 and 30 (world units) respectively.

 

The result is the camera at X==10, looking down the -X axis toward the origin, and the sphere (5 units in radius, 10 units in diameter) will be centered in a 20x20 unit view. Because the near/far planes are 2 and 30 respectively (distances from the camera), objects within the range of X from +8 (2 units from the camera) to -20 (30 units from the camera) will be rendered.

Share this post


Link to post
Share on other sites

Maybe change this:

projection = Matrix.CreateOrthographic(Width,Height,near,far);

to something like this:

projection = Matrix.CreateOrthographicOffCenter(left,right,bottom,top,near,far);

Where left is 0, right is width, bottom is height and top is 0 and near could be say -2000 and far +2000 if you really wanted..

Also good to translate the projection -0.5 up and -0.5 left to get good pixel alignment (could just leave view as identity and use a world matrix to move scene)

Share this post


Link to post
Share on other sites
combined should be:
 
combined = view * projection;
But you typically don’t have a view matrix with orthographic projections.

I would like to have proof of your results. I doubt that if you change the parameters in your projection matrix you get the same results. In other words, you may think you are changing values, but you aren’t. This means you think you are setting the viewport or projection matrix, but it is either being overwritten or not actually set.

You need to verify that both are being set and not being overwritten.


L. Spiro

Share this post


Link to post
Share on other sites

I would like to have proof of your results. I doubt that if you change the parameters in your projection matrix you get the same results. In other words, you may think you are changing values, but you aren’t. This means you think you are setting the viewport or projection matrix, but it is either being overwritten or not actually set.

You need to verify that both are being set and not being overwritten.

 
They are definitely being applied, as I can change the hard-coded value. Thanks for your replies but I am still a little stumped.
 
I am not quite sure what to tell you, I'll show you some screen shots with corresponding code:
 
Here is the camera code, this is called in the loop (which I understand needs to be done for any camera that can translate, move etc).
 

       public void Update(){
           projection = Matrix.CreateOrthographic(viewportWidth, viewportHeight, near, far);
           view = Matrix.CreateLookAt(new Vector3(viewportWidth / 2, viewportHeight / 2, 0), new Vector3(0, 0, 0), direction);
           combined = view*projection;
       } 

I have a little renderer class that draws for me and you can pass in a matrix for it to use, default it just uses identity matrix.
 

projection = Matrix.Identity;
batch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, projection); 

 
 So I pass in the values of GraphicsDevice.Viewport, like so:
 

            cam = new OrthographicCamera(tests.GraphicsDevice.Viewport.Width, tests.GraphicsDevice.Viewport.Height);
            renderer.SetProjectionMatrix(cam.Projection);

This is very difficult to see, but in the top left corner you can see a tiny little dot (it moves for me as it is animated, so easier to spot):
 

[spoiler]

Dot.png
 [/spoiler]
 
If I pass in a value of 2x2 like so:
 


            cam = new OrthographicCamera(2, 2);

[spoiler]

Looks_Normal.png
 [/spoiler]
 
This is with a value of 1x1:
 

            cam = new OrthographicCamera(1, 1);

[spoiler]

Zoomed_looking.png
[/spoiler] 

 

Now if I don't pass in any matrix into the batch, it looks the exact same as 2x2:

 

[spoiler]
 

No_matrix.png

[/spoiler]

Edited by Gibbo3771

Share this post


Link to post
Share on other sites

You need to investigate how that renderer class works and how its shaders are written because it is very obvious that it defines things in terms of “quadrants” per X and Y.

NDC space ranges from -1 to 1 in both X and Y, which means 2 units wide and 2 units tall.

So if you pass 2-by-2 you get a 1-to-1 ratio.

If you pass 1-by-1 it stretches 1 unit over the 2-unit range and your image is twice as big.

If you pass 800 for X, your image is 400 times thinner.

 

 

This is abnormal behavior and you should find the root of it.

 

 

L. Spiro

Share this post


Link to post
Share on other sites
XNA's spritebatch already has a default ortho projection for (Windows style) screen/pixel coordinates. The last parameter of this Begin() overload has a different meaning (it's actually not quite obvious reading the docs). Here are a couple of posts on stackoverflow about it (there are follow-up links in the answer).

Share this post


Link to post
Share on other sites

Thanks for all the replies!

 

I have managed to solve my problem, I am essentially scaling everything into world coordinates using a scale matrix and Vector2.Transform for any screen coordinates that need to be turned into world coordinates.

Share this post


Link to post
Share on other sites

This topic is 1118 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this