An introduction to DirectDraw and Direct3d

by Chris Byrd

Disclaimer

Didn't have a MSVC compiler so was unable to actually compile any code and was dependent on the accuracy of the documentation to put together the information in this presentation.

Introduction

This presentation gives an introduction to the DirectDraw and Direct3d components of Microsofts DirectX SDK. This presentation is intended to be more an overview of the graphics components of DirectX and how they can be used than a comprehensive programming introduction, hence all of the nitty gritty details neccassary to get a DirectX application up and running are not neccassarily mentioned.

1. The DirectX package

a) What is it, what is it used for.

DirectX is a suite of libraries, that provide a standard set of functions for interfacing with the graphics, sound, input, and network pieces of a PC running Windows95/NT. In previous iterations DerectX was called the Game SDK, and has traditionally been aimed primary at the computer gaming market. What DirectX provides is a common interface to the graphics/sound capabilities of a machine independent of what the actual hardware is. One of the age old problems with programming graphics on a PC has been the need to tailor your code to fit every possible graphics card available. DirectX provides a solution to application programmers to allow them to program using one API and making each manufacturer of hardware responsible for providing a DirectX driver. Another benefit of DirectX is that in the past graphics and windows were notorious for poor speed. DirectX provides a much faster interface to graphics than the standard windows functions, and makes a graphically intensive windows program a more viable option.

b) where does DirectDraw/Direct3d fit in

I will be talking about DirectDraw and Direct3D the two graphics components of DirectX. Since the other pieces have little or no relevance to this class they won't be mentioned. Direct3D is a 3D graphics library (sort of like OpenGl with the addition of high level 3d routines), and DirectDraw is the piece that provides applications with direct access to video memory.

3. DirectDraw

a) Overview

As mentioned above DirectDraw has an advantage over the standard windows Graphics Device Interface (GDI). Whereas the GDI has to go through windows to draw, Directdraw talks directly to the video memory.

Besides faster video access DirectDraw also provides automatic video configuration, the automatic use of graphics acceleration hardware, and a set of standard graphics functions.

b) Overall architecure - HEL/HAL

DirectDraw's Hardware Abstraction Layer (HAL) in combination with its Hardware Emulation Layer allows applications to automatically make the best use out of the graphics card that they own. If there is a computer that has the appropriate hardware a request from Directdraw will be sent directly to the HAL. If on the otherhand the hardware does not support a particular operation the request will go to the HEL were the appropriate command is emulated (albeit slower) in software. This makes the process totally transparent to the application.

c) Direct draw objects

DirectDraw is composed of 4 main object classes, DirectDraw itself, IDirectDrawSurface IDirectDrawPalette and IDirectDrawClipper.

e) DirectDraw

This object that needs to be created for starting off DirectDraw. The Directdraw object represents the display device, and is responsible for setting up the properties of the display, such as resolution and how the Directdraw window will interact in the windows environment. In a system with multiple display devices one might have one DirectDraw object for each one. This object also provides the means for creating the other 3 types of objects. The DirectDraw object does all this through member functions that are contained in its class.

e) Surfaces

DirectDraw surfaces are the pieces of memory that are used for drawing on. A surface contains the image data, sprites, bitmaps, the actual screen etc. A surface is created through a member function of the DirectDraw object.

Simple Surfaces

At least one surface must be created, namely that belonging to the main display image. This Surface is referred to as the Primary Surface. In order to draw onto this surface you can use windows GDI functions. Or if you wanted to draw a bitmap you could create another Surface place the bitmap into that surface and then blit it from that surface onto your primary surface. It is also possible to write to surface memory directly.

Complex Surfaces

A complex surface is a surface that has multiple buffers, where one buffer would represent the active display and the others would be hidden. This is especially useful for generating smooth animation because you can make all your changes to a scene hidden from view and then blit it all to the screen at once. A complex surface consists of a Front Buffer which is the buffer corresponding to the display, and one or more Back buffers. The Front and back buffers can be thought of as a FIFO stack, with the first buffer begin the front buffer. A member function is provided to flip buffers in which case the front buffer gets moved to the end of the stack and becomes a back buffer. And the next buffer on the stack becomes the Front buffer.

