RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Drawing with Direct3D, Part 1: Getting Started : Page 2

Learn how to produce amazing, high-performance, three-dimensional pictures in Visual Basic or C# by using Direct3D.

Installing the SDK
Before you can do anything with Direct3D you need to install the DirectX SDK. Before you can even do that, you need to decide which version of DirectX you want to use.

The most recent major version is DirectX 10. Unfortunately, DirectX 10 was designed to support the graphical needs of Windows Vista, is supported only for Vista, and Microsoft has no plans to make it compatible with other previous operating systems. However, DirectX 10 (and Vista) should eventually provide the best performance on computers that have hardware support for DirectX 10, although I have yet to see any computers with DirectX 10 hardware in the wild.

DirectX 9, on the other hand, supports several operating systems, including Windows XP, Windows Server 2003, and Windows Vista.

Author's Note: I wrote the code for this article with DirectX 9 in Windows XP, but all of the code shown here should work with little or no change in both DirectX 9 and 10, so you probably can't make a really bad choice no matter which version you choose.

After you decide which version you want to use, go to Microsoft's web site and download the SDK installation kit. You can either go to the Microsoft Download Center and search for "DirectX SDK," or you can go to the DirectX Resource Center, and look for the latest download.

Even though DirectX 10 is available, Microsoft will continue to support DirectX 9 and in fact plans to release updated versions of DirectX 9. The current version is 9.21.1148 dated November 2007 and weighs in at around 47 MB.

Download the version you want to use, and run the executable install file. The kit should decompress itself and install with little effort.

Creating a Device
Older versions of DirectX were fairly hard to use, providing features only as API-like functions with somewhat confusing structures and data types. The latest versions of DirectX are much easier to use, providing managed code and classes that greatly simplify the confusion. Still, there are several non-obvious steps that you need to follow to get things off the ground.

This first sample program will create a single form that displays a blank background. The program is controlled by a Main method that continuously redraws the form as long as the form is loaded. You won't see anything except the blank background, but this program sets up the tools you need to do something more interesting in the next section.

Start by creating a new Windows Forms application. I'm using Visual Basic 2005 for this article but similar steps should apply to other versions of Visual Basic or to C#.

After you create the new application, open the Project menu and select the Properties command at the bottom. On the Application tab, uncheck the "Enable application framework" box, and set the startup object to Sub Main. Next, go to the References tab, click the Add button, and add references to the Microsoft.DirectX and Microsoft.DirectX.Direct3D namespaces.

Open the Project menu again, select Add Module, and create the Main method shown in the following code:

   Module SubMain
      ' Prepare Direct3D and run the event loop.
      Public Sub Main()
         ' Make the form.
         Dim frm As New RenderForm
         ' Initialize Direct3D.
         If frm.InitializeGraphics() Then
            ' While the form is valid,
            ' render the scene and process messages.
            Do While frm.Created
         End If
      End Sub
   End Module
Author's Note: In C#, you can add similar code to the main method in Program.cs.

The Main method above starts by creating a new instance of the program's form class, named RenderForm. That class provides two methods that the main program uses to produce Direct3D: InitializeGraphics and Render, described shortly.

After it creates the form, the Main method calls the form's InitializeGraphics function to create the Direct3D device and prepares Direct3D for use.

If the call to InitializeGraphics succeeds, the program displays the form and then enters a loop. As long as the form exists (in other words, until the user closes it), the program repeatedly calls the form's Render method to draw the form's blank background. It also calls DoEvents so the program has time to process other events such as the user trying to close the form.

The program's form class does most of the work. The following code shows its InitializeGraphics function:

   ' The Direct3D device.
   Private m_Device As Device
   ' Initialize the graphics device. Return True if successful.
   Public Function InitializeGraphics() As Boolean
      Dim params As New PresentParameters
      params.Windowed = True
      params.SwapEffect = SwapEffect.Discard
      ' Best: Hardware device and hardware vertex processing.
         m_Device = New Device(0, DeviceType.Hardware, Me, _
            CreateFlags.HardwareVertexProcessing, params)
         Debug.WriteLine("Hardware, HardwareVertexProcessing")
      End Try
      ' Good: Hardware device and software vertex processing.
      If m_Device Is Nothing Then
            m_Device = New Device(0, DeviceType.Hardware, Me, _
               CreateFlags.SoftwareVertexProcessing, params)
            Debug.WriteLine("Hardware, SoftwareVertexProcessing")
         End Try
      End If
      ' Adequate?: Software device and software vertex processing.
      If m_Device Is Nothing Then
            m_Device = New Device(0, DeviceType.Reference, Me, _
               CreateFlags.SoftwareVertexProcessing, params)
            Debug.WriteLine("Reference, SoftwareVertexProcessing")
         Catch ex As Exception
            ' If we still can't make a device, give up.
            MessageBox.Show("Error initializing Direct3D" & _
               vbCrLf & vbCrLf & ex.Message, _
               "Direct3D Error", MessageBoxButtons.OK)
            Return False
         End Try
      End If
      ' We succeeded.
      Return True
   End Function
The form class starts by defining a Direct3D Device object. This object represents the Direct3D drawing surface and provides the methods that the program needs to draw.

The InitializeGraphics function tries to create the Direct3D device. It starts by creating a PresentParameters object to hold information about the type of presentation the program wants. In this example, the Direct3D device displays output in a window (as opposed to using the whole screen) and discards old buffered graphics whenever it displays a new scene.

Next InitializeGraphics tries to create the device. Note that the example tries to create three different devices, in decreasing order of performance. First it tries to create a hardware-assisted device to process the vertex data that determines where shapes are drawn. This type of device gives the best performance but works only if the computer's hardware can support Direct3D.

If the program cannot create this device, it tries to make a hardware device that uses software to process vertex data. That device type isn't as fast as the hardware-based device, but still gives good performance.

If creation of those device types fails, InitializeGraphics tries to create a reference device that emulates Direct3D functionality in software. This device has limited performance—in fact the performance may not be good enough for some applications. The software-emulation device isn't really intended for commercial applications, but it's better than nothing.

If the InitializeGraphics function cannot create any of these types of devices, it displays an error message and returns False to tell the main program that it failed.

The following code shows the structure of the RenderForm class's simple Render method that does the actual drawing:

   ' Draw.
   Public Sub Render()
      ' Clear the back buffer.
      m_Device.Clear(ClearFlags.Target, Color.Black, 1, 0)
      ' Make a scene.
      ' Draw stuff here...
      ' End the scene and display.
   End Sub
Figure 2. Blank Screen: The d3dCreateDevice program displays a blank scene.
The Render method starts by calling the device's Clear method to clear the drawing surface. The first parameter indicates the type of drawing object that the method should clear. This example uses Clear to clear the drawing target. Other options for this parameter cause the method to clear the stencil buffer or z-buffer, neither of which are needed for this example. The final parameters to Clear give more information for use by stencils and the z-buffer.

Next, the Render method calls the device's BeginScene method to tell the device that a new drawing is on the way. A more interesting example would then draw objects in three-dimensional space before calling EndScene to let the device know that the scene is complete. Finally the method calls Present to display the scene.

The sample program d3dCreateDevice uses this code to display a blank RenderForm. Figure 2 shows the unimpressive result: a form with a black background.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date