Creating a DirectX Device plus more.
Monday, November 28 2005
With the current work that I have been doing I have created a small base application that is the base for the application that I am working on at the moment. (This is going to be a long post as it includes code.) The example that I am posting is just a basic DirectX Device that use the AppIdle game loop and does some checks on the hardware before the device is created. Also included is a small example of using the DirectInput system to exit the application, as the program moves on I will have the DI doing a bit more. some of the plans I have is to integrate mouse movement and off course use Direct3D for 2D Operations.
So here it goes, The application is developed using the Visual Studio 2005 Pro system, but also works under the express product line. I has also use the ghostdoc application to generate the xml comment tags for the application. Start by creating a simple windows forms application then replace the code inside the program.cs file to the following...
//------------------------------------------------------------------------------------ // Copyright (c) ircomm.net. All rights reserved. // // The use and distribution terms for this software are covered by the // Common Public License 1.0 (<A href="http://opensource.org/licenses/cpl.php">http://opensource.org/licenses/cpl.php</A>) // which can be found in the file CPL.TXT at the root of this distribution. // By using this software in any fashion, you are agreeing to be bound by // the terms of this license. // // You must not remove this notice, or any other, from this software. // // Email: <A href="mailto:glenn.wilson@ircomm.net">glenn.wilson@ircomm.net</A> //------------------------------------------------------------------------------------ using System; using System.Collections.Generic; using System.Windows.Forms; namespace CreateDevice { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { using (CreateDevice GraphicsDisplay = new CreateDevice()) { if (!GraphicsDisplay.InitializeGraphics()) { MessageBox.Show("Could not initialize Direct3D. The application will now Exit."); return; } GraphicsDisplay.Show(); Application.Idle += new EventHandler(GraphicsDisplay.OnApplicationIdle); Application.Run(GraphicsDisplay); } } } } Next the main code for the Windows form is as follows.
//------------------------------------------------------------------------------------ // Copyright (c) ircomm.net. All rights reserved. // // The use and distribution terms for this software are covered by the // Common Public License 1.0 (<A href="http://opensource.org/licenses/cpl.php">http://opensource.org/licenses/cpl.php</A>) // which can be found in the file CPL.TXT at the root of this distribution. // By using this software in any fashion, you are agreeing to be bound by // the terms of this license. // // You must not remove this notice, or any other, from this software. // // Email: <A href="mailto:glenn.wilson@ircomm.net">glenn.wilson@ircomm.net</A> //------------------------------------------------------------------------------------ using System; using System.IO; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; using DI = Microsoft.DirectX.DirectInput; namespace CreateDevice { public partial class CreateDevice : Form { // DirectX Graphic Device private Device graphicDevice = null; // DirectInput Keyboard Device private DI.Device keyboardDevice = null; // Set the Default settings for the Display Device. private Color displayBackgroundColor = Color.Blue; private int displayScreenWidth = 640; private int displayScreenHeight = 400; private string displayTitle = "IrSamples - Create Device"; [System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern bool PeekMessage(out Message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags); /// <summary>Windows Message</summary> [StructLayout(LayoutKind.Sequential)] public struct Message { public IntPtr hWnd; public IntPtr msg; public IntPtr wParam; public IntPtr lParam; public uint time; public System.Drawing.Point p; } /// <summary> /// Initializes a new instance of the <see cref="T:CreateDevice"/> class. /// </summary> public CreateDevice() { InitializeComponent(); this.ClientSize = new Size(this.displayScreenWidth, this.displayScreenHeight); this.Text = this.displayTitle; } /// <summary> /// Initializes the graphics. /// </summary> /// <returns></returns> public bool InitializeGraphics() { try { PresentParameters presentParams = new PresentParameters(); // Run the Application in a Windowed mode. presentParams.Windowed = true; presentParams.SwapEffect = SwapEffect.Discard; // Set the DepthBuffer Stencil format to A 16-bit z-buffer bit depth. presentParams.AutoDepthStencilFormat = DepthFormat.D16; presentParams.EnableAutoDepthStencil = true; // Present the Display immediatly presentParams.PresentationInterval = PresentInterval.Immediate; // The runtime updates the window client area immediately, // and might do so more than once during the adapter // refresh period. Device.Present operations might be // affected immediately. This option is always available // for both windowed and full-screen swap chains. // Store the default adapter information int adapterOrdinal = Manager.Adapters.Default.Adapter; CreateFlags flags = CreateFlags.SoftwareVertexProcessing; // Check to see if we can use a pure device Caps caps = Manager.GetDeviceCaps(adapterOrdinal, DeviceType.Hardware); //Do we support hardware vertex processing? if (caps.DeviceCaps.SupportsHardwareTransformAndLight) { // Replace the software vertex processing flags = CreateFlags.HardwareVertexProcessing; } // Do we support a pure device? if (caps.DeviceCaps.SupportsPureDevice) { flags |= CreateFlags.PureDevice; } this.graphicDevice = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams); //set up DirectInput keyboard device... this.keyboardDevice = new DI.Device(DI.SystemGuid.Keyboard); this.keyboardDevice.SetCooperativeLevel(this, DI.CooperativeLevelFlags.Background | DI.CooperativeLevelFlags.NonExclusive); this.keyboardDevice.Acquire(); return true; } catch (DirectXException) { return false; } } /// <summary> /// Renders the graphics. /// </summary> public void RenderGraphics() { if (this.graphicDevice == null) return; // Clear the Graphics Display and set the background color this.graphicDevice.Clear(ClearFlags.Target, this.displayBackgroundColor, 1.0f, 0); // Begin the Dispay Preperation this.graphicDevice.BeginScene(); // Render the Display Objects Here // End the Graphics Scene Presentation this.graphicDevice.EndScene(); // Present the Graphics to the Display this.graphicDevice.Present(); } /// <summary> /// Updates the graphics. /// </summary> public void UpdateGraphics() { // Update the Graphics Objects here } /// <summary> /// Processes the state of the input. /// </summary> protected void ProcessInputState() { foreach (DI.Key k in this.keyboardDevice.GetPressedKeys()) { if (k == DI.Key.Escape) { //release the keyboard device this.keyboardDevice.Unacquire(); // Dispose of the Keyboard Device this.keyboardDevice.Dispose(); // Exit the Application Application.Exit(); } } } /// <summary> /// Called when [application idle]. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param> public void OnApplicationIdle(object sender, EventArgs e) { while (this.AppStillIdle) { // Process the Keyboad Input State this.ProcessInputState(); // Update the Graphics Objects this.UpdateGraphics(); // Render and Present the Graphics to the Display this.RenderGraphics(); } } /// <summary> /// Gets a value indicating whether [app still idle]. /// </summary> /// <value><c>true</c> if [app still idle]; otherwise, <c>false</c>.</value> private bool AppStillIdle { get { Message msg; return !PeekMessage(out msg, IntPtr.Zero, 0, 0, 0); } } } }
