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.

Xna: Load Texture2D from Embedded Resource

If you’re writing an app which uses Xna, you may need to load a texture from an embedded resource. Here’s how:

First embed the resource in your app. Do so by choosing Embedded Resource as the Build Action in the properties of the resource.

Properties Dialog for a File

After that you can load the Texture2D using a stream handle to the embedded file.

Stream stream = Assembly.GetCallingAssembly().GetManifestResourceStream("AppNamespace.Folder.font.bmp");
return Texture2D.FromFile(graphicsDevice, stream);

GetCallingAssembly() can be exchanged with GetExecutingAssembly() if needed. The name of the resource must be fully qualified with the app’s namespace and folders. I usually keep my resources in a folder Resources so I would have: AppNamespace.Resources.font.bmp.