The Interfaces of DirectDraw
DirectDraw is composed of a number of interfaces. If you recall from the discussion on the Component Object Model (COM) in Chapter 5, "DirectX Fundamentals and the Dreaded COM," interfaces are nothing more than collections of functions and/or methods that you use to communicate with components. Take a look at Figure 6.1 for a graphical illustration of the DirectDraw interfaces. And keep in mind, I am not going to put the version numbers on each of the interfaces; for now, let's talk in the abstract. For example, IDirectDraw is really up to version 7.0, so when we actually use it, we would be talking about IDirectDraw7, but for now, I just want to show basics and relationships.
As you can see, there are only five interfaces that make up DirectDraw:
IUnknown—All COM objects must be derived from this base interface, and DirectDraw is no exception. IUnknown doesn't contain much more than the Addref(), Release(), and QueryInterface() functions that are overridden by each of the other interfaces.
IDirectDraw— This is the main interface object that must be created to start working with DirectDraw. IDirectDraw literally represents the video card and support hardware. Interestingly enough, with MMS (Multiple Monitor Support) and Windows 98/ ME/XP/NT2000, now you can have more than one video card installed in your system and hence more than one DirectDraw object. However, in this book we'll assume that there is only one video card in the computer and always select the default card to represent the DirectDraw object, even if there is more than one card in the system.
IDirectDrawSurface— This represents the actual display surface(s) that you will create, manipulate, and display using DirectDraw. A DirectDraw surface can exist on the video card itself using VRAM (Video RAM) or within system memory. There are basically two types of surfaces: primary surfaces and secondary surfaces.
Primary surfaces usually represent the actual video buffer that is currently being rasterized and displayed by the video card. Secondary surfaces, on the other hand, are usually offscreen. In most cases, you will create a single primary surface to represent the actual video display, and then one or more secondary surfaces to represent object bitmaps and/or back buffers to represent offscreen drawing areas where you'll build up the next frame of animation. We'll get to the details of surfaces later in the chapter, but for now, take a look at Figure 6.2 for a little graphical elaboration.
IDirectDrawPalette— DirectDraw is equipped to deal with any color space, from 1-bit monochrome to 32-bit Ultra-True Color. Thus, DirectDraw supports the IDirectDrawPalette interface to deal with color palettes in video modes that use 256 or fewer colors. In this case, you will use the 256-color mode extensively in a number of demos because it's the fastest mode for a software rasterizer. In the discussion of Direct3D Immediate Mode in Volume II, you'll switch over to 24-bit color because that's the native mode that D3D likes to work in. In any case, the IDirectDrawPalette interface is used to create, load, and manipulate palettes, and to attach palettes to drawing surfaces, such as the primary or secondary surfaces that you might create for your DirectDraw applications. Take a look at Figure 6.3 to see the relationship between a drawing surface and a DirectDraw palette.
IDirectDrawClipper— This is used to help with clipping DirectDraw raster and bitmap operations to some subset of the visible display surface. In most cases, you'll only use DirectDraw clippers for windowed DirectX applications and/or to clip bitmap operations to the extents of your display surface, whether it be a primary or secondary surface. The cool thing about the IDirectDrawClipper interface is that it takes advantage of hardware acceleration if it's available, and the costly pixel-by-pixel or sub-image processing that is normally needed to clip bitmaps to the screen extents is done for you.
Now, before you move on to creating a DirectDraw object, I want to refresh your memory with some tasty tidbits of information that we touched upon in the previous chapter when dealing with COM. DirectDraw and all DirectX components are in constant flux, and thus the interfaces are always being upgraded. Alas, even though so far in this chapter I have referred to the interfaces of DirectDraw generically as IDirectDraw, IDirectDrawSurface, IDirectDrawPalette, and IDirectDrawClipper, for the most part these interfaces have all been updated and newer versions exist. For example as mentioned before, IDirectDraw is up to IDirectDraw7 as of DirectX version 7.0.
All this means is that if you want the very latest software and hardware performance, you should always IUnknown::QueryInterface() for the latest interface revision. However, to find this out you'll have to take a look at the DirectX SDK docs. Of course, in this book you're using DirectX 8.0, so you already know what's up, but keep in mind that when you upgrade to DirectX 9.0 you might have some newer interfaces that you want to use. However, both volumes of this book are about writing your own rasterization and 3D software, so I want to cheat as little as possible. In most cases, you're going to be using very few of the bells and whistles of all the new revisions. Cool, home slice?
Using the Interfaces Together
Of course, there are about a bazillion (yes, that's a technical term) little details I've left out, but that's the gist of using the different interfaces. With that in mind, let's get down to details and really make these interfaces work…
You might want to have both the DDRAW.H header file and the DirectX SDK Help system open for reference during the remainder of the chapter.