XNA – Set Up Camera

Posted: July 18, 2009 in C#, Programming, XNA
Tags: , ,

xna_logo

Before we render 3D world, we need set up camera. We do this by specifying the View and Projection matrices. Before rendering, both matrices are needed so the graphics card can correctly transform 3D world to 2D screen in our monitor.

Setting up camera in 3D world comes down to specifying two matrices. We can save the camera position and direction in a single matrix, which is called the View matrix. To create the View matrix, XNA needs to know the Position, Targer, and Up vector of camera. We can also save the view frustum, which is the part of the 3D world that is actually seen by the camera, in another matrix, which is called the Projection matrix.

Untitled


View Matrix

The View matrix holds the definition of the camera position and the direction into which it is looking. We can create this matrix by a simple call method CreateLookAt

public static Matrix CreateLookAt (
         Vector3 cameraPosition,
         Vector3 cameraTarget,
         Vector3 cameraUpVector
)
Parameters :
cameraPosition – The position of the camera.
cameraTarget – The target towards which the camera is pointing.
cameraUpVector – The direction that is “up” from the camera’s point of view.



View Frustum

A frustum in computer graphics is generally a volume of 3D space, defined as the part of a rectangular pyramid that lies between two planes perpendicular to its center line. A frustum is often used to represent what a “camera” sees in your 3D space.

image006

Look at figure below, the pyramid minus the top of the left side of the image is called view fustrum. All object you instruct XNA to render, only inside this volume are actually rendered to the screen

public static Matrix CreatePerspectiveFieldOfView (
         float fieldOfView,
         float aspectRatio,
         float nearPlaneDistance,
         float farPlaneDistance
)
Parameters :
fieldOfView – Field of view in radians.
aspectRatio – Aspect ratio, defined as view space width divided by height.
nearPlaneDistance – Distance to the near view plane.
farPlaneDistance – Distance to the far view plane.



Example Code

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace ViewCamera
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        BasicEffect basicEffect;
        GraphicsDevice device;

        Model myModel;
        Matrix[] modelTransforms;

        Matrix viewMatrix;
        Matrix projectionMatrix;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            graphics.PreferredBackBufferWidth = 700;
            graphics.PreferredBackBufferHeight = 500;
            graphics.IsFullScreen = false;
            graphics.ApplyChanges();
            Window.Title = "View Camera Example";

            base.Initialize();

            float viewAngle = MathHelper.PiOver4;
            float aspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio;
            float nearPlane = 0.5f;
            float farPlane = 500.0f;
            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(viewAngle, aspectRatio, nearPlane, farPlane);
        }

        protected override void LoadContent()
        {
            device = graphics.GraphicsDevice;
            basicEffect = new BasicEffect(device, null);

            myModel = Content.Load<Model>("tank");
            modelTransforms = new Matrix[myModel.Bones.Count];
        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            Vector3 camPosition = new Vector3(7, 8, 8);
            Vector3 camTarget = new Vector3(0, 0, 0);
            Vector3 camUpVector = new Vector3(0, 1, 0);
            viewMatrix = Matrix.CreateLookAt(camPosition, camTarget, camUpVector);

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1, 0);

            basicEffect.World = Matrix.Identity;
            basicEffect.View = viewMatrix;
            basicEffect.Projection = projectionMatrix;
            basicEffect.Begin();
            basicEffect.End();

            //draw model
            Matrix worldMatrix = Matrix.CreateScale(0.01f, 0.01f, 0.01f);
            myModel.CopyAbsoluteBoneTransformsTo(modelTransforms);

            foreach (ModelMesh mesh in myModel.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World = modelTransforms[mesh.ParentBone.Index] * worldMatrix;
                    effect.View = viewMatrix;
                    effect.Projection = projectionMatrix;
                }
                mesh.Draw();
            }            

            base.Draw(gameTime);
        }
    }
}



Sorry i don’t upload the complete source code files…because size of tank model file is very huge :/



Source :

XNA 3.0 Game Programming Recipes – Riemer Grootjans


Comments
  1. Keren zer..
    Suangar..
    Frustrum..frustrum..frustrum….

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s