Microsoft Developer Network >
Forums Home
>
Archived Forums Forums
>
XNA Game Studio Express
>
Orthographic Perspective/Drawing in 2D
Orthographic Perspective/Drawing in 2D
- This should be simple, but I'm having trouble getting it to work. I sort of understand matrices. I understand them enough to use projection matrices and I have before, but for some reason I'm unable to get the right orthographic projection. All I want is an orthographic projection matrix that uses the same coordinates as the viewport so that placing a point at (0,0,0) is the top left and (screenWidth, screenHeight, 0) is the bottom right. I've tried two different ones (both orthographic matrix creation methods), but neither yielded proper results.
b.effect.View = Matrix.CreateLookAt(
new Vector3(
(float)graphics.GraphicsDevice.Viewport.Width / 2f,
(float)graphics.GraphicsDevice.Viewport.Height / 2f,
-5f
),
Vector3.UnitZ,
Vector3.Up
);
//b.effect.Projection = Matrix.CreateOrthographic(
// (float)graphics.GraphicsDevice.Viewport.Width,
// (float)graphics.GraphicsDevice.Viewport.Height,
// .01f,
// 100f
//);
b.effect.Projection = Matrix.CreateOrthographicOffCenter(
0f,
(float)graphics.GraphicsDevice.Viewport.Width,
(float)graphics.GraphicsDevice.Viewport.Height,
0f,
.01f,
1000f
);
If those are correct perhaps my drawing code is incorrect. I know I'm generating the proper vertices, but I'm not 100% sure if I'm drawing them properly:
public override void Draw(GameTime gameTime)
{
GraphicsDevice.Vertices[0].SetSource(vb, 0, VertexPositionColor.SizeInBytes);
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
GraphicsDevice.VertexDeclaration = vd;
GraphicsDevice.DrawPrimitives(
((DrawType == BezierDrawType.Line) ? PrimitiveType.LineStrip : PrimitiveType.PointList),
0,
verts.Length
);
pass.End();
}
effect.End();
}
Answers
- Nick- I do the exact same thing, use these matrices:
Matrix world = Matrix.Identity;
Matrix view = new Matrix(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
Matrix projection = Matrix.CreateOrthographicOffCenter(
0, this.Width, -this.Height, 0, 0, 1);
// The view flips the Y axis so it's going down instead of the default up.
// The view also flips the Z axis, (so that we remain right-handed.)
// The projection is choosing to render the bottom right quadrant, so it uses -height.
-- View matrix flips the y (and z)
-Y
|
|
-------0,0---------->X(800)
|///////////////////////////////
|/////////////////////////////// <- Ortho projection part, specified as (0, Width, -Height, 0)
|///////////////////////////////
+Y(600)
All Replies
- What are you using as the Z coordinate in your vertices?
Your matrix sets the clip planes to 0.01 and 1000, so if your vertices have 0 z, they will be culled. - That should've been something I thought of. Even after fixing that though, I still get nothing. Maybe I am creating the vertices wrong. I'm trying to implement a bezier curve, so not seeing it might be because my method is incorrect. Here's my loading and computation (for the example my Steps is set to 10000 I believe and compute is initially at true):
protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
effect = new BasicEffect(GraphicsDevice, null);
effect.DiffuseColor = new Vector3(1f, 1f, 1f);
effect.World = Matrix.Identity;
vd = new VertexDeclaration(GraphicsDevice, VertexPositionColor.VertexElements);
if (compute)
{
generateCurve();
compute = false;
}
}
base.LoadGraphicsContent(loadAllContent);
}
void generateCurve()
{
verts = new VertexPositionColor[steps + 1];
vb = new VertexBuffer(
GraphicsDevice,
VertexPositionColor.SizeInBytes * (steps + 1),
ResourceUsage.None,
ResourceManagementMode.Automatic
);
float step = 1f / (float)steps;
Vector2 a, b, c;
c.X = 3f * (start.ControlPoint1.X - start.Point.X);
b.X = 3f * (end.ControlPoint2.X - start.ControlPoint1.X) - c.X;
a.X = end.Point.X - end.ControlPoint2.X - b.X - c.X;
c.Y = 3f * (start.ControlPoint1.Y - start.Point.Y);
b.Y = 3f * (end.ControlPoint2.Y - start.ControlPoint1.Y) - c.Y;
a.Y = end.Point.Y - end.ControlPoint2.Y - b.Y - c.Y;
int j = 0;
for (float i = 0f; i <= 1f; i += step)
{
float i3 = (float)Math.Pow(i, 3f);
float i2 = (float)Math.Pow(i, 2f);
float x = a.X * i3 + b.X * i2 + c.X * i + start.Point.X;
float y = a.Y * i3 + b.Y * i2 + c.Y * i + start.Point.Y;
verts[j++] = new VertexPositionColor(new Vector3(x, y, 0f), Color.White);
}
vb.SetData<VertexPositionColor>(verts);
} - This is where I'd pull out PIX for Windows. Looking at a capture of the frame in question, you can debug your draw calls to easily see if they're failing entirely, or drawing just off the screen, or maybe drawing in the right place but coming out black for some reason. Armed with that information, it's usually a lot easier to find which bit in the code is going wrong.
- It's drawing, just off screen. I think a tiny bit is actually hitting the top left corner, but all the vertices in the draw call are the same that I set, so I don't know why it'd be off the screen like that.
- I found one error, not the main one, in that I was having XNA draw one more vertex than I had in the array, but that's not causing it to be offscreen.
I've uploaded the whole project so if anyone wants to download it to help me out (just 28k), I'd appreciate it.
http://cis.gvsu.edu/~gravelyn/BezierCurves.zip - Nick- I do the exact same thing, use these matrices:
Matrix world = Matrix.Identity;
Matrix view = new Matrix(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
Matrix projection = Matrix.CreateOrthographicOffCenter(
0, this.Width, -this.Height, 0, 0, 1);
// The view flips the Y axis so it's going down instead of the default up.
// The view also flips the Z axis, (so that we remain right-handed.)
// The projection is choosing to render the bottom right quadrant, so it uses -height.
-- View matrix flips the y (and z)
-Y
|
|
-------0,0---------->X(800)
|///////////////////////////////
|/////////////////////////////// <- Ortho projection part, specified as (0, Width, -Height, 0)
|///////////////////////////////
+Y(600)
- Thanks a ton. Now I just have to figure out how to get the curve to draw right...
