Skip to content

Commit d76ff5f

Browse files
Update base doc with clean example
1 parent 6dded3c commit d76ff5f

File tree

2 files changed

+137
-3
lines changed

2 files changed

+137
-3
lines changed

articles/getting_to_know/whatis/graphics/WhatIs_Camera.md

Lines changed: 136 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ The way we describe a camera in 3D terms is to define a [View Frustrum](./WhatIs
1818

1919
The following diagram shows how this looks.
2020

21-
![A diagram visualisation of the View Frustrum](images/frustum.jpg)
21+
![A diagram visualization of the View Frustrum](images/frustum.jpg)
2222

2323
Everything within the "cone of view" is recognized by the graphics pipeline and is rendered into a Texture for displaying on the screen. Everything outside these bounds is ignored (culled) and left on the cutting room floor.
2424

@@ -86,7 +86,7 @@ The functionality does provide some techniques to sort what is drawn, provide so
8686

8787
## [3D Drawing](../../howto/graphics/HowTo_RenderModel.md)
8888

89-
When drawing 3D content in a scene, the Camera's current `View` and `Projection` are what are fed in to the [Effect](xref:Microsoft.Xna.Framework.Graphics.Effect) that draws the 3D content, together with a [Transformational Matrix](../../howto/graphics/HowTo_TransformPoint.md) (`World` position and rotation of the model) multiplied by the same `World` matrix used by the camera (as they are both part of the same world).
89+
When drawing 3D content in a scene, the Camera's current `View` and `Projection` are what are fed in to an [Effect](xref:Microsoft.Xna.Framework.Graphics.Effect) that draws the 3D content, together with a [Transformational Matrix](../../howto/graphics/HowTo_TransformPoint.md) (`World` position and rotation of the model) multiplied by the same `World` matrix used by the camera (as they are both part of the same world).
9090

9191
An Example model drawing method:
9292

@@ -155,13 +155,147 @@ Each perspective simply alters the way in which content is rendered into view.
155155
To demonstrate a camera setup, the following class acts as a base camera definition that can then be extended to meet your needs for rendering:
156156

157157
```csharp
158+
using Microsoft.Xna.Framework;
159+
using Microsoft.Xna.Framework.Input;
160+
161+
public class Camera
162+
{
163+
private Vector3 position;
164+
private float yaw;
165+
private float pitch;
166+
private int viewportWidth;
167+
private int viewportHeight;
168+
private float nearClip = 10.0f;
169+
private float farClip = 100000.0f;
170+
171+
public Vector3 Position => position;
172+
173+
public float Yaw => yaw;
174+
175+
public float Pitch => pitch;
176+
177+
public Matrix ViewMatrix
178+
{
179+
get
180+
{
181+
Vector3 cameraDirection = Vector3.Transform(Vector3.Forward, Matrix.CreateFromYawPitchRoll(yaw, pitch, 0));
182+
Vector3 cameraTarget = position + cameraDirection;
183+
return Matrix.CreateLookAt(position, cameraTarget, Vector3.Up);
184+
}
185+
}
186+
187+
public Matrix ProjectionMatrix { get; private set; }
188+
189+
public Camera(Vector3 startPosition, float startYaw, float startPitch, int viewportWidth, int viewportHeight)
190+
{
191+
position = startPosition;
192+
yaw = startYaw;
193+
this.viewportWidth = viewportWidth;
194+
this.viewportHeight = viewportHeight;
195+
this.nearClip = nearClip;
196+
this.farClip = farClip;
197+
198+
ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(
199+
MathHelper.ToRadians(45),
200+
viewportWidth / (float)viewportHeight,
201+
nearClip,
202+
farClip
203+
);
204+
}
205+
}
158206
```
159207

160208
Using this camera is then as simple as:
161209

162210
```csharp
211+
using Microsoft.Xna.Framework;
212+
using Microsoft.Xna.Framework.Graphics;
213+
using Microsoft.Xna.Framework.Input;
214+
215+
public class MonoGameCameraSample : Game
216+
{
217+
private GraphicsDeviceManager _graphics;
218+
private SpriteBatch _spriteBatch;
219+
private Camera camera;
220+
221+
private Model myModel;
222+
223+
public MonoGameCameraSample()
224+
{
225+
_graphics = new GraphicsDeviceManager(this);
226+
Content.RootDirectory = "Content";
227+
}
228+
229+
protected override void Initialize()
230+
{
231+
// Create a new camera with the following parameters:
232+
// 1. Position 50 units Up and 100 units back from the center
233+
// 2. Camera is looking straight forward, no turn.
234+
// 3. Angle the camera down 25 degrees
235+
// 4. Pass in the width and height of the Graphics Device
236+
camera = new Camera(
237+
new Vector3(0, 50, 100),
238+
0f,
239+
-MathHelper.ToRadians(25f),
240+
GraphicsDevice.Viewport.Width,
241+
GraphicsDevice.Viewport.Height
242+
);
243+
244+
base.Initialize();
245+
}
246+
247+
protected override void LoadContent()
248+
{
249+
_spriteBatch = new SpriteBatch(GraphicsDevice);
250+
251+
myModel = Content.Load<Model>("Models/p1_wedge");
252+
}
253+
254+
protected override void Draw(GameTime gameTime)
255+
{
256+
GraphicsDevice.Clear(Color.CornflowerBlue);
257+
GraphicsDevice.BlendState = BlendState.Opaque;
258+
GraphicsDevice.RasterizerState = RasterizerState.CullNone;
259+
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
260+
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
261+
262+
// Draw a model using the camera's current View and Projection Matrix
263+
DrawModel(myModel, camera.ViewMatrix, camera.ProjectionMatrix);
264+
265+
base.Draw(gameTime);
266+
}
267+
268+
void DrawModel(Model aModel, Matrix aWorld, Matrix aView)
269+
{
270+
//Copy any parent transforms
271+
Matrix[] transforms = new Matrix[aModel.Bones.Count];
272+
aModel.CopyAbsoluteBoneTransformsTo(transforms);
273+
274+
//Draw the model, a model can have multiple meshes, so loop
275+
foreach (ModelMesh mesh in aModel.Meshes)
276+
{
277+
//This is where the mesh orientation is set, as well as our camera and projection
278+
foreach (BasicEffect effect in mesh.Effects)
279+
{
280+
effect.EnableDefaultLighting();
281+
effect.PreferPerPixelLighting = true;
282+
effect.World = transforms[mesh.ParentBone.Index] * aWorld;
283+
effect.View = aView;
284+
effect.Projection = currentProjection;
285+
}
286+
287+
//Draw the mesh, will use the effects set above.
288+
mesh.Draw();
289+
}
290+
}
291+
}
163292
```
164293

294+
This is a fixed camera with no movement and only looking in a single direction all the time, it has no movement, input logic or capability to move around the scene. IN the following guides we will use/extend this camera base to fit different modes of operation.
295+
296+
> [!NOTE]
297+
> The sample has wider scope to show all these modes and a much more versatile and multi-purpose camera, you may wish to use it or create your own bespoke implementation that fits your game.
298+
165299
## See Also
166300

167301
- [HowTo Create a First Person Camera](../../howto/graphics/camera/HowTo_Create_First_Person_Camera.md)

external/MonoGame

Submodule MonoGame updated 246 files

0 commit comments

Comments
 (0)