
cobra
striver
-
个人空间
相册
- 性别:
- 来自:拼吾爱
- 积分:6813
- 帖子:6725
- 注册:
2007-04-09
|
XNA Primitives画线 2(3D空间)
在XNA Primitives画线 1(2D和微量反射)的Demo中有很多的问题,比如,画的点不够精确、要画的线太多的话也就需要更多的点,这样的话对机子的性能可能要求就有点过了。 其实做现在这个Demo的主要目标也就是为了提高精度,在3D环境中我们可以用一个像素表示一个点,因此精确度应该就高的多。在XNA中 PrimitiveType.LineList可以直接画线,也可以由画出的线组成我们要的圆等图形。 另外,我想要实现全3D效果的话,我要用这种方式才行。 因为GraphicsDevice可以绘制点、线和三角形,我们的需要就主要是画线。如,根据四个点的坐标就可以绘制一个坐标轴,下面就是绘制坐标轴的方法:  Code
1 private void DrawCoordinate() 2 { 3 DrawLine(new Vector3(0 - Window.ClientBounds.Width / 2, 0, 0), new Vector3(Window.ClientBounds.Width / 2, 0, 0)); 4 DrawLine(new Vector3( 0,0 - Window.ClientBounds.Width / 2, 0), new Vector3( 0,Window.ClientBounds.Width / 2, 0)); 5 }
现在让我们来绘制圆,XNA Primitives画线 1中的圆是由一个个的点组成的所以看起来就比较粗糙。这里的圆是由一个一个的线段,所以我就写了一个画线的方法:  Code
1 private void DrawLine(Vector3 point1, Vector3 point2) 2 { 3 VertexPositionColor[] vpcs = new VertexPositionColor[2]; 4 vpcs[0] = new VertexPositionColor(point1, Color.White); 5 vpcs[1] = new VertexPositionColor(point2, Color.White); 6 7 vertexDecl = new VertexDeclaration(GraphicsDevice, VertexPositionColor.VertexElements); 8 GraphicsDevice.VertexDeclaration = vertexDecl; 9 BasicEffect effect = new BasicEffect(GraphicsDevice, null); 10 effect.View = view; 11 effect.Projection = projection; 12 effect.World = worldTrans; 13 14 effect.Begin(); 15 foreach (EffectPass pass in effect.CurrentTechnique.Passes) 16 { 17 pass.Begin(); 18 GraphicsDevice.DrawUserPrimitives(PrimitiveType.LineList, vpcs, 0, 1); 19 pass.End(); 20 } 21 effect.End(); 22 }
在开始画圆之前,我们还要为我们要画的圆创建好它的顶点:  Code
1 private Vector3[] CirlcePoint() 2 { 3 Vector3[] VertexPoints = new Vector3[120]; 4 Vector2 point = new Vector2(200,0); 5 Matrix tranmatrix; 6 for (int i = 0; i < 120;i++) 7 { 8 tranmatrix = new Matrix((float)Math.Cos(MathHelper.ToRadians( 3)), (float)Math.Sin(MathHelper.ToRadians( 3)), 0, 0, 9 -1 * (float)Math.Sin(MathHelper.ToRadians( 3)), (float)Math.Cos(MathHelper.ToRadians( 3)), 0, 0, 10 0, 0, 0, 0, 11 0, 0, 0, 0 12 ); 13 point = Vector2.Transform(point, tranmatrix); 14 VertexPoints = new Vector3(point.X, point.Y, 0); 15 } 16 return VertexPoints; 17 }
现在就开始画我们的圆了:  Code
1 private void DrawCircle() 2 { 3 for (int i = 0; i < CirclePosition.Length; i++) 4 { 5 Vector3 point1; 6 Vector3 point2; 7 if (i == CirclePosition.Length - 1) 8 { 9 point1 = CirclePosition; 10 point2 = CirclePosition[0]; 11 } 12 else 13 { 14 point1 = CirclePosition; 15 point2 = CirclePosition[i + 1]; 16 } 17 DrawLine(point1, point2); 18 LineNumber++; 19 } 20 }
看下效果  附件: 您所在的用户组无法下载或查看附件这个是比之前那个好的多吧。 剩下和就是主题部分了,其实原理我之前那个还是一样的。  Code
1 private void DrawMyEffect() 2 { 3 if (points[points.Length - 1].Length() >200) 4 { 5 ArrayList al = new ArrayList(); 6 foreach(Vector3 vec in points) 7 { 8 al.Add(vec); 9 } 10 al.Add(points[points.Length - 1]); 11 points = (Vector3[])al.ToArray(typeof(Vector3)); 12 velocity = Vector3.Reflect(velocity, Vector3.Normalize(points[points.Length - 1])); 13 } 14 15 for( int i = 0; i < points.Length-1;i++) 16 { 17 DrawLine(points, points[i + 1]); 18 } 19 points[points.Length-1] += velocity; 20 }
效果如下:  附件: 您所在的用户组无法下载或查看附件 附件: 您所在的用户组无法下载或查看附件 附件: 您所在的用户组无法下载或查看附件 顺便贴出其它用到的方法: 随机的起点和方向  Code
1 private Vector3 GetRandomVector3() 2 { 3 Random rand=new Random(DateTime.Now.Second); 4 return new Vector3((float)rand.Next(-180, 180), (float)rand.Next(-180, 180),0); 5 } 6 7 private Vector3 GetRandomVelocity() 8 { 9 Random rand = new Random(); 10 return new Vector3((float)rand.Next(-80, 80), (float)rand.Next(-80, 80), 0); 11 }
初始化  Code
1 protected override void Initialize() 2 { 3 IsMouseVisible = true; 4 view = Matrix.CreateLookAt(new Vector3(0, 0, 800), Vector3.Zero, Vector3.Up); 5 projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 4 / 3f, 1, 10000); 6 velocity = GetRandomVelocity(); 7 startPosition = GetRandomVector3(); 8 points = new Vector3[2]; 9 points[0] = startPosition; 10 points[1] = startPosition + velocity; 11 12 base.Initialize(); 13 }
键盘控制  Code
1 private void HandelInput() 2 { 3 KeyboardState ks = Keyboard.GetState(); 4 if (ks.IsKeyDown(Keys.W)) 5 { 6 worldTrans *= Matrix.CreateRotationX(MathHelper.ToRadians(10f)); 7 } 8 if (ks.IsKeyDown(Keys.S)) 9 { 10 worldTrans *= Matrix.CreateRotationX(MathHelper.ToRadians(-10f)); 11 } 12 if (ks.IsKeyDown(Keys.A)) 13 { 14 worldTrans *= Matrix.CreateRotationY(MathHelper.ToRadians(10f)); 15 } 16 if (ks.IsKeyDown(Keys.D)) 17 { 18 worldTrans *= Matrix.CreateRotationY(MathHelper.ToRadians(-10f)); 19 } 20 if (ks.IsKeyDown(Keys.Q)) 21 { 22 worldTrans *= Matrix.CreateRotationZ(MathHelper.ToRadians(10f)); 23 } 24 if (ks.IsKeyDown(Keys.E)) 25 { 26 worldTrans *= Matrix.CreateRotationZ(MathHelper.ToRadians(-10f)); 27 } 28 29 if (ks.IsKeyDown(Keys.Up)) 30 { 31 view *= Matrix.CreateTranslation(new Vector3(0,0,20)); 32 } 33 if (ks.IsKeyDown(Keys.Down)) 34 { 35 view *= Matrix.CreateTranslation(new Vector3(0, 0, -20)); 36 } 37 }
这里主要是在3D环境中画出的2D效果,本来想再将这个Demo做成3D效果的,可惜顶点没添加到好多的时候速度就已经很慢了,所以做成3D效果的话还不成形机子就死了,所以就免了。 现在更希望有高手能指教这里面的不足。 (文/desmend 出处/博客园) | 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。 |
|