您的位置:首页 > 其它

[翻译]XNA 3.0 Game Programming Recipes之one

2009-07-13 11:48 489 查看
PS:自己翻译的,转载请著明出处

2-1 调好摄像机的:地位,目标, 视景体

问题
在您绘制你的3D世界到屏幕前,你需要设置你的摄象机。通过设置视角和对象矩阵。在绘制之前,2个矩阵都是需要的以至于图形卡能正确的将你的3D世界转化成2D屏幕中。

解决方案
在你的3D世界里设置你的摄象机归根揭底是2个特别的矩阵。
你也可以保存摄象机的位置和方向用一个单独的矩阵。这个矩阵叫做View matrix.为了建立View matrix,XNA需要知道摄象机的位置,目标和摄象机的上部方向。
你同样可以保存view frustum,这是3D世界可以被摄象机能真实的看见。这个矩阵称为Projection matrix.

它是如何工作的
View matrix存有摄象机的位置和摄象机面向的方向。你可以建立它门用一个简单的Matrix.CreateLokAt方法:

viewMatrix=Matrix.CreateLookAt(camPosition,camTarget,camUpVector);
这个方法有3个向量:摄象机的位置,目标,向上的方向。位置向量有应该很容易察觉因为它声明在3D世界里你的摄象机的位置。在3D世界里你还要定义你的摄象机朝向的方向。这个定义了视角的方向。那么你需要向上的方向做什么呢?
思考接下来的例子:你的头(好,应该是你的眼睛)是一个摄象机。你想定义假设用你的头一个摄象机用相同的位置和方向第一个向量很容易找到:在3D场景中你的头的位置就是摄象机的位置向量。同样,接下来的目标向量也不是很难定义。假设你正在看X在图1。这种情况下,这本书中的X的位置可能就是你摄象机的目标向量。越远越好,但是在现在,你需要保持的头在原来的位置上和目标的一定距离观察X。
仅仅只有位置和目标向量被定义,你可以旋转你的头围绕着两眼之间的点。例如,在固定点的颠倒混乱。同时你又准备做这个,你头的位置和目标的一直保持相同的位置。你看到的结果图象变的完全不同了是因为任何事物都旋转了。这就是为什么要定义摄象机的向上方向的位置。
一旦你知道你的摄象机的位置,哪里是你用它要观察的。哪个方面被认为是摄象机的上部方向,摄象机被认为是"独特的自定义者"
View matrix,这3个独特的载体,可以用Matrix.CreateLookAt方法来构造:

1 Matrix viewMatrix;
2 Vector3 camPosition=new Vector3(10,0,0);
3 Vector3 camTarget=new Vector3(0,0,0);
4 Vector3 camUpVector=new Vector3(0,1,0);
5 viewMatrix=Matrix.CreateLookAt(camPosition,camTarget,camUpVector);
注意:尽管现在的位置和目标向量相机指向真正点在三维空间,向上矢量显示向上的方向。例如,说是在相机的位置( 300,0,0 )和面向点( 200,0,0 ) 。如果你想表明相机的更新向量就是指着向上,你通过( 0,1,0 )向上的向量表示,而不是点在相机在三维空间上面的,这将是( 300,1,0 )点也在这个例子中。
注意:XNA提供快捷最常用的向量,如Vector3.Up点(0,1,0),Vector3.Forward点(0,0,-1)和Vector3.Right点(1,0,0).让你更熟悉三维矢量, 所有媒介,您可以找到在本章书面的第一节看到写的很全。

