Topic : Direct3D vs. OpenGL
Author : Promit Roy
Page : 1 Next >>
Go to page :


Direct3D vs. OpenGL: Which API to Use When, Where, and Why
by Promit Roy


I have tried to keep this article as devoid of error and opinion as possible. All of my opinions are marked as such, and all errors are purely accidental. Please excuse any minor errors that I may make. I am of the opinion that everything is correct; all facts have been confirmed by third party sources. Please also understand that this article is written for beginners who are unsure how to start graphics programming, and that while I have tried my best to keep this article neutral, this issue is very debatable.

For many years now, the question "Which should I use: Direct3D or OpenGL?" has elicited heated arguments. Most of the things said do very little to help you decide which API you should use. There are fanatics on both sides; some people will tell you that OpenGL is the only way to go, and others will swear by Direct3D. Others will talk about how they have used both, and that you should do the same and decide which you like better, but for someone starting out, that's not much help either. The point is, it can be a tough decision to make, and I am writing this article to help you do it. My specialty is primarily in Win32 programming, so that will be my focus. No need to fear though, I discuss other platforms as well.

In this article, I concentrate on only two API's: OpenGL (version 1.3) and Direct3D (version 8.1). I don't have enough experience with any other API to discuss it in detail, but I'll at least comment on Glide later. I'll attempt to present you with the hard facts about each API, their structure, and what kind of code you can expect. I do not, however, actually include any code here. You can find that easily enough in other areas on GameDev.net. There really are no prerequisites to understanding this article (except possibly knowing English). Thus far, I've assumed that you know what an API is, and what purpose APIs serve. In case you don't know this, API stands for Application Programming Interface, and it's essentially a set of functions that allow you to perform some specific task. For our purposes, that task is interfacing with the graphics hardware.

The Hard Facts: Direct3D8
For a long time, Direct3D was considered to be pretty bad compared to OpenGL. Recent advancements in the API, however, have made it very powerful and stable. Many people now believe that Direct3D is the standard for graphics on Windows platforms, not OpenGL. Microsoft works very closely with graphics hardware companies to make sure that any new features that they introduce will be supported in Direct3D. Often, Direct3D supports features before cards do.

History
Well after the debut of Windows 95, the overwhelming majority of games were still being made for DOS. Microsoft wanted game developers to move away from DOS and make games for Windows, in turn making Windows a more popular platform. Windows, however, did not provide a good gaming platform. The many layers of abstraction meant that access to video and sound hardware was very limited and slow. They decided to create an API that would allow game developers more direct access to the hardware to allow games on Windows to run at acceptable speeds.

Rather than develop their own 3D API from scratch, they noticed a very promising 3D API being developed by a company called RenderMorphics. It was a small project the company had written and was showing at a trade show when Microsoft discovered it. (As an interesting side note, the API was submitted by the creators as a college project and flunked for having deviated from the assignment somewhat.) They integrated it into their own sort of mini-Graphics Library known as the Game SDK. They expected it to be the perfect solution for game developers. They were wrong.

What later became known as DirectX 1.0 ended up not being very widely accepted. It was buggy, slow, badly structured, and overly complex.

Of course, Microsoft wasn't about to just give up. They kept working at it, asking the community for ways to improve it. The first truly viable version of DirectX was DirectX 3.0. A few years later, they released DirectX 5 (skipping 4 entirely), which was the first truly useful version. Incremental improvements were made with version 6. Then came DirectX 7.0.

DirectX 7 was the first one to actually be embraced by game developers. It worked well, making game programming reasonably easy, and a lot of people liked the interface. Now here's where the big one hits. Up to and including DirectX 7, DirectX included two components for graphics: DirectDraw and Direct3D. DirectDraw was pretty much 2D only, but quite powerful. Direct3D was built on top of DirectDraw.

With DirectX8, the deprecated DirectDraw interface, which hadn't changed much for several versions, finally got thrown out as a separate component. Although this was a controversial action, Microsoft wanted to focus on the 3D aspects of the API. Most things that are done in 2D can be duplicated using 3D techniques, with the advantage of being faster due to the use of hardware acceleration. In addition, the older DirectDraw interfaces would still be available due to the nature of COM. And that's pretty much where we are today.

Structure
The structure of Direct3D, and DirectX in general, is hugely different from OpenGL. As time goes on however, DirectX is slowly becoming more and more like OpenGL. I won't show all the class diagrams here, but basically, DirectX is based on the COM object model. What this means is that you create pointers to classes and use those, rather than just calling functions that don't clearly show associations.

A COM object is analogous to a C++ class. You can even derive from the DirectX classes, although doing so is one of the most profoundly stupid things anyone could ever do. A typical DirectX app will have a few structures such as LPDIRECT3DDEVICE8. Using the - notation, you can call members of these classes. Unfortunately, writing DirectX applications in pure C is not the most fun thing to do. Because of the way COM works, you must explicitly dereference a VTable, as well as pass a pointer to the interface, both of which are done implicitly in C++. What this means is that instead of writing D3DDevice->DoSomething(Params), you have to write D3DDevice-lpVtbl-DoSomething(D3DDevice, Params). Not pretty. Microsoft realized this and made some macros to ease the paid, but the equivalent macros are often just as bad (for example, IDirect3DDevice8_DoSomething( D3DDevice, Params).

DirectX apps typically make heavy use of C structs, and often your app will be build around nice custom classes. The rendering is done in between two calls: Direct3DDevice8-BeginScene() and Direct3DDevice8-EndScene(), a format which was "borrowed" from OpenGL. When you shut down your program, you follow a certain pattern: you call X->Release, where X is a COM object, to free resources allocated for the object.

DirectX also provides something called the Direct3DX function library, introduced with DirectX 7.0. This is a static library that provides gobs of useful functions that help make your life easier. There is one catch, though: many of the things that have been added are C++ specific. D3DXMATRIX is derived from D3DMATRIX, for example, and many of the operators are overloaded as well. Of course, if you're using C++ anyway, this really isn't a problem. The Direct3DX library provides a lot of useful functions which have been very heavily optimized. Amongst other things, it will load and save meshes, do matrix and vector math, provide over a hundred C++ enhanced data structures, and manage things such as 3D fonts.

The last thing to be mentioned is the DirectX Application Framework, now known as the DirectX Common Files. As I mentioned earlier, even drawing a simple triangle takes a lot of code. To help reduce the amount of code required to perform even simple operations, Microsoft wrote a set of classes that do most of it for you. All the initialization is hidden from you. Even somewhat complicated operations such as listing all the capabilities of the graphics card are handled by the Common Files. The source is available to, so that you can edit it as you like. Of course, because they are built around classes, you need to be using C++ to take advantage of them. I recommend that you use the Common Files, but be aware of how they work. A good way to do this is to use the DirectX AppWizard to create a small D3D project and step through it, watching exactly how the different functions/classes interact.

Looking at the Header
If you've never used COM, the contents of the d3d8.h header may seem foreign to you. Most reactions lie along the lines of "Huh?" or "Wha?!". I spent a long time looking through objbase.h to figure it out. (objbase.h is the header for COM objects) Abstract classes are declared, along with

Page : 1 Next >>