بســم الله الـرحمــن الرحيــم الدرس السابع أهلا بكم في الدرس السابع من سلسلة دروس تعلم ال3D Xna السلسلة الأولى، في هذا الدرس سوف نتحدث عن اساسيات إنشاء التضاريس. حتى الآن، قد درسنا عناوين كافيه لكي نبدأ بإنشاء التضاريس الخاصة بنا. دعنا نبدأ بشيئ بسيط، عن طريق ربط 3*4 رؤوس محددة. بكل الأحوال، سوف نقوم بعمل المحرك الخاص بنا بشكل ديناميكي، لذا في الدرس القادم سوف نستطيع ببساطة تحميل عدد اكبر بكثير من النقاط. لعمل ذلك، علينا إنشاء متغيرين جديدين في الصنف:
private int terrainWidth = 4; private int terrainHeight = 3;
private float[,] heightData;
private void LoadHeightData() { heightData = new float[4, 3]; heightData[0, 0] = 0; heightData[1, 0] = 0; heightData[2, 0] = 0; heightData[3, 0] = 0; heightData[0, 1] = 0.5f; heightData[1, 1] = 0; heightData[2, 1] = -1.0f; heightData[3, 1] = 0.2f; heightData[0, 2] = 1.0f; heightData[1, 2] = 1.2f; heightData[2, 2] = 0.8f; heightData[3, 2] = 0; }
LoadHeightData();
private void SetUpVertices() { vertices = new VertexPositionColor[terrainWidth * terrainHeight]; for (int x = 0; x < terrainWidth; x++) { for (int y = 0; y < terrainHeight; y++) { vertices[x + y * terrainWidth].Position = new Vector3(x, 0, -y); vertices[x + y * terrainWidth].Color = Color.White; } } myVertexDeclaration = new VertexDeclaration(device, VertexPositionColor.VertexElements); }
private void SetUpIndices() { indices = new int[(terrainWidth - 1) * (terrainHeight - 1) * 3]; int counter = 0; for (int y = 0; y < terrainHeight - 1; y++) { for (int x = 0; x < terrainWidth - 1; x++) { int lowerLeft = x + y*terrainWidth; int lowerRight = (x + 1) + y*terrainWidth; int topLeft = x + (y + 1) * terrainWidth; int topRight = (x + 1) + (y + 1) * terrainWidth; indices[counter++] = topLeft; indices[counter++] = lowerRight; indices[counter++] = lowerLeft; } } }
vertices[x + y * terrainWidth].Position = new Vector3(x, heightData[x,y], -y);
private void SetUpIndices() { indices = new int[(terrainWidth - 1) * (terrainHeight - 1) * 6]; int counter = 0; for (int y = 0; y < terrainHeight - 1; y++) { for (int x = 0; x < terrainWidth - 1; x++) { int lowerLeft = x + y*terrainWidth; int lowerRight = (x + 1) + y*terrainWidth; int topLeft = x + (y + 1) * terrainWidth; int topRight = (x + 1) + (y + 1) * terrainWidth; indices[counter++] = topLeft; indices[counter++] = lowerRight; indices[counter++] = lowerLeft; indices[counter++] = topLeft; indices[counter++] = topRight; indices[counter++] = lowerRight; } } }
private void SetUpIndices() { indices = new short[(terrainWidth - 1) * (terrainHeight - 1) * 6]; int counter = 0; for (int y = 0; y < terrainHeight - 1; y++) { for (int x = 0; x < terrainWidth - 1; x++) { short lowerLeft = (short)(x + y * terrainWidth); short lowerRight = (short)((x + 1) + y * terrainWidth); short topLeft = (short)(x + (y + 1) * terrainWidth); short topRight = (short)((x + 1) + (y + 1) * terrainWidth); indices[counter++] = topLeft; indices[counter++] = lowerRight; indices[counter++] = lowerLeft; indices[counter++] = topLeft; indices[counter++] = topRight; indices[counter++] = lowerRight; } } }
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 XNAtutorial { public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; GraphicsDevice device; Effect effect; VertexPositionColor vertices; VertexDeclaration myVertexDeclaration; int indices; Matrix viewMatrix; Matrix projectionMatrix; private int terrainWidth = 4; private int terrainHeight = 3; private float heightData; 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 1"; base.Initialize(); } protected override void LoadContent() { device = graphics.GraphicsDevice; spriteBatch = new SpriteBatch(GraphicsDevice); effect = Content.Load ("effects"); LoadHeightData(); SetUpVertices(); SetUpCamera(); SetUpIndices(); } private void SetUpVertices() { vertices = new VertexPositionColor[terrainWidth * terrainHeight]; for (int x = 0; x < terrainWidth; x++) { for (int y = 0; y < terrainHeight; y++) { vertices[x + y * terrainWidth].Position = new Vector3(x, heightData[x, y], -y); vertices[x + y * terrainWidth].Color = Color.White; } } myVertexDeclaration = new VertexDeclaration(device, VertexPositionColor.VertexElements); } private void SetUpIndices() { indices = new int[(terrainWidth - 1) * (terrainHeight - 1) * 6]; int counter = 0; for (int y = 0; y < terrainHeight - 1; y++) { for (int x = 0; x < terrainWidth - 1; x++) { int lowerLeft = x + y*terrainWidth; int lowerRight = (x + 1) + y*terrainWidth; int topLeft = x + (y + 1) * terrainWidth; int topRight = (x + 1) + (y + 1) * terrainWidth; indices[counter++] = topLeft; indices[counter++] = lowerRight; indices[counter++] = lowerLeft; indices[counter++] = topLeft; indices[counter++] = topRight; indices[counter++] = lowerRight; } } } private void SetUpCamera() { viewMatrix = Matrix.CreateLookAt(new Vector3(0, 10, 0), new Vector3(0, 0, 0), new Vector3(0, 0, -1)); projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 1.0f, 300.0f); } private void LoadHeightData() { heightData = new float[4, 3]; heightData[0, 0] = 0; heightData[1, 0] = 0; heightData[2, 0] = 0; heightData[3, 0] = 0; heightData[0, 1] = 0.5f; heightData[1, 1] = 0; heightData[2, 1] = -1.0f; heightData[3, 1] = 0.2f; heightData[0, 2] = 1.0f; heightData[1, 2] = 1.2f; heightData[2, 2] = 0.8f; heightData[3, 2] = 0; } protected override void UnloadContent() { } protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); base.Update(gameTime); } protected override void Draw(GameTime gameTime) { device.Clear(Color.DarkSlateBlue); device.RenderState.CullMode = CullMode.None; device.RenderState.FillMode = FillMode.WireFrame; effect.CurrentTechnique = effect.Techniques["Colored"]; effect.Parameters["xView"].SetValue(viewMatrix); effect.Parameters["xProjection"].SetValue(projectionMatrix); effect.Parameters["xWorld"].SetValue(Matrix.Identity); effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); device.VertexDeclaration = myVertexDeclaration; device.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length / 3); pass.End(); } effect.End(); base.Draw(gameTime); } } }