Getting started with SlimDX

Since I tried OpenTK, I decided to give SlimDX a try as well. So, here’s a simple getting started app:

using System;
using System.Drawing;
using System.Windows.Forms;
using SlimDX;
using SlimDX.Direct3D9;
using SlimDX.Windows;

namespace SlimDXApp1
{
	public partial class SlimDXApp1Form : RenderForm
	{
		struct Vertex
		{
			public Vector4 Position;
			public int Color;
		}

		Device device;
		VertexDeclaration vertexDeclaration;

		public SlimDXApp1Form()
			: base("SlimDXApp1")
		{
			this.ClientSize = new Size(800, 600);

			this.device = new Device(new Direct3D(), 0, DeviceType.Hardware, this.Handle, CreateFlags.HardwareVertexProcessing, new PresentParameters()
            {
                BackBufferWidth = this.ClientSize.Width,
                BackBufferHeight = this.ClientSize.Height
            });

			this.vertexDeclaration = new VertexDeclaration(this.device, new[] {
        		new VertexElement(0, 0, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.PositionTransformed, 0),
        		new VertexElement(0, 16, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),
				VertexElement.VertexDeclarationEnd
        	});
		}

		public void Run()
		{
			MessagePump.Run(this, () =>
			{
				this.device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);
				this.device.BeginScene();

				this.device.VertexDeclaration = this.vertexDeclaration;

				this.device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, new[] {
					new Vertex() { Color = Color.Red.ToArgb(), Position = new Vector4(400.0f, 100.0f, 0.5f, 1.0f) },
					new Vertex() { Color = Color.Blue.ToArgb(), Position = new Vector4(650.0f, 500.0f, 0.5f, 1.0f) },
					new Vertex() { Color = Color.Green.ToArgb(), Position = new Vector4(150.0f, 500.0f, 0.5f, 1.0f) }
				});

				this.device.EndScene();
				this.device.Present();
			});
		}

		[STAThread]
		static void Main()
		{
			SlimDXApp1Form form = new SlimDXApp1Form();
			form.Run();

			// Cleans up COM handles
			foreach(var item in ObjectTable.Objects)
				item.Dispose();
		}
	}
}

Getting started with OpenTK

I started experimenting with OpenTK and I had to look in a few places to put this code together, so I’m posting it here for anyone who might be looking for an easy getting started lesson.

I’ve set up a window similar to what I’ve been used to in Xna (CornflowerBlue 4 life). I’ve also set up a 2D projection matrix and drawn a triangle in a 2D fashion. You’ll need to add a reference to the OpenTK assembly for your project in Visual Studio.

using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;

namespace OpenTKApp1
{
	public class AppWindow : GameWindow
	{
		public AppWindow()
		{
			this.Title = "OpenTK App 1";
			this.WindowBorder = WindowBorder.Fixed;
			this.ClientSize = new Size(800, 600);
		}

		protected override void OnRenderFrame(FrameEventArgs e)
		{
			base.OnRenderFrame(e);

			GL.ClearColor(Color.CornflowerBlue);
			GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

			GL.MatrixMode(MatrixMode.Projection);
			GL.LoadIdentity();
			GL.Ortho(0, 800, 600, 0, -1, 1);
			GL.Viewport(0, 0, 800, 600);

			GL.Begin(BeginMode.Triangles);
			GL.Color3(Color.Red);
			GL.Vertex3(400, 150, 0);
			GL.Color3(Color.Green);
			GL.Vertex3(600, 450, 0);
			GL.Color3(Color.Blue);
			GL.Vertex3(200, 450, 0);
			GL.End();

			GL.Flush();
			this.SwapBuffers();
		}

		[STAThread]
		public static void Main()
		{
			AppWindow window = new AppWindow();
			window.Run();
		}
	}
}

Keeping SplitContainer SplitterDistance consistent

If you’re having trouble keeping the SplitterDistance property of a SplitContainer consistent across app sessions, you can set the FixedPanel property of the splitter to FixedPanel.Panel1.

splitter.FixedPanel = FixedPanel.Panel1;

I guess this could also work with FixedPanel.Panel2 as well but I haven’t given it a try. Credit this stackoverflow post.

Favoring Composition over Inheritance

You may have heard the expression before “Favor Composition over Inheritance”, but do you know what it means and how to apply it? Lets take this code for example:

abstract class Car
{
	public Color Color { get; protected set; }
	public Engine Engine { get; protected set; }
}

class ElectricCar : Car
{
	public ElectricCar()
	{
		this.Color = Color.Blue;
		this.Engine = new ElectricEngine();
	}
}

class SportsCar : Car
{
	public SportsCar()
	{
		this.Color = Color.Red;
		this.Engine = new V8Engine();
	}
}

class Truck : Car
{
	public Truck()
	{
		this.Color = Color.White;
		this.Engine = new DieselEngine();
	}
}

In this contrived example, we’ve defined three types of cars. Each instance of each of the cars will always have the same color and same engine. What happens when we need a 4th type? We have to define another class. By refactoring this code, we can compose a car type by giving it a color and an engine:

class Car
{
	public Color Color { get; private set; }
	public Engine Engine { get; private set; }

	public Car(Color color, Engine engine)
	{
		this.Color = color;
		this.Engine = engine;
	}
}

Car electricCar = new Car(Color.Blue, new ElectricEngine());
Car sportsCar = new Car(Color.Red, new V8Engine());
Car truck = new Car(Color.White, new DieselEngine());
Car familyCar = new Car(Color.Black, new V4Engine());

Now we can compose many car types, with any combination of colors and engines and we’ve only defined one class.