I'm starting to feel like an evangelist for Microsoft these days (hint to Microsoft: Send me money), trying to turn all my friends to the dark side. But the bad guys always have better technology! Am I right? What would you rather ride around in, one of the Empire's Super Star Destroyers or some half-converted Rebel transport? See what I'm saying?
DirectX may take a bit more control from you as a programmer, but in truth it's worth its weight in gold. It's basically a system of software that abstracts video, audio, input, networking, installation, and more, so no matter what a particular PC's hardware configuration is, you can use the same code. In addition, DirectX technology is many times faster and more robust than GDI and/or MCI (the Media Control Interface), which is native to Windows.
Figure 5.1 illustrates how you would make a Windows game with and without DirectX. Notice how clean and elegant the DirectX solution is.
So how does DirectX work? Well, it gives you almost hardware-level control of all devices. This is possible through a technology called Component Object Model (COM) and a set of drivers and libraries written by both Microsoft and the hardware vendors themselves. Microsoft came up with a set of conventions—functions, variables, data structures, and so on—that must be used by the hardware vendors when implementing drivers to talk to the hardware.
As long as these conventions are followed, you don't need to worry about the details of the hardware. You just make calls to DirectX and it handles the details for you. No matter the video card, sound card, input device, network card, or whatever, as long as there's DirectX support, your program will be able to use it without you knowing anything about it!
Currently there are a number of DirectX components. They are listed here and shown graphically in Figure 5.2.
With the release of DirectX 8.0, Microsoft decided to tightly integrate DirectDraw and Direct3D together and refer to it as DirectX Graphics. The results are the removal of DirectDraw from version 8.0; however, you can still use DirectDraw, there's simply not an upgrade of it in DirectX 8.0. Additionally, DirectSound and DirectMusic are more tightly integrated and now called DirectX Audio. Finally, DirectShow (formerly from DirectMedia) has been integrated into DirectX. Those guys at Microsoft really are busy little beavers!
All this may seem a bit overwhelming and confusing, but the cool thing about DirectX is if we want we could just use DirectX 3.0, or 5.0, or 6.0, or whatever. It's up to us since with COM (which we will get to) we can work with whatever version we like that suits our needs. And in our case, version 7.0 and some of 8.0 is more than enough. Furthermore, if you know one version of DirectX you know them all, the syntax may change a little, the interfaces do more, but all in all it's roughly the same. The only thing that really changes quickly is Direct3D, and we aren't going to be talking about that in this book, per se, we are going to be talking about game programming. True, on the CD there are two books on 3D and one is on Direct3D, but within the book we are going to try and keep the monster of DirectX under control, so you learn it well enough to use to make games. But, your entire game programming life is not connected to it, and if you were to use another API, you would still understand the fundamental techniques of game programming, that's the ultimate goal of this book.
The HEL and HAL
In Figure 5.2, you may notice that there are two layers under DirectX called the HEL (Hardware Emulation Layer) and the HAL (Hardware Abstraction Layer). Here's the deal: DirectX is a very forward-looking design, so it assumes that advanced features are implemented by the hardware. However, if the hardware doesn't support some feature, what happens? This is the basis of the dual-mode HAL and HEL design.
The HAL, or Hardware Abstraction Layer, is the "to the metal" layer. It talks directly to the hardware. This layer is usually the device driver from the vendor, and you communicate to it directly through generic DirectX calls. The bottom line is that HAL is used when the feature you're requesting is supported directly by the hardware and thus is accelerated. For example, when you request a bitmap to be drawn, the hardware blitter does the work rather than a software loop.
The HEL, or Hardware Emulation Layer, is used when the hardware doesn't support the feature that you're requesting. Let's say that you ask the video card to rotate a bitmap. If the hardware doesn't support rotation, the HEL kicks in and software algorithms take over. Obviously, this is slower, but the point is that it does not break your program. It will still work—just slower. In addition, the switching between the HAL and HEL is transparent to you. If you ask DirectX to do something and the HAL does it directly, the hardware will do it. Otherwise, a software emulation will be called to get the job done with HEL.
Now, you might be thinking that there are a lot of layers of software here. That's a concern, but the truth is that DirectX is so clean that the only penalty you take for using it is maybe an extra function call or two. That's a small price to pay for 2D/3D graphics, network, and audio acceleration. Can you imagine writing drivers to control all the video accelerators on the market? Trust me, it would take literally thousands of man-years—it just can't be done. DirectX is really a massively distributed engineering effort by Microsoft and all the hardware vendors to bring you an ultra-high-performance standard.
The DirectX Foundation Classes in Depth
Now let's take a quick look at each DirectX component and what each does:
DirectDraw— This is the primary rendering and 2D bitmap engine that controls the video display. It's the conduit that all graphics must go through and probably the most important of all the DirectX components. The DirectDraw object represents more or less the video card(s) in your system. This is no longer available in DirectX 8.0 though, so we must use DirectX 7.0 interfaces for this one.
DirectSound— This is the sound component of DirectX. It only supports digital sound, not MIDI. However, this component makes your life 100 times easier because no longer do you have to license a third-party sound system to do your sound. Sound programming is a black art, and in the past no one wanted to keep up with writing all the drivers for all the sound cards. Hence, a couple of vendors cornered the market on sound libraries: Miles Sound System and DiamondWare Sound Toolkit. Both were very capable systems that allowed you to simply load and play digital and MIDI sounds from your DOS or Win32 programs. However, with DirectSound, DirectSound3D, and the latest DirectMusic components, there's obviously less use for third-party libraries.
DirectSound3— This is the 3D sound component of DirectSound. It allows you to position 3D sounds in space as if objects were floating around the room! This technology is relatively new, but it's maturing quickly. Today, most sound cards support hardware-accelerated 3D effects, including Doppler shift, refraction, reflection, and more. However, if software emulation is used, all this stuff comes to a halt!
DirectMusic— The newest addition to DirectX. Thank God! DirectMusic is the missing MIDI technology that DirectSound didn't support. But more than that, DirectMusic has a new DLS (Downloadable Sounds) system that allows you to create digital representations of instruments and then play them back with MIDI control. It's much like a Wave Table synthesizer, but in software. Also, DirectMusic has a new Performance Engine that is an artificial intelligence system of sorts. In real-time, it can make changes to your music based on templates you supply it with. In essence, the system can create new music on-the-fly. Wild, huh?
DirectInput— This system handles all input devices, including the mouse, keyboard, joystick, paddles, space balls, and so forth. Moreover, DirectInput now supports Force Feedback devices, which have electromechanical actuators and force sensors that allow you to physically manifest forces so the user can feel them. It's going to really put the cybersex industry into overdrive!
DirectPlay— This is the networking aspect of DirectX. It allows you to make abstract connections using the Internet, modems, direct connect, or any other kind of medium that might come up. The cool thing about DirectPlay is that it allows you to make these connections without knowing anything about networking. You don't have to write drivers, use sockets, or anything like that. In addition, DirectPlay supports the concepts of sessions, which are games in progress, and lobbies, which are places for gamers to congregate and play. Also, DirectPlay doesn't force you into any kind of multiplayer network architecture. All it does is send and receive packets for you. What they contain and if they are reliable is up to you.
Direct3DRM— This is Direct3D Retained Mode, which is a high-level, object- and frame-based 3D system that you can use to create basic 3D programs. It takes advantage of 3D acceleration, but it isn't the fastest thing in the world. It's great for making walkthrough programs, model displayers, or extremely slow demos.
Direct3DIM— This is Direct3D Immediate Mode, which is the low-level 3D support for DirectX. Originally, this was incredibly hard to work with and was the cause for many flamewars with OpenGL. The old Immediate Mode used what are called execute buffers, basically arrays of data and instructions that you created that described the scene to be drawn—very ugly. However, since DirectX 5.0, Immediate Mode now supports a much more OpenGL-like interface through the DrawPrimitive() functions. This allows you to send triangle strips, fans, and so on to the rendering engine and make state changes with function calls rather than execute buffers. Hence, I now like Direct3D Immediate Mode! Even though this volume and Volume II are software-based 3D game books, to be complete, we're going to cover D3D IM at the end of Volume II. In fact, there is an entire cyber-book on Direct3D Immediate Mode on the CD of Volume II.
DirectSetup/AutoPlay— These are quasi-DirectX components that allow a program to install DirectX from your application on the user's machine and start your game up directly when the CD is placed in the system. DirectSetup is a small set of functions that load the run-time DirectX files on a user's machine and register them in the registry. AutoPlay is the standard CD subsystem that looks for the AUTOPLAY.INF file on the CD root. If the file is found, AutoPlay executes the batch command functions in the file.
DirectX Graphics— Microsoft decided to merge the functionality of DirectDraw and Direct3D here to increase performance and allow 3D effects in a 2D domain. I personally don't think that DirectDraw should have been removed. Not only is there a lot of software that uses it, but using Direct3D to do 2D is a pain for the most part, it's overkill in many applications that are 2D in nature for example GUI applications or other simple games. In any case, we won't need to worry about it since we are going to use DirectX 7.0 interfaces for DirectDraw.
DirectX Audio— This merger is far less destructive than that of DirectX Graphics, here DirectSound and DirectMusic have been more tightly integrated—that's about it, nothing has been removed. In DirectX 7.0 DirectMusic was still a little on its own, totally COM based, and not accessible from DirectSound. With DirectX Audio this has changed, and you can work with them together if you wish.
DirectShow— This component is used to stream media on the Windows platform. DirectShow provides for high-quality capture and playback of multimedia streams. It supports a wide variety of formats, including Advanced Streaming Format (ASF), Motion Picture Experts Group (MPEG), Audio-Video Interleaved (AVI), MPEG Audio Layer-3 (MP3), and WAV files. It supports capture using Windows Driver Model (WDM) devices or older Video for Windows devices. DirectShow is integrated with other DirectX technologies. It automatically detects and uses video and audio acceleration hardware when available, but also supports systems without acceleration hardware. This makes life really easy, since before when you wanted to play some video in a game you either had to use a 3rd party library or write one yourself. This is REALLY nice since it's integrated into DirectX. The only problem is it's rather advanced, and takes quite a bit to set up and use.
Finally, you might be wondering what the deal is with all the versions of DirectX. It seems to be revised on a six-month basis. This is true, for the most part. It's a hazard of the business we're in—graphics and game technology move very fast. However, since DirectX is based on COM technology, programs that you write for, say, DirectX version 3.0 are guaranteed to work on DirectX version 8.0. Let's see how that works…