0
\$\begingroup\$

I just started working in MonoGame with 3D code. I've used OpenGL before in the past, and I've also built engines with 2D Sprites/SpriteBatch's in MonoGame.

However, I'm getting extremely stumped with going from GL to XNA, likely due to the fact that I believe XNA is no longer a "state" machine like GL is.

I've looked thru the tutorials by RB Whitaker and Riemers -- but most of the stuff they have written covers models, etc. I've already migrated some of my code to build procedural meshes into a VertexBuffer. I'd like to test it now, but I'm getting very confused as to how to setup the World, View, Projection matrices, etc.

Are there any good tutorials that either show how to move from GL to XNA -- or optionally -- any good tutorials that assume you're not using Models, etc? I'm looking to write something fairly low-level when it comes to primitives.

\$\endgroup\$
1
\$\begingroup\$

The three matrices are used regardless you use models or draw primitives. They have a specific purpose:

The camera matrix defines the point of view in the 3D world, it has a position and a target where the camera is pointed at.

The projection matrix defined what your screen looks like- where you want to project the 3D scene to. It contains the aspect ratio and dimensions of the target you want to render to. It also has a field of view (wide angle or narrow view).

The world matrix defines where an object is located in the 3D world. It contains rotations, translations and scale.

In the most simple application you define your projection matrix for your screen once per game. Your camera once per frame and world matrix per frame and object.

In XNA the BasicEffect has the shader basics needed to draw in 3D. As per Whitaker tutorial:

 BasicEffect basicEffect;
 Matrix world = Matrix.CreateTranslation(0, 0, 0);
 Matrix view = Matrix.CreateLookAt(new Vector3(0, 0, 3), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
 Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800f / 480f, 0.01f, 100f);

When you use these matrices to draw anything the object will be at the origin (world matrix sets a translation at 0,0,0) sets the camera at 0,0,3 looking at 0,0,0 where 0,1,0 defines the up direction. Finally the projection has a viewing angle of 45 degrees, sets the aspect ratio for a 800/480 viewport, where the minimum distance is 0.1 and the max distance to render is 100.

Use these matrices to test draw some vertices (both Riemers and Whitaker have a basic triangle as starting point).

\$\endgroup\$
  • \$\begingroup\$ No, I understand all of that, since that's basic to Open GL. My question is more geared towards HOW does one setup the Matrices inside the engine? Where do I pass them into? The Effect? Is that the equivalent of a glPush/PopMatrix to some degree? Apologies -- after re-reading my question, I realize that it was EXTREMELY unclear. I meant, how do I load the matrices up into something? \$\endgroup\$ – Locke Sep 2 '16 at 21:11
  • \$\begingroup\$ Ah, but you state in your question that you struggle to set these things up. XNA isn't so different from OpenGL what is it exactly you can't get to work? \$\endgroup\$ – Felsir Sep 2 '16 at 21:13
  • \$\begingroup\$ Sorry, it was extremely unclear of me. Where do I load the matrices into? I assume a BasicEffect? And if so -- if you wanted to do something like Billboarding "characters," would you need to do another BasicEffect after you rendered a Mesh with a prior BasicEffect, and adjust the Projection on the second BasicEffect? \$\endgroup\$ – Locke Sep 2 '16 at 21:15
  • 1
    \$\begingroup\$ You create the basicEffect, and you load the matrices like this: basicEffect.View = viewMatrix. You can reuse the effect, in fact you need to set the worldmatix only for each object (given that the view doesn't change). Be sure to Apply() the effect before drawing when you change a parameter. \$\endgroup\$ – Felsir Sep 2 '16 at 21:20
  • \$\begingroup\$ Ah, thank you. And as a note to whoever else might find this... BasicEffect myEffect = new BasicEffect( <graphicsDevice> ) { World = <worldMatrix>, View = <viewMatrix>, Projection = <projection> }; Before you call your code, you'd need to do myEffect.CurrentTechnique.Passes[0].Apply(); \$\endgroup\$ – Locke Sep 2 '16 at 22:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.