XNA要求的另外一个矩阵是Projection matrix.你可以这样认为矩阵(是一个很奇妙的东西)是从3D空间转化为2Dwindow图片上所有的点但是我宁愿你把它看作矩阵持有摄像机镜头的相关信息。
图片现在3D场景的左半部分,图片在摄象机的视角内。这正如你所看到的,形状的金字塔。在右边,你可以找到二维截面这个金字塔。Code
1 namespace BookCode
2 {
3 public class Game1:Microsoft.Xna.Framework.Game
4 {
5 GraphicsDeviceManager graphics;
6 BasicEffect basicEffect;
7 GraphicsDevice device;
8 CoordCross cCross;
9 Matrix viewMatrix;
10 Matrix projectionMatrix;
11 public Game1()
12 {
13 graphics=new GraphicsDeviceManager(this);
14 Content.RootDirectory="Content";
15 }//Projcetion矩阵只在目标窗口的纵横比变换时才会变化.如果不会发生,那么你只有一次定义它的机会,可以在初始化的阶段定义它
16 protected override void Initialize()
17 {
18 base.Initialize();
19 float viewAngle=MathHelper.PiOver4;
20 float aspectRatio=graphics.GraphicsDevice.Viewport.AspectRatio;
21 float nearPlane=0.5f;
22 float farPlane=100.0f;
23 projectionMatrix=Matrix.CreatePerspectiveFieldOfView(viewAngle,aspectRatio,nearPlane,farPlane);
24 }
25 protected override void LoadContent()
26 {
27 device=graphics.GraphicsDevice;
28 basicEffect=new BasicEffect(device,null);
29 cCross=new CoordCross(device);
30 }
31 protected override void UnloadContent()
32 {}//用户输入移动摄象机将使你想改变View矩阵,将在跟新阶段实现这一想法
33 protected override void Update(GameTime gameTime)
34 {
35 if(GamePad.GetState(PlayerIndex.One).Button.Back==ButtonState.Pressed)
36 this.Exit()
37 Vector3 camPosition=new Vector3(10,10,-10);
38 Vector3 camTarget=new Vector3(0,0,0);
39 Vector3 camUpVector=new Vector3(0,1,0);
40 viewMatrix=Matrix.CreateLookAt(camPosition,camTarget,camUpVector);
41 base.Update(gameTime);
42 }//传递Projection和View矩阵到Effect类将会绘制场景.在这点上,在初始点(0,0,0)上将绘制一个交叉的3D世界的坐标系.CoordCross.cs文件将实实在在的绘制交叉的坐标系.
43 protected override void Draw(GameTime gameTime)
44 {
45 device.Clear(ClearOptions.Target|ClearOptions.DepthBuffer,Color.CornflowerBlue,1,0);
46 basicEffect.World=Matrix.Identity;
47 basicEffect.View=viewMatrix;
48 basicEffect.Projection=projectionMatrix;
49 basicEffect.Begin();
50 foreach(EffectPass pass in basicEffect.CurrentTechnique.Passes)
51 {
52 pass.Begin();
53 cCross.DrawUsingPresetEffect();
54 pass.End();
55 }
56 basicEffect.End();
57 base.Draw(gameTime);
58 }
59
课外阅读

前两个矩阵都是XNA需要正确在你的屏幕上提供您的三维场景的二维窗口 。从三维到二维涉及某些挑战,这是所有由XNA所考虑的。但是,如果您希望能够创建和调试中到大型的3D 应用,清楚地了解正在引擎盖下发生的事情是必要的。


然而,如何对象B先画,在帧缓冲响应象素先把对象B的颜色标记了。下一刻,对象A被绘画,现在,图形卡设备不管象素是否需要被对象A的颜色覆盖。
为了解决这个问题,在第二个图形卡存储图像,以同样的大小的窗口。目前,一种颜色被派往像素的帧缓冲,
摄象机和对象的距离被存储在在第二副图象中,距离值是0到1之间,0是摄象机到近剪裁面板而1是摄象机到远剪裁面板。
由于这一原因,第2副图片被称为深度缓冲区或Z轴缓冲。
所以,它是怎么解决着个问题的呢?现在对象B被绘制了,Z轴缓冲被选中。因为对象B是第一个被绘制的,Z轴缓冲将清空。
结果,所有帧缓冲相应的象素获得对象B的颜色,同一像素中的Z轴缓冲获得值根据摄像机与对象B之间的距离。
下一刻,对象A被绘制。每一个象素可能被对象A所占用,Z轴缓冲先被锁定。Z轴缓冲区将已经包含了一种值的像素与对象B重叠。保存在Z轴缓冲区的距离大于摄象机和对象A之间的
距离,所以图形卡知道用对象A的象素覆盖它。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: