Tutorial 2, DirectX using C#
DirectX using C#
Tutorial 2
Required Files
Loading a model
Models are 3d objects that form part of game. We'll have separate class for managing these objects nested within cosmicX.
Contents of class Object
private Mesh mesh; private Material[] materials; private Texture[] textures;
private float radius; public Vector3 Position, centre, Orientation, LocalAxis, Scaling;
- radius -> used for simple collision detection
- Orientation is actually angle(s) made by object with X, Y, Z axis
- LocalAxis will be used for moving object in 3d space
static cosmicX _CosmicX; public static cosmicX CosmicX { get { return cosmicX._CosmicX; } set { cosmicX._CosmicX = value; } }
Using the code
cosmicX.Object truck; public Form1() { InitializeComponent(); SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true); X = new cosmicX(this); truck = new cosmicX.Object("slam\\slam.x", 1); }
Output
Complete Code
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; using D3D = Microsoft.DirectX.Direct3D; namespace XBasic { public partial class Form1 : Form { class cosmicX { event EventHandler Render; #region -FIELDS- D3D.Device device; Form form; float aspectRatio; static cosmicX _CosmicX; #endregion #region -Properties- public D3D.Device Device { get { return device; } set { device = value; } } public static cosmicX CosmicX { get { return cosmicX._CosmicX; } set { cosmicX._CosmicX = value; } } #endregion #region -Methods- public cosmicX(Form f) { CosmicX = this; this.form = f; D3D.PresentParameters presentParams = new D3D.PresentParameters(); presentParams.Windowed = true; presentParams.SwapEffect = SwapEffect.Discard; presentParams.AutoDepthStencilFormat = DepthFormat.D16; presentParams.EnableAutoDepthStencil = true; this.Device = new D3D.Device(0, D3D.DeviceType.Hardware, f, CreateFlags.SoftwareVertexProcessing, presentParams); calculateAspectRatio(); } void calculateAspectRatio() { this.device.RenderState.Lighting = true; this.device.Lights[0].Type = LightType.Directional; this.device.Lights[0].Diffuse = Color.White; this.device.Lights[0].Direction = new Vector3(1, 1, -1); this.device.Lights[0].Update(); this.device.Lights[0].Enabled = true; this.device.Lights[1].Type = LightType.Directional; this.device.Lights[1].Diffuse = Color.White; this.device.Lights[1].Direction = new Vector3(-1, -1, -1); this.device.Lights[1].Update(); this.device.Lights[1].Enabled = true; this.aspectRatio = (float)form.Width / (float)form.Height; this.device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.aspectRatio, 0.3f, 500f); } public void RenderX() { this.device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkSlateBlue, 1.0f, 0); this.device.BeginScene(); this.device.RenderState.Ambient = Color.DarkGray; if (Render != null) Render(this, null); this.device.EndScene(); this.device.Present(); this.form.Invalidate(); } #endregion public class Object { private Mesh mesh; private Material[] materials; private Texture[] textures; object _Tag; public object Tag { get { return _Tag; } set { _Tag = value; } } private float radius; public Vector3 Position, centre, Orientation, LocalAxis, Scaling; public Object(string Filename, float scaling) : this(Filename, scaling, true) { } public Object(string Filename, float scaling, bool renderable) { Scaling = new Vector3(scaling, scaling, scaling); LoadMesh(Filename, ref mesh, ref materials, ref textures, ref radius, scaling, out centre); Position = new Vector3(0, 0, 0); if (renderable) CosmicX.Render += new EventHandler(_CosmicX_Render); Orientation = new Vector3(0, 0, 0); LocalAxis = new Vector3(0, 0, 1); } public void LoadMesh(string filename, ref Mesh mesh, ref Material[] meshmaterials, ref Texture[] meshtextures, ref float meshradius, float scaling, out Vector3 meshcenter) { if (!System.IO.File.Exists(filename)) { throw new Exception("File not found " + filename); } ExtendedMaterial[] materialarray; mesh = Mesh.FromFile(filename, MeshFlags.Managed, CosmicX.device, out materialarray); if ((materialarray != null) && (materialarray.Length > 0)) { meshmaterials = new Material[materialarray.Length]; meshtextures = new Texture[materialarray.Length]; for (int i = 0; i < materialarray.Length; i++) { meshmaterials[i] = materialarray[i].Material3D; meshmaterials[i].Ambient = meshmaterials[i].Diffuse; if ((materialarray[i].TextureFilename != null) && (materialarray[i].TextureFilename != string.Empty)) { System.IO.FileInfo fi = new System.IO.FileInfo(filename); if (System.IO.File.Exists(fi.DirectoryName + "\\" + materialarray[i].TextureFilename)) { meshtextures[i] = TextureLoader.FromFile(CosmicX.device, fi.DirectoryName + "\\" + materialarray[i].TextureFilename); } else System.Diagnostics.Debug.Print("File not found: " + materialarray[i].TextureFilename + " !"); } } } mesh = mesh.Clone(mesh.Options.Value, CustomVertex.PositionNormalTextured.Format, CosmicX.device); mesh.ComputeNormals(); VertexBuffer vertices = mesh.VertexBuffer; GraphicsStream stream = vertices.Lock(0, 0, LockFlags.None); meshradius = Geometry.ComputeBoundingSphere(stream, mesh.NumberVertices, mesh.VertexFormat, out meshcenter) * scaling; } public void DrawMesh() { for (int i = 0; i < materials.Length; i++) { CosmicX.device.Material = materials[i]; CosmicX.device.SetTexture(0, textures[i]); mesh.DrawSubset(i); } } void _CosmicX_Render(object sender, EventArgs e) { Render(); } public void Render() { CosmicX.device.Transform.World = Matrix.Scaling(Scaling.X, Scaling.Y, Scaling.Z) * Matrix.RotationX(Orientation.X) * Matrix.RotationZ(Orientation.Z) * Matrix.RotationY(Orientation.Y) * Matrix.Translation(Position); DrawMesh(); } public void Dispose() { CosmicX.Render -= _CosmicX_Render; mesh = null; materials = null; textures = null; System.GC.SuppressFinalize(this); } } } cosmicX X; cosmicX.Object truck; public Form1() { InitializeComponent(); SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true); X = new cosmicX(this); truck = new cosmicX.Object("slam\\slam.x", 1); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); X.RenderX(); } } }
Comments
Post a Comment