3D游戏开发

创建一个新的工程,打开vs2008 选择File----New----Project. 当创建一个新工程的窗口显示的时候,选择Visual c#---XNA Game Studio 3.0. 给工程起名叫3D Madness,选择一个存放工程的路径,点击确定.

 

 

3D游戏跟2D游戏有很多区别,现在我们来具体的看一下一些关键的区别

 

坐标系统

第一个区别是,3D2D多了一维的坐标系统.2D 坐标系中,绘图就像在屏幕中打印一个图片,你在屏幕的二维坐标中画一个图片.坐标(0,0)代表的是屏幕的左上角,X坐标轴向右,Y坐标轴向下.

如果说2D就像是在画一个图片的话,那么3D就像是在用一个手持的录像机录像.3D的显示是基于三维的坐标系统的.这种坐标系统,有时候被成为是世界坐标系,世界坐标系的最中间的圆点坐标为(0,0,0), 3D的图形你不可能只简单的画在屏幕上了.因为屏幕是二维的.我们能看到的只是摄像机拍到的东西.所以3D的图形,我们只关心两个元素:物体在世界的那个位置,摄像机放在世界的那个位置,摄像机朝向的角度.

摄像机的位置不同,角度不同,我们在看到的3d模型的位置就不同,可能是在屏幕的中间,也可能是在屏幕的下面,也可能就不在我们所能看到的屏幕上….

有很多总不同的3D坐标系,最常见的坐标系是X轴向右,Y轴向上,但是Z轴的方向是没有明确定义的.两种不同的3D坐标系统的存在,左手坐标系统和右手坐标系统.

伸出你的手,如图所示,拇指指向的方向是Z,手指的方向是X,卷曲手指的方向是Y.

 

 

XNA中用的是右手坐标系统就是说,从圆点开始,向右是X,向上是Y,朝着你的方向是Z.

 

摄像机

现在你明白了什么是坐标系统,我们来谈一谈什么是摄像机.这个相机不是陈冠希的摄像机.其实在屏幕上画一个3D的场景,就是拿一个手持的摄像机,观察相机里的图像.你要决定的是,摄像机在哪个位置,朝向哪个方向等等一些因素.

这些摄像机的属性存储在一个叫 Matrix(矩阵) 的类里. 矩阵运算其实是个特别复杂的数学问题,大学学的线性代数早就还给老师了.这里我们也不讨论这个问题.不过简单的说,你做3D图形显示的时候,他们的核心都是在进行过矩阵运算.幸运的是XNA提供的API能够处理全部的无聊的可怕的矩阵运算,我们所要做的就只剩下了,渐渐淡淡的了解 Matrix这个类,来表示一个摄像机~哈哈,开心吧.

XNA中有两个Matrix类可以表现摄像机…view(视图)类和projection(投影).view 类来控制在世界的哪个地方放摄像机啊,摄像机朝向方向啊,这些问题

Projection 投影类定义摄像机的角度啊,摄像机能看多远啊等等问题.

整个Matrix类就用来把3D的世界表现在2D的屏幕上.

创建一个矩阵视图.我们用Matrix类的静态方法CreatLookAt(),这个静态的方法 返回一个Matrix的类,他接受一下的几个参数.

 

camaraPositon 是个vector3类型的 他用来描述摄像机的位置

cameraTarge         vector3 类型摄像机朝向的坐标

cameraUpVector      vector3类型   标志哪个个方向是向上的

 

Vector3是个什么类型呢,其实Vector3就是个三维坐标类型表示(X,Y,Z)

CreateLookAt() 方法的第三个参数标志了一个摄像机的向上的方向

拿一个手持的摄像机,你可以斜着拿,你也可以倒着拿,你爱怎么拿就怎么拿,对吧. 但是你你怎么拿的肯定会影响到你录制的结果.XNA中着同样也是一个问题.

你给摄像机定义一个向上的向量,所以XNA就知道了,摄像机的方向.

创建projection 要用到Matrix的另外的一个静态的方法,这个静态的方法叫Matrix.CreatePerspectiveFieldOfView,这个方法同样的返回一个Matrix,并且接受的参数如下

 

 

FieldOfView    float类型     摄像机视角的弧度通常用弧度表示 比如说45°就是π/4;

aspectRatio    float类型     摄像机的外观比例.一般说是屏幕的宽度比上屏幕的高度.

nearPlaneDistance float类型 近端的梯形,也就是离多进物体会看不到.

farPlaneDistance   float类型   多远后的东西摄像机看不到.

