First Steps: Setting Up DirectXThe first stage in learning to use "Enhanced 2D" requires the creation of a minimal Win32 application. The sources that come with this article include WinMain.cpp (for each example), which is about as minimal as you can get if you still want your program to be called "Win32"! The only significant items to note in this code are the following:
The DXEngine FrameworkI'm a diehard C++ fan. I admit it. Classes, Object Oriented Programming and similar concepts appeal to me in ways that probably can't be described to minors… or at least intellectually, anyway. ;-) Because of my love for C++, I've designed the framework used for all the demonstrations in an object oriented manner. DXEngine is the base class for the game itself. Its an abstract class - meaning you can't instantiate it. It includes all of the code necessary to initialize DirectDraw and Direct3D, and hides it away in a single call to InitDirectX(). All a programmer wanting this functionality in his/her program needs to do is inherit this class and write GameInit(), GameMain() and GameDone(). Is that not nifty? Setting up DirectDrawDXEngine does quite a lot of work to bring DirectDraw to life. Much of this code originally came from LaMothe's work (although the BOB engine itself was trashed very quickly - talk about slow). The function that does all the work for setting up DirectDraw is InitDirectDraw() (no surprises there!). It doesn't differ significantly from the steps that you would need in general - although it does take the time to work in both windowed and fullscreen modes. Basically, it gets an interface to DirectDraw, sets the cooperation level, creates the screen mode, creates a primary and secondary surface and then sets up a clipper. Nothing too revolutionary. A few points in it need to be highlighted, however, in the context of Direct3D:
Setting Up Direct3DInitDirect3D() handles most of this work. Since this is all new material to most people, I'll go through the initialization process in detail. Fortunately, its not as complicated as it could be. Direct3D 7 actually includes some helper functions to make this even easier - but we'll learn more doing it the hard way! (See the DirectX 7 SDK for details of the easy way to do this). The first step in initializing Direct3D is to query DirectDraw for an interface (ReportError is part of my DXEngine class - it displays a message box):
The second step is to enumerate 3D devices. This is done with the FindDevice command (part of the Direct3D interface). The following code looks for hardware accelerated Direct3D devices:
Assuming that this found a device, the next stage is to go ahead and create it. This can be as simple as calling CreateDevice (again, part of the Direct3D interface). The following line of code searches for a hardware accelerated device:
In my code, I actually expand on this somewhat; if a HAL device isn't found, DXEngine will look for an MMX device, then a regular RGB (software emulated) device. This isn't strictly necessary, though. The final stage in starting up Direct3D involves the creation of a viewport. Viewports tell Direct3D how to render the world. Part of this structure sets up 3D clipping - and is only really of use if you are using Direct3D's transformation functions. It's of no use to this article, so we can ignore it. The important part is this:
What this does is it sets up a viewport structure with the screen size (if you wanted to render a smaller window, you can change these values). Then it creates the viewport, adds it to the device, adds the data to the viewport itself, and tells the device to use it. Overly complicated, if you ask me, but it gets the job done. When you are finished with Direct3D, it's a good idea to release the variables you've allocated:
If you don't do this, memory leaks are pretty likely. You may also make it impossible to run other Direct3D programs (until you reboot)… not a good idea - especially if you want to keep any fans you might have! |
|||||||||||