بسم الله الرحمن الرحيم الدرس الثالث أهلا بكم في الدرس الثالث من سلسلة دروس تعلم 3D Xna (السلسلة الثانية)، في هذا الدرس سوف نقوم بإنشاء أرضية المدينة. الآن وقد رأينا كيف بإمكاننا إستيراد صور بسيطة إلى مشروع ال Xna الخاص بنا، و كيف تقوم الXna بعرض هذه الصور على المثلثات، لن يكون من الصعب علينا إنشاء كمية كبيرة من الصور. من المهم جدا إيجاد طريقة لجعل الكمبيوتر يقوم بتعريف كل النقاط لنا بشكل تلقائي. كمثال بسيط، دعنا نقوم بإنشاء شبكة مكونة من 3*3 صور، بدون الصورة في الوسط. هذا يعني 8 صور، إذا 16 مثلث، و 48 رأس. بدلا من تعريف جميع هذه الرؤوس يدويا، دعنا نقوم بإنشاء مصفوفة بإسم “floorPlan”، في أعلى الكود. هذه المصفوفة سوف تحتوي لاحقا الأماكن التي نريد أن يكون فيها مباني في المدينة ثلاثية الأبعاد:
int[,] floorPlan; VertexBuffer cityVertexBuffer; VertexDeclaration texturedVertexDeclaration;
private void LoadFloorPlan() { floorPlan = new int[,] { {0,0,0}, {0,1,0}, {0,0,0}, }; }
LoadFloorPlan();
sceneryTexture = Content.Load<Texture2D> ("texturemap");
private void SetUpVertices() { int cityWidth = floorPlan.GetLength(0); int cityLength = floorPlan.GetLength(1); List<VertexPositionNormalTexture> verticesList = new List<VertexPositionNormalTexture> (); for (int x = 0; x < cityWidth; x++) { for (int z = 0; z < cityLength; z++) { //if floorPlan contains a 0 for this tile, add 2 triangles } } cityVertexBuffer = new VertexBuffer(device, verticesList.Count * VertexPositionNormalTexture.SizeInBytes, BufferUsage.WriteOnly); cityVertexBuffer.SetData<VertexPositionNormalTexture> (verticesList.ToArray()); texturedVertexDeclaration = new VertexDeclaration(device, VertexPositionNormalTexture.VertexElements);}
int imagesInTexture = 11; if (floorPlan[x,z] == 0) { verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z), new Vector3(0, 1, 0), new Vector2(0, 1))); verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z-1),new Vector3(0, 1, 0), new Vector2(0, 0))); verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1,0,-z), new Vector3(0, 1, 0), new Vector2(1.0f / imagesInTexture, 1))); verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0,-z-1), new Vector3(0, 1, 0), new Vector2(0, 0))); verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1,0,-z-1), new Vector3(0, 1, 0), new Vector2(1.0f / imagesInTexture, 0))); verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1,0,-z), new Vector3(0, 1, 0), new Vector2(1.0f / imagesInTexture, 1))); }
private void DrawCity() { effect.CurrentTechnique = effect.Techniques["Textured"]; effect.Parameters["xWorld"].SetValue(Matrix.Identity); effect.Parameters["xView"].SetValue(viewMatrix); effect.Parameters["xProjection"].SetValue(projectionMatrix); effect.Parameters["xTexture"].SetValue(sceneryTexture); effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); device.VertexDeclaration = texturedVertexDeclaration; device.Vertices[0].SetSource(cityVertexBuffer, 0, VertexPositionNormalTexture.SizeInBytes); device.DrawPrimitives(PrimitiveType.TriangleList, 0, cityVertexBuffer.SizeInBytes / VertexPositionNormalTexture.SizeInBytes / 3); pass.End(); } effect.End(); }
protected override void Draw(GameTime gameTime) { ClearOptions.DepthBuffer, Color.DarkSlateBlue, 1.0f, 0); DrawCity(); base.Draw(gameTime); }
viewMatrix = Matrix.CreateLookAt(new Vector3(3, 5, 2), new Vector3(2, 0, -1), new Vector3(0, 1, 0));
using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Net; using Microsoft.Xna.Framework.Storage; namespace XNAseries2 { public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; GraphicsDevice device; Effect effect; Matrix viewMatrix; Matrix projectionMatrix; Texture2D sceneryTexture; int[,] floorPlan; VertexBuffer cityVertexBuffer; VertexDeclaration texturedVertexDeclaration; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; } protected override void Initialize() { graphics.PreferredBackBufferWidth = 500; graphics.PreferredBackBufferHeight = 500; graphics.IsFullScreen = false; graphics.ApplyChanges(); Window.Title = "Riemer's XNA Tutorials -- Series 2"; LoadFloorPlan(); base.Initialize(); } protected override void LoadContent() { device = graphics.GraphicsDevice; effect = Content.Load<Effect> ("effects"); sceneryTexture = Content.Load<Texture2D> ("texturemap"); SetUpVertices(); SetUpCamera(); } private void LoadFloorPlan() { floorPlan = new int[,] { {0,0,0}, {0,1,0}, {0,0,0}, }; } private void SetUpCamera() { viewMatrix = Matrix.CreateLookAt(new Vector3(3, 5, 2), new Vector3(2, 0, -1), new Vector3(0, 1, 0)); projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 0.2f, 500.0f); } private void SetUpVertices() { int cityWidth = floorPlan.GetLength(0); int cityLength = floorPlan.GetLength(1); List<VertexPositionNormalTexture> verticesList = new List<VertexPositionNormalTexture> (); for (int x = 0; x < cityWidth; x++) { for (int z = 0; z < cityLength; z++) { int imagesInTexture = 11; if (floorPlan[x,z] == 0) { verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z), new Vector3(0, 1, 0), new Vector2(0, 1))); verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z-1),new Vector3(0, 1, 0), new Vector2(0, 0))); verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z), new Vector3(0, 1, 0), new Vector2(1.0f / imagesInTexture, 1))); verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0,-z-1), new Vector3(0, 1, 0), new Vector2(0, 0))); verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z-1), new Vector3(0, 1, 0), new Vector2(1.0f / imagesInTexture, 0))); verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z), new Vector3(0, 1, 0), new Vector2(1.0f / imagesInTexture, 1))); } } } cityVertexBuffer = new VertexBuffer(device, verticesList.Count * VertexPositionNormalTexture.SizeInBytes, BufferUsage.WriteOnly); cityVertexBuffer.SetData<VertexPositionNormalTexture> (verticesList.ToArray()); texturedVertexDeclaration = new VertexDeclaration(device, VertexPositionNormalTexture.VertexElements); } protected override void UnloadContent() { } protected override void Update(GameTime gameTime) { base.Update(gameTime); } protected override void Draw(GameTime gameTime) { device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.DarkSlateBlue, 1.0f, 0); DrawCity(); base.Draw(gameTime); } private void DrawCity() { effect.CurrentTechnique = effect.Techniques["Textured"]; effect.Parameters["xWorld"].SetValue(Matrix.Identity); effect.Parameters["xView"].SetValue(viewMatrix); effect.Parameters["xProjection"].SetValue(projectionMatrix); effect.Parameters["xTexture"].SetValue(sceneryTexture); effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); device.VertexDeclaration = texturedVertexDeclaration; device.Vertices[0].SetSource(cityVertexBuffer, 0, VertexPositionNormalTexture.SizeInBytes); device.DrawPrimitives(PrimitiveType.TriangleList, 0, cityVertexBuffer.SizeInBytes / VertexPositionNormalTexture.SizeInBytes / 3); pass.End(); } effect.End(); } } }