这个近端跟远端形成的椎体里的物体一般来说都会被draw到屏幕上,除非有在前面的物体挡着了. 这个椎体叫viewable frustum ,椎体外的东西是不会被绘制到屏幕上的.

 

NearplaneFarplane之间的椎体.会被draw 到屏幕上,进的和远的都不会被绘制….

 

 

好了说了这么多没用的废话.我们现在开始do点代码.

把摄像机做成一个组建 是个不错的想法.这样以后你再给游戏增加个cameras,就变的很是方面了.好了,右键工程Add----New Item ----Game Component. 给文件起个名字叫Camera.cs 然后点add

 

 

Camera.cs类中 增加两个类级别的属性来表示 view projection

然后,更改构造器来接受3Vector3的变量,分别表示摄像机初始的position target up Vectors.在构造器中通过调用Matrix.CreateLookt来初始化View .调用Matix.CreatePerspectiveFieldOfView 来初始化projection

下面是camera.cs构造器的完整代码

Public Camera(Game game,Vector3 pos, Vector3 target, Vector3 up)

:base (game)

{

         View =Matrix.createLookAt(pos,target,up);

         Projection = Matrix.CreatePerspectiveFieldOfView(

                   MathHelper.PiOver4,

                   (float)Game.Window.ClientBounds.Width/

                   (float)Game.Window.ClientBounds.Height,

                   1,

                   100);

}

注意,要把屏幕的宽和高强制转化为float 这样就不会因为int类型损失,造成屏幕的畸形

 

好了 在你的game.cs里加如下面的代码

类级别的定义

Camera camera;

Game1 类的初始化方法里 假如下面的代买 来初始化

// Initialize camera

Camera = new Camera(this ,new Vector3(0,0,5),

                   Vector3.Zero, Vector3.Up);

         Components.Add(camera);

 

 

哈哈 运行一下吧~你太厉害了 就让一个摄像机成功的工作了看看你令人惊人的成就

 

多美丽的界面啊

 

 

….可能你会说不就是个垃圾蓝色界面么

Come on ,man 想想你做了啥,你创建了一个摄像机在(0,0,5)这个位置,并且告诉了摄像机向(0,0,0)这个位置观看,你制定了(0,1,0)这个位置是向上的位置.

干的太漂亮了.这个蓝色的界面实在是太他妈的帅了~加油.

 

 

绘制基元

好了,现在你有了一个摄像机,let get ready to go~ 3D图形绘制的基础是三角形,也就是说,所有的3d图形都是通过绘制三角形来完成的,如果你画足够多的三角形,你就可以描述出所有可能的形状.只要三角形离得够进,画的够小,能画出来光滑的,圆形的表面.

好了 let’s rock and roll

为了画第一个三角形,我们要定义一些点,来表示三角形.

好了,game1 类里面 在类空间里,创建一个VertexPositionColor的类数组

VertexPositionColor[] verts;

我们用这些对象来创建这些点

VertexPositionColor这个对象可以表示点的位置和颜色

我们在构造器里来给他们赋值.LoadContent方法里

把点初始化了,代码如下:

//Initialize vertices

Verts = new VertexPositionColor[3];

Verts[0] = new VertexPositionColor(new vector3(0,1,0),Color.Blue);

Verts[1]= new VertexPositionColor(new vector3(1,-1,0),Color.Red);

Verts[2]=new VertexPositionColor(new Vector3(-1,-1,0),Color.Green);

 

下面在Game1draw方法里,你需要做些事情来完成对VertexDeclaration的调用.简单的说 就是你要告诉你的图形设备,你要发送一些信息了.这些信息是VertexDeclaration类型的.

GraphicsDevice.Clear的方法下面添加下面的代码

GraphicsDevice.VertexDeclaration=

        New VertexDeclaration(GraphicsDevice,VertexPositionColor.VertexElements);

好了,接下来设置下效果和显示属性

BasicEffect effect = new BasicEffect(GraphicsDevice,null);

effect.World= Matrix.Identity;

effect.View=camera.view;

effect.projection=camera.projection;

effect.VertexColorEnabled=true;

 

//Begin effect and draw for each pass

effect.Begin();

foreach (EffectPass pass in effect.CurrentTechnique.Passes)

{

         Pass.Begin();

         GraphicsDevice.DrawUserPrimitives<VertexPositionColor>

                   (PrimitiveType.TriangleStrip,verts,0,1);

                   Pass.End();

}

effect.End();

运行下游戏吧,一个特别酷的方框就被渲染出来了.看看效果

 

 

 

posted @ 2009-03-17 18:02  zehua  阅读(489)  评论(0)    收藏  举报