XNA学习笔记——线、三角形的绘制
来源:互联网 发布:centos cp 拷贝文件夹 编辑:程序博客网 时间:2024/05/21 08:55
1: namespace WindowsGame4
2: {
3: public class Game1 : Microsoft.Xna.Framework.Game
4: {
5: GraphicsDeviceManager graphics;
6: SpriteBatch spriteBatch;
7:
8: public Game1()
9: {
10: graphics = new GraphicsDeviceManager(this);
11: Content.RootDirectory = "Content";
12: }
13:
14: protected override void Initialize()
15: {
16: // TODO: Add your initialization logic here
17:
18: base.Initialize();
19: }
20:
21: protected override void LoadContent()
22: {
23: // Create a new SpriteBatch, which can be used to draw textures.
24: spriteBatch = new SpriteBatch(GraphicsDevice);
25:
26: // TODO: use this.Content to load your game content here
27: }
28:
29: protected override void UnloadContent()
30: {
31: // TODO: Unload any non ContentManager content here
32: }
33:
34: protected override void Update(GameTime gameTime)
35: {
36: // Allows the game to exit
37: if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
38: this.Exit();
39:
40: // TODO: Add your update logic here
41:
42: base.Update(gameTime);
43: }
44: protected override void Draw(GameTime gameTime)
45: {
46: GraphicsDevice.Clear(Color.CornflowerBlue);
47:
48: // TODO: Add your drawing code here
49:
50: base.Draw(gameTime);
51: }
52: }
53: }
上面就是XNA自动生成的代码,整个类执行的流程如下图所示: http://img.ddvip.com/2009_03_14/1237027284_ddvip_4250.jpeg
按F5,即可运行,弹出如下对话框:
默认是800x600
1、修改窗口的宽度和高度,还有标题。
在构造函数中添加下面两行代码
1: Window.Title = "Hello XNA";
2: graphics.PreferredBackBufferWidth = 640;
3: graphics.PreferredBackBufferHeight = 480;
注:是在构造函数中,如果添加在Initialize(),没有效果。graphics的类型是GraphicsDeviceManager,也就是图形设备管理器,相当于D3D中的
D3D对象(LPDIRECT3D9 pD3D)。GraphicsDevice device = graphics.GraphicsDevice 通过图形设备管理器得到图形设备,相当于D3D中的设备对象(LPDIRECT3DDEVICE9 pd3dDevice )。图形设备对象可以用来绘制。
2、设置观察矩阵(Matrix viewMatrix)和投影矩阵(Matrix projectMatrix)
1: protected override void Initialize()
2: {
3: // TODO: Add your initialization logic here
4:
5: float viewAngle = MathHelper.PiOver4;
6: float aspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio;
7: float nearPlane = 0.1f;
8: float farPlane = 1000.0f;
9: projectMatrix = Matrix.CreatePerspectiveFieldOfView(viewAngle, aspectRatio, nearPlane, farPlane);
10:
11: Vector3 camPostion = new Vector3(10, 10, -10);
12: Vector3 camTarget = new Vector3(0, 0, 0);
13: Vector3 camUpVector = new Vector3(0, 1, 0);
14: viewMatrix = Matrix.CreateLookAt(camPostion, camTarget, camUpVector);
15:
16: base.Initialize();
17:
18: }
3、设置顶点
1: private void InitVertices()
2: {
3: vertices = new VertexPositionColor[30];
4:
5: vertices[0] = new VertexPositionColor(new Vector3(0, 0, 0), Color.Red);
6: vertices[1] = new VertexPositionColor(Vector3.Right * 5, Color.White);
7: vertices[2] = new VertexPositionColor(new Vector3(5, 0, 0), Color.White);
8: vertices[3] = new VertexPositionColor(new Vector3(4.5f, 0.5f, 0), Color.Plum);
9: vertices[4] = new VertexPositionColor(new Vector3(5, 0, 0), Color.White);
10: vertices[5] = new VertexPositionColor(new Vector3(4.5f, -0.5f, 0), Color.White);
11:
12: vertices[6] = new VertexPositionColor(new Vector3(0, 0, 0), Color.White);
13: vertices[7] = new VertexPositionColor(Vector3.Up * 5, Color.White);
14: vertices[8] = new VertexPositionColor(new Vector3(0, 5, 0), Color.White);
15: vertices[9] = new VertexPositionColor(new Vector3(0.5f, 4.5f, 0), Color.White);
16: vertices[10] = new VertexPositionColor(new Vector3(0, 5, 0), Color.White);
17: vertices[11] = new VertexPositionColor(new Vector3(-0.5f, 4.5f, 0), Color.White);
18:
19: vertices[12] = new VertexPositionColor(new Vector3(0, 0, 0), Color.White);
20: vertices[13] = new VertexPositionColor(Vector3.Forward * 5, Color.White);
21: vertices[14] = new VertexPositionColor(new Vector3(0, 0, -5), Color.White);
22: vertices[15] = new VertexPositionColor(new Vector3(0, 0.5f, -4.5f), Color.White);
23: vertices[16] = new VertexPositionColor(new Vector3(0, 0, -5), Color.White);
24: vertices[17] = new VertexPositionColor(new Vector3(0, -0.5f, -4.5f), Color.White);
25:
26: vertices[18].Position = new Vector3(3, 0, 0);
27: vertices[18].Color = Color.Blue;
28:
29: vertices[19].Position = new Vector3(0, 3, 0);
30: vertices[19].Color = Color.Red;
31:
32: vertices[20].Position = new Vector3(0, 0, -3);
33: vertices[20].Color = Color.Green;
34: }
private VertexPositionColor[] vertices; //VertexPositionColor表示该Vertex中有位置(Position)和颜色(Color)信息
private VertexDeclaration vertDeclaration;//VertexDeclaration是用来声明该Vertex中有哪些信息(位置、颜色、纹理、发现)
看下面的代码
1: public void DrawUsingPresetEffect()
2: {
3: device.VertexDeclaration = new VertexDeclaration(device, VertexPositionColor.VertexElements);
4: device.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, vertices, 0, 12);
5: device.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList, vertices, 18, 1);
6: }
device.vertDeclaration = new VertexDeclaration(device, VertexPositionColor.VertexElements);
DrawUserPrimitives中的第三个参数表示从哪个位置开始,第四个参数表示绘制多少个图元
0,12 表示vertices数组中从下标为0开始,绘制12条直线。18,1表示vertices数组中从下标18开始,绘制一个三角形
注:XNA的坐标系是右手坐标系,和D3D不同。
4、BasicEffect
一开始接触的是2D,绘制用的是SpriteBatch的Draw方法。到了3D,就迷糊了。
1: protected override void Draw(GameTime gameTime)
2: {
3: GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1, 0);
4:
5: // TODO: Add your drawing code here
6: basicEffect.World = Matrix.Identity;
7: basicEffect.View = viewMatrix;
8: basicEffect.Projection = projectMatrix;
9: basicEffect.VertexColorEnabled = true;//如果没有这句,颜色的效果体现不出来
10: basicEffect.Begin();
11: foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
12: {
13: pass.Begin();
14: cCross.DrawUsingPresetEffect();
15: pass.End();
16: }
17: basicEffect.End();
18: base.Draw(gameTime);
19: }
以前用的FFP(Fixed Function Pipeline 固定渲染管道)XNA已不再支持。XNA默认的是可编程的渲染管道,进行顶点渲染(Vertex Shader )和像素渲染(Pixel Shader),用HLSL编写,也就是说在3D中绘制物体都要用到HLSL。但由于HLSL的语法接近于C,所以在XNA中提供了一个BasicEffect这样的类,所有绘制在basicEffect.Begin()和basicEffect.End()中。像代码中的pass,Technique都是HLSL中的东西。需要对HLSL有一个基本的了解。
注:ClearOptions.Target是颜色缓存的刷新。上面漏了一个非常重要的知识点:在Draw函数的开始添加device.RenderState.CullMode = CullMode.None; 不然绘制的三角形有50%是看不见的。这就是背面剔除。
5、程序逻辑
1: protected override void Update(GameTime gameTime)
2: {
3: // Allows the game to exit
4: if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed
5: || Keyboard.GetState().IsKeyDown(Keys.Escape))
6: this.Exit();
7:
8: // TODO: Add your update logic here
9: base.Update(gameTime);
10: }
键盘状态的判断:Keyboard.GetState().IsKeyDown(Keys.Escape)
注:关于Update的参数GameTime。因为XNA默认的刷新频率是60Hz。也就是1秒钟,调用Update方法60次。但是游戏的帧数并不一定是60fps,所以提供了GameTime,可以根据相关的属性进行设置。下面是其中一种方式。
1: if(timeElapse >= ((double)1/fps)*1000)
2: {
3: hero.UpdateHero();
4: timeElapse = 0;
5: }
6: else
7: {
8: timeElapse += gameTime.ElapsedGameTime.Milliseconds;
9: }
- XNA学习笔记——线、三角形的绘制
- XNA学习笔记——2D屏幕中绘制线条
- XNA学习笔记——Tile Map的碰撞检测
- XNA学习笔记——SpriteBatch.Begin的Matrix参数
- XNA学习笔记——SpriteBatch.Draw的layerDepth
- XNA学习笔记——SpriteBatch.Draw的origin参数
- XNA学习笔记——相机设置
- Android OpenGL学习笔记(二)之----三角形的绘制.
- Opengl ES 学习笔记 2:绘制一个旋转的三角形
- Android OpenGL学习笔记(二)之----三角形的绘制.
- XNA学习笔记(2)-XNA的编程模型
- opengl学习笔记3-3-绘制三角形
- #学习笔记#(43)CSS-border绘制三角形
- OpenGL学习笔记之绘制三角形
- XNA学习笔记——顶点缓存和索引缓存
- XNA学习笔记——Quake式相机
- XNA学习笔记——文档翻译1
- XNA学习笔记——横版卷轴
- install mpd (music player daemon) mpc --backup--archlinux
- 七种qsort排序方法
- 手指的方向……
- 职业规划测试
- 主题:[转] Flex Builder 3.0 for Eclipse
- XNA学习笔记——线、三角形的绘制
- 令人出乎意外的感动
- 算法导论中的堆排序算法时间复杂度推导
- 在ubuntu/archlinux中安装sun的nimbus主题
- 新一代移动通讯
- 一个简单方法完成C#时间间隔的计算
- OGRE1.7学习笔记一:编译ogre
- 在archlinux中安装realplayer
- chatroulette: 早晚被封