Color Keying

In addition to providing the basic drawing framework a surface also provides some color keying schemes in its Bliting functions. Color keying is a way of implementing transparency. DirectDraw supports two types of transparency: Source color keying, destination color keying. For source color keying, a surface can be defined to have a certain color or range of colors defined as transparent. When this surface is Blited onto another the colors within that range do not get copied thus giving transparency.

Destination color keying is a property that comes into play on the surface that is being blitted to. If enabled when a bitmap is being blitted to this surface only those color ranges specified will be overwritten by the incoming data. This might be useful if you had a surface with a window and wanted to show something moving behind the window. The destination color keys would be set to the colors of the glass. Anything blitted onto this picture would only show up if it were located on the glass pixels.

Overlays

Another capability is useing overlays. With overlays each surface has a Z-order associated with it. When two surfaces are blited onto a screen and they coincide with each other in location, the Z-order determines which one comes out on top.

f) Clippers

Clippers are another object created by the DirectDraw object. Clippers can be used to control where in a window Directdraw is allowed to draw. This is particularly useful in a windowing type environment because it easily allows you to make sure your application doesn't keep writing to portions of the screen that have been covered by by another window. The boundaries of a clipper are defined by giving the clipper a clip-list, which is a list of rectangles that the application is allowed to draw in. After creation a clipper is attached a surface by passing it to one of the member functions of that surface.

g) Pallettes

The remaining object type that can be created is the a Pallete object. This object is obviously responsible for the management of the colors for a particular surface. The pallete entries are specified in the standard RGB triplets, and each pallette object is associated with a surface in a similar way to how the clippers are. Using the pallete objects member function you can do all the neccassary manipulations or a palette.

f) Directly Drawing on the Surface

As mentioned before you can draw on a surface either by using the GDI commands of by bliting from surface to surface. However if neither of those suit your needs you also have the option of getting at the surface memory directly. By retrieving the memory pointer from a surface method you can then access the surface memory much in the same way you would access video memory directly in a Dos session. This allows you to implement your own drawing/bliting functions if you wish to. In order to ensure that the surface can only be acceseed by one object at a time whenever you wish to modify a surface you can Lock it.

4. Direct3D

Direct3D is a 3d library that works on top of DirectDraw - it renders its images to a DirectDraw surface. As of right now is is an add on package (as part of DirectX) but Microsoft supposedly plans on incorporating it into windows proper. As with DirectDraw, Direct3D takes maximum advantage of any hardware acceleration you might have. Transparently emulating that which is not supported in software.

a) Immediate Mode and Retained Mode

Direct3D has two operating modes, called Immediate and Retained Mode. Retained mode is a higher level mode that works on top of Immediate mode. It provides many of the higher level functionality for the 3d scene management. Immediate mode is a lower level mode, and would be more likely used if you wanted to create some of your own specialized tools and not rely on what Retained Mode does.

b) Rendering Pipeline

In order to get Intermediate mode to render a scene you send it an execute buffer. An Execute buffer is comprised of a list of vertices making up your scene and information on how to render the scene, including such things as camera location, how the polygons will move, etc.

Immediate mode takes this execute buffer and brings it through a rendering pipeline. This pipeline is broken down into three stages, transformation, lighting and rendering. Each of these modules is independent so if you wanted to write your own lighting model and replace the one that exists you are able to. Using retained mode uses and sets up the given pipeline automatically hiding the complexity from the user.

1) Transformation Model

This module does all the transformations neccassary on the polygons and camera found in the execute buffers. It also does clips all vertices not within the view of the camera.

2) Lighting Module

This module is responsible for figuring out all the lighting aspects of the scene. Calculating the correct shading from all the defined lights on the polygons. There are two default lighting modules, Ramp and RGB. The RGB model allows for colored lights, and although this is much more realistic its also much more computationally intensive. The Ramp module uses only lights that are a shade of grey.

3) Rendering Module

This module is naturally the one that takes the information from the above two modules and then creates the final scene with it. There are a couple different rendering modes that can be specified. Some typical different modes are a wireframe model, an unlit monocolor model, a monocolor model with lighting, and a Gouraud shaded model. ( A phong model shading is slated for future releases)

c) Retained Mode

1) The basics

Whereas DirectDraw had 4 main object types, Direct3D has a much larger range, Here is a list of them and their description. I will talk a bit more about some of the main ones but not all of them.

As with DirectDraw there is a Direct3D object. Unlike Directdraw however this Direct3d object does not represent the display screen, it is just used to create and destroy other Direct3D objects that are used.

There is also an object named the Direct3d device. This represents the objects rendering destination. You could have multiple Direct3D devices, perhaps one for an overhead view of a scene, one for a wireframe view of that scene, or a Gourad shaded view of the scene etc.

Objects (camera's, lights, polygons) in a scene are put together in a hierarchical model of frames. One frame can contain one or more objects. And each frame can have frames as children or parents. So if you had a scene with several objects, each object could be in its own frame. And each of those frames would be a child of the parent frame for that scene. Why might you want to do something like this? Say you wanted to model the earth the moon and the sun. You could put the sun in the main frame. Then create a second frame for the earth. This second frame would rotate around the sun. Now add a third frame of the moon. Place this frame inside the second frame and have it rotating around the earth. Now the moon rotates around the earth which is rotating around the sun. This makes for a easy way to one object in respect to a second object, without having a need to know the seconds objects movement relative to the overall scene. All objects can also have the typical transformations applied to them (scaleing, translating, rotation)

A list of the D3D retained mode objects:

Direct3DRMAnimation This object defines how a transformation will be modified, often in reference to a Direct3DRMFrame object; therefore, you can use it to animate the position, orientation, and scaling of Direct3DRMVisual, Direct3DRLight, and Direct3DRMViewport objects.

Direct3DRMAnimationSet This object allows Direct3DRMAnimation objects to be grouped together.

Direct3DRMDevice This object represents the visual display destination for the renderer.

Direct3DRMFace This object represents a single polygon in a mesh.

Direct3DRMFrame This object positions objects within a scene and defines the positions and orientations of visual objects.

Direct3DRMLight This object defines one of five types of lights that are used to illuminate the visual objects in a scene.

Direct3DRMMaterial This object defines how a surface reflects light.

Direct3DRMMesh This object consists of a set of polygonal faces. You can use this object to manipulate groups of faces and vertices.

Direct3DRMMeshBuilder This object allows you to work with individual vertices and faces in a mesh.

Direct3DRMObject This object is a base class used by all other Direct3D Retained-Mode objects; it has characteristics that are common to all objects.

Direct3DRMPickedArray This object identifies a visual object that corresponds to a given 2D point.

Direct3DRMShadow This object defines a shadow.

Direct3DRMTexture This object is a rectangular array of colored pixels.

Direct3DRMUserVisual This object is defined by an application to provide functionality not otherwise available in the system.

Direct3DRMViewport This object defines how the 3D scene is rendered into a 2D window.

Direct3DRMVisual This object is anything that can be rendered in a scene. Visual objects need not be visible; for example, a frame can be added as a visual object.

Direct3DRMWrap This object calculates texture coordinates for a face or mesh.

Creating polygon objects

The creation of a 3d polygon begins by creating a Meshbuilder object using the Direct3d object. The Meshbuilder takes a bunch of information about the polygon you are creating and puts it into a form that can be added to a frame. The Meshbuilder takes in three lists to define an object, a list of vertices, a list of faces, and a list of normals. The list of vertices is an array of floats that are grouped in x,y,z triples representing the location of each vertex. The list of normals is an array of floats again grouped in x,y,z triples that represent all the normals from each vertex. The faces list is an array of integers. Each face entry starts with a the number of vertexes in this face. For each vertex the index into the vertex and normal lists are paired together.

So a very simple example, for a one side of a cube we might have

D3DVECTOR vertex[] = { 
	0,0,0,  // lower left corner
	1,0,0,  // lower right corner
	1,1,0,  // upper right corner
	0,1,0,  // upper left corner
}

D3DVECTOR normal[] = {
	0,0,-1  // All vertices in this case have normals in same direction 
}

 int faces[] = {
	4, 0,0, 1,0, 2,0, 3,0  // vertex,normal pairs
}

A restriction is that all polygon faces must be convex and planar. Once you have created your faces you can modify their attributes either indivudually or as a whole object. A group of faces that have been put together are referred to as a mesh. There are a number of things that one can do to a face. Amung the things that can be assigned to a face is color, a texture or a material type.

Material

A material allows you to define how much light is reflected from a surface, including if it emits light. In Direct3d a material has two compontent its specular component and its emissive component. The specular component controls how much the face reflects light and the emmisive component controls how much light the object emmits.

Creating lights

There are 5 different types of light sources that one can add to a scene. Ambients, spotlights, point lights, directional lights and parallel point lights.

Ambient lights illuminate everything in a scene with a constant amount of light.

Spotlights illuminate a specific circle of lights.

Point lights are lights that have a position and radiate light in all direction from that position.

Directional lights have a direction but no position.

And lastly parralell point lights, which are like directional lights that have a position. (about the same as point lights but a bit faster)

Lights are created using the Direct3D object, when they are created you can set their intensity.

Animation

Direct3d supports a form of keyframe animation. Keyframe animation is a method whereby you take an object that you wish to move/rotate/scale and specify along a time interval where you want an object to be at a certain time. This location that you specify is called a keyframe. The computer will then interpolate the objects location at the times where the object is between two keyframes.

Creating textures

In mapping textures onto objects a 2D coordinate system is used. The coordinate system ranges from 0,0 in the upper left corner of a texture to 1,1 in the lower right corner. A texture object is loaded with a texture, and then a particular face or groups of faces can be assigned this texure. In order to put a texture onto an object, for a face of an object you specify where each vertex of that face is located in the texture coordinate system.

Some Problems & deficiencies

A number of articles pointed out some of the problems that they had with Direct3d (they compared it to what one can do with OpenGl). Here is a summary of some of the points.

Amount of layers has the potential to cause more significant performace hits for simple tasks. It is compared to Opengl, where Opengl is the lowest level of software above the hardware, whereas Direct3d has its HAL/HEL layers that stand between it and the video hardware.

Because of its dependence on windows the portability of Direct3d is limited to the windows-compatible market, whereas OpenGl has been created so as to be able to run on different opersating systems.

Poor documentation and having no complete published specification for Direct3D exist, poses a problem for hardware vendors have no way to ensure that their drivers conform fully to it.

John Carmack thinks poorly of D3D immediate mode. Opengl is presented by him as a better designed API, that is easier to use. His main gripe is that D3d is painfull to use, whereas Opengl is easy to use. For example you can make a simple opengl program with a single page of code, whereas you need to go through all sorts of hassle to do the same with D3d. A quote from John Carmack plan: "Direct-3D IM is a horribly broken API. It inflicts great pain and suffering on the programmers using it, without returning any significant advantages." He does beleive that retained mode has a value and suggests that replaceing Direct3d immediate mode with Opengl and porting the retained mode functionality on top of it would make a far better product.

References

http://www.sgi.com/Technology/openGL/direct-3d.html

DirectX documentation available at http://www.microsoft.com/msdownload/directx3.htm

Kolb, Jason. "Win32 Game developers Guide wiht DirectX 3"

[Return to CS563 '95 talks list]