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;
These 3 fields define a 3d model

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
Another thing to note is that our class cosmicX is now Singleton, to provide easy reference to class Object
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);
        }
See its simple !

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

Popular Posts