XNA Primitives画线 2(3D空间)

    在XNA Primitives画线 1(2D和微量反射)的Demo中有很多的问题,比如,画的点不够精确、要画的线太多的话也就需要更多的点,这样的话对机子的性能可能要求就有点过了。

    其实做现在这个Demo的主要目标也就是为了提高精度,在3D环境中我们可以用一个像素表示一个点,因此精确度应该就高的多。在XNA中 PrimitiveType.LineList可以直接画线,也可以由画出的线组成我们要的圆等图形。

    另外,我想要实现全3D效果的话,我要用这种方式才行。

    因为GraphicsDevice可以绘制点、线和三角形,我们的需要就主要是画线。如,根据四个点的坐标就可以绘制一个坐标轴,下面就是绘制坐标轴的方法:

 

1        private void DrawCoordinate()
2        {
3            DrawLine(new Vector3(0 - Window.ClientBounds.Width / 200), new Vector3(Window.ClientBounds.Width / 200));
4            DrawLine(new Vector3( 0,0 - Window.ClientBounds.Width / 20), new Vector3( 0,Window.ClientBounds.Width / 20));
5        }

 

     现在让我们来绘制圆,XNA Primitives画线 1中的圆是由一个个的点组成的所以看起来就比较粗糙。这里的圆是由一个一个的线段,所以我就写了一个画线的方法:

 

 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, 01);
19                pass.End();
20            }

21            effect.End();
22        }

 

     在开始画圆之前,我们还要为我们要画的圆创建好它的顶点:

 

 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)), 00,
 9                   -1 * (float)Math.Sin(MathHelper.ToRadians( 3)), (float)Math.Cos(MathHelper.ToRadians( 3)), 00,
10                   0000,
11                   0000
12                   );
13                point = Vector2.Transform(point, tranmatrix);
14                VertexPoints[i] = new Vector3(point.X, point.Y, 0);
15            }

16            return VertexPoints;
17        }

 

    现在就开始画我们的圆了:

 

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            forint i = 0; i < points.Length-1;i++)
16            {
17                DrawLine(points[i], points[i + 1]); 
18            }

19             points[points.Length-1+= velocity;
20        }

 

效果如下:

 

 

 

 

 

 

    顺便贴出其它用到的方法:
    随机的起点和方向

 

 1        private Vector3 GetRandomVector3()
 2        
 3            Random rand=new Random(DateTime.Now.Second);
 4            return new Vector3((float)rand.Next(-180180), (float)rand.Next(-180180),0);
 5        }

 6
 7        private Vector3 GetRandomVelocity()
 8        {
 9            Random rand = new Random();
10            return new Vector3((float)rand.Next(-8080), (float)rand.Next(-8080), 0);
11        }

 

初始化

 

 1        protected override void Initialize()
 2        {
 3            IsMouseVisible = true;
 4            view = Matrix.CreateLookAt(new Vector3(00800), Vector3.Zero, Vector3.Up);
 5            projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 4 / 3f, 110000);
 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        }

 

键盘控制

 

 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(00-20));
36            }

37        }

 

    这里主要是在3D环境中画出的2D效果,本来想再将这个Demo做成3D效果的,可惜顶点没添加到好多的时候速度就已经很慢了,所以做成3D效果的话还不成形机子就死了,所以就免了。

现在更希望有高手能指教这里面的不足。

posted @ 2008-09-04 23:17  齐.net  阅读(3909)  评论(15编辑  收藏  举报