| • Science | • People | • Locations | • Timeline |
Prior to version 8, Direct3D was known to be rather clumsy to use -- to do a state change, for instance, it required a number of complex operations. For example, to enable or disable alpha blending, one had to create a so-called execute buffer, lock it, fill it with the correct opcodes (along with a structure header telling how many opcodes the buffer contained and a special "exit" opcode), unlock it and finally send it to the driver for execution. In contrast, an OpenGL program would do a single "glEnable(GL_BLEND);" call. This model was rather frustrating for many programmers; the most famous example probably comes from John Carmack's .plan where he urged Microsoft to drop Direct3D altogether in favour of OpenGL.
However, with Direct3D version 8, many changes were made, and Direct3D can probably not be called a clumsy API anymore. However, Direct3D and OpenGL still follow different paradigms -- Direct3D is based on Microsoft's COM technology and thus is in its heart object oriented (so every texture is an object, for instance). OpenGL does not have such a paradigm, but instead is known as a state machine accessed through simple C functions. Which one is ultimately "better" depends on a programmer's preferences. The OpenGL state machine may be wrapped with an object oriented programming interface as part of the game engine.
Direct3D tends to be closer to the hardware than OpenGL is. For instance, if a program is minimized and then restored, Direct3D users will get what is known as a lost device, meaning the program has to re-upload all textures, set all vertex shader constants etc. OpenGL does this transparently for the programmer, of course at the cost of less control. A Direct3D game could for instance pause the game while the upload is happening, which would be harder for an OpenGL game.
A widely preferred way of using OpenGL is what GL calls "immediate mode", which allows the programmer to enter vertices (or vertex attributes such as texture-coordinates or colors) to the current vertex-buffer one-by-one manner (e.g. "glVertex3f( 1.0f, 2.0f, 3.0f);"), on the obvious expense of speed. This is a very convenient way of drawing simple things, but in practice it makes the rendering notably slower. Direct3D 8.0, on the other hand, only allowed the programmer to render thru self-managed vertex-buffers, thus removing the ease of "quickly rendering simple objects on the screen". Direct3D 9.0 introduced a function called DrawPrimitveUP (UP being "user pointer"), which allows the programmer to give the function the pointer to his own vertex-data and render it without needing to create his own vertex-buffer, of course on the expense of additional overhead.
In the early days, Microsoft often claimed OpenGL was too slow to be used for games, but there seems to be very little actual data on this. It is true that Direct3D was probably better suited to software rendering (i.e. on machines without hardware acceleration ), but there are few studies examining performance in real-world situations between the two. An nVidia presentation on batching claims OpenGL has lower call overhead per batch (1.7-2.3x faster than D3D) in their driver[1].
Many games today are CPU-bound even on mid-end graphics hardware; for those, the API speed will of course not matter.
The OpenGL extension mechanism is probably what is most heavily disputed. OpenGL has a mechanism where any driver can advertise its own extensions to the graphics API, thus introducing new functionality in some way (such as blend modes, new ways of transferring data to the GPU or different texture wrapping parameters). This leads to new functionality being exposed quickly, but can often lead to confusion as different vendors implement similar extensions with different APIs, until they are standardized by the OpenGL ARB and possibly included in future OpenGL revisions (OpenGL extensions are specified in terms of edits from the official specification , so they are usually quite simple to incorporate into the main standard). On the other hand, Direct3D is specified by one vendor ( Microsoft) only, which leads to a more consistent API, but sometimes missing vendor-specific features. nVidia's UltraShadow [2] technology, for instance, is not yet available in the stock Direct3D APIs at the time of writing.
An example is what Microsoft calls pixel shaders (and OpenGL "fragment programs"); for Direct3D you have a single "pixel shader 1.1" (PS1.1) standard working on both GeForce 3 and up, and Radeon 8500 and up. In OpenGL the coder would have to write different code paths for the nVidia and ATI TechnologiesATI Technologies Inc. where ATI is an acronym for Array Technology Industry is a Canadian manufacturer of graphics cards, graphics chips and graphics processing units for personal computers. Founded in 1985, their main headquarters is located in Markham, cards. OpenGL enthusiasts claim the cards are actually rather different in reality, and thus should be addressed in different ways -- for instance, PS1.3 and PS1.4 are more or less tailored to how the Radeon 8500 card works internally (and often, utilizing the extra power in them over PS1.1 will lead to a more efficient application on a Radeon 8500) and thus won't work on GF3, so a D3D programmer would probably be writing separate code paths for PS1.1 and PS1.4 after all (all PS2.0 cards are required to be backwards compatible with all the earlier pixel shader revisions, though, so an application originally written with the Radeon 8500 only in mind will run on for instance a GeForce FX, supporting PS2.0).
It should be noted that Direct3D also supports extensions (via so-called FOURCC codes), but they are little known and rarely used. Also, OpenGL now has ARB-approved extensions for both vertex and pixel shader extensions (GL_ARB_vertex_program and GL_ARB_fragment_program), but the latter is PS2.0-equivalent only; a unified PS1.1-like standard for OpenGL still does not exist (and probably never will). The significance of this will most likely decrease as PS2.0 and higher becomes the norm for graphics cards.