Meditation, The Art of Exploitation

Thinking? At last I have discovered it--thought; this alone is inseparable from me. I am, I exist--that is certain. But for how long? For as long as I am thinking. For it could be, that were I totally to cease from thinking, I should totally cease to exist....I am, then, in the strict sense only a thing that thinks.

Friday, May 26, 2006

Introduction

This article shows how to use .net windows form controls with managed directx content. Most books/tutorials use a winform strictly with MDX content. But people are more interested in using winform controls together with MDX. This question is frequently asked and not well answered. Here I present a small code project using .net 2.0 and visual studio 2005.

Technique

The most important part of this project the directx device creation. Normally it's
device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);           
'this' is the alias of 'Form' used to represent this winForm.
In order to make .net controls such as menu bar etc to co-exist with directx control, I set up a panel to be used by directx.
private System.Windows.Forms.Panel panel1;
// Initialize panel1
device = new Device(0, DeviceType.Hardware, panel1, CreateFlags.SoftwareVertexProcessing, presentParams);
To demonstrate that this works, I have provided a simple managed directx project with this project that can be downloaded. The complete source code:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace Chapter1Code
{
///
/// Summary description for Form1.
///

public class Form1 : System.Windows.Forms.Form
{
private Device device = null;
///
/// Required designer variable.
///

private System.ComponentModel.Container components = null;
private Panel panel1;
private MenuStrip menuStrip1;
private ToolStripMenuItem mDXFormWithMenuToolStripMenuItem;
private ToolStripMenuItem exitToolStripMenuItem;
private float angle = 0.0f;

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

this.Size = new Size(800, 600);
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
}

///
/// We will initialize our graphics device here
///

public void InitializeGraphics()
{
// Set our presentation parameters
PresentParameters presentParams = new PresentParameters();

presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;

// Create our device
device = new Device(0, DeviceType.Hardware, panel1, CreateFlags.SoftwareVertexProcessing, presentParams);
}

private void SetupCamera()
{
device.RenderState.CullMode = Cull.None;
device.Transform.World = Matrix.RotationAxis(new Vector3(angle / ((float)Math.PI * 2.0f), angle / ((float)Math.PI * 4.0f), angle / ((float)Math.PI * 6.0f)), angle / (float)Math.PI);
angle += 0.1f;

device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1.0f, 100.0f);
device.Transform.View = Matrix.LookAtLH(new Vector3(0,0, 5.0f), new Vector3(), new Vector3(0,1,0));
device.RenderState.Lighting = true;
}

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
device.Clear(ClearFlags.Target, System.Drawing.Color.CornflowerBlue, 1.0f, 0);

SetupCamera();

CustomVertex.PositionNormalColored[] verts = new CustomVertex.PositionNormalColored[3];
verts[0].Position = new Vector3(0.0f, 1.0f, 1.0f);
verts[0].Normal = new Vector3(0.0f, 0.0f, -1.0f);
verts[0].Color = System.Drawing.Color.White.ToArgb();
verts[1].Position = new Vector3(-1.0f, -1.0f, 1.0f);
verts[1].Normal = new Vector3(0.0f, 0.0f, -1.0f);
verts[1].Color = System.Drawing.Color.White.ToArgb();
verts[2].Position = new Vector3(1.0f, -1.0f, 1.0f);
verts[2].Normal = new Vector3(0.0f, 0.0f, -1.0f);
verts[2].Color = System.Drawing.Color.White.ToArgb();

device.Lights[0].Type = LightType.Point;
device.Lights[0].Position = new Vector3();
device.Lights[0].Diffuse = System.Drawing.Color.White;
device.Lights[0].Attenuation0 = 0.2f;
device.Lights[0].Range = 10000.0f;

device.Lights[0].Enabled = true;

device.BeginScene();
device.VertexFormat = CustomVertex.PositionNormalColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, verts);
device.EndScene();

device.Present();

this.Invalidate();
}

///
/// Clean up any resources being used.
///

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///

private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.mDXFormWithMenuToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip1.SuspendLayout();
this.SuspendLayout();
//
// panel1
//
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(0, 24);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(307, 275);
this.panel1.TabIndex = 0;
//
// menuStrip1
//
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mDXFormWithMenuToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(307, 24);
this.menuStrip1.TabIndex = 1;
this.menuStrip1.Text = "menuStrip1";
//
// mDXFormWithMenuToolStripMenuItem
//
this.mDXFormWithMenuToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.exitToolStripMenuItem});
this.mDXFormWithMenuToolStripMenuItem.Name = "mDXFormWithMenuToolStripMenuItem";
this.mDXFormWithMenuToolStripMenuItem.Size = new System.Drawing.Size(117, 20);
this.mDXFormWithMenuToolStripMenuItem.Text = "MDX form with Menu";
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.exitToolStripMenuItem.Text = "Exit";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
//
// Form1
//
this.ClientSize = new System.Drawing.Size(307, 299);
this.Controls.Add(this.panel1);
this.Controls.Add(this.menuStrip1);
this.Name = "Form1";
this.Text = "Form1";
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();

}
#endregion

///
/// The main entry point for the application.
///

static void Main()
{
using (Form1 frm = new Form1())
{
// Show our form and initialize our graphics engine
frm.Show();
frm.InitializeGraphics();
Application.Run(frm);
}
}

private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Dispose();
}
}
}