Comparison of OpenGL and Direct3D
From Wikipedia, the free encyclopedia
Direct3D is a proprietary API designed by Microsoft Corporation for hardware 3D acceleration on the Windows platform. OpenGL is an open standard API that provides a number of functions for the rendering of 2D and 3D graphics. An implementation is available on most modern operating systems. OpenGL and Direct3D are both implemented in the display driver.
Following is a comparison of the two APIs, structured around various considerations mostly relevant to game development.
Contents |
[edit] Portability
Direct3D is only officially implemented on Microsoft's Windows family of operating systems, including the embedded versions used in the Xbox family of video game consoles. Several partially functional ports of the Direct3D API have been made by Wine, a project to port common Windows APIs to Linux, but this work is difficult due to the dependency of DirectX as a whole on many other components of Windows. Microsoft once started development on a port to Apple Computer's Mac OS, but later abandoned this project.
OpenGL, on the other hand, has implementations available across a wide variety of platforms including Microsoft Windows, UNIX-based systems such as Linux and Mac OS X, and the PlayStation 3 and Wii game consoles. With the exception of Windows and the Xbox, all operating systems that allow for hardware-accelerated 3D graphics have chosen OpenGL as their primary graphics API.
Microsoft's OpenGL driver, bundled with Windows versions before Windows Vista, provides no hardware acceleration or direct support for extensions. These versions of Windows thus require that users install installable client drivers (ICD) developed by GPU manufacturers for OpenGL hardware support. These ICDs are, in virtually all cases, bundled with the standard driver download package from the hardware vendor (IHV), so simply installing recent graphics drivers is sufficient to provide hardware OpenGL support.
Windows Vista will include three OpenGL implementations. The first maps OpenGL calls to Direct3D ones. This allows for hardware acceleration through OpenGL from a standard install, but this implementation only implements OpenGL 1.4, and features of versions after this must be accessed as extensions. The second uses legacy Installable Client Drivers (ICD) available for Windows XP. This will disable the Aero desktop but otherwise functions as expected. The third is a full implementation that will work alongside the desktop and still allow access to the GPU.
[edit] Ease of use
[edit] Direct3D
In its earliest incarnations, Direct3D was known to be rather clumsy to use — to perform a state change, for instance, it required a number of complex operations. For example, to enable alpha blending, one had to create an 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, OpenGL only requires a single "glEnable(GL_BLEND);" call. The Direct3D model frustrated many programmers. The most famous complaint was probably made by high-profile game developer John Carmack in the .plan file in which he urged Microsoft to abandon Direct3D in favor of OpenGL.
Version 5 (the second version, named to reflect its release as part of DirectX 5) abandoned execute buffers and improved the API significantly, but it was still considered cumbersome and didn't provide much in terms of texture management or vertex array management. Direct3D 7 provided texture management, and Direct3D 8, among other things, provided vertex array management. Direct3D's API is currently viewed by many as well written, but still follows a different paradigm compared to OpenGL.
Direct3D is built upon Microsoft's COM. The use of this framework means that C++ code is a little unusual. Functions for acquiring values don't return the value in the return argument for the function because all COM functions return an "HRESULT" that tells whether the function executed correctly or not. The plus side of using COM is that the same API can be used in any COM-aware language, notably C# and Visual Basic.NET.
[edit] OpenGL
OpenGL is a specification based on the C programming language. It is built around the concept of a finite state machine, though more recent OpenGL versions have transformed it into much more of an object based system. Though the specification is built on C, it can be implemented in other languages as well.
[edit] Comparison
In general, Direct3D is designed to be a 3D hardware interface. The feature set of Direct3D is derived from the feature set of what hardware provides. OpenGL, on the other hand, is designed to be a 3D rendering system that may be hardware accelerated. These two APIs are fundamentally designed under two separate modes of thought. The fact that the two APIs have become so similar in functionality shows how well hardware is converging into user functionality.
Even so, there are functional differences in how the two APIs work. Direct3D expects the application to manage hardware resources; OpenGL makes the implementation do it. This makes it much easier for the user in terms of writing a valid application. At the same time, because OpenGL hides hardware details (including whether hardware is even being used), the user is unable to query the status of various hardware resources. So the user must trust that the implementation is using hardware resources "optimally".
Until recently, another functional difference between the APIs was the way they handled rendering to textures: the Direct3D method (SetRenderTarget()) is convenient, while previous versions of OpenGL required the manipulation of P-buffers (pixel buffers). This was cumbersome and risky: if the programmer's codepath was different from that anticipated by the driver manufacturer, the code would have fallen back to software rendering, causing a substantial performance drop. According to a Gamasutra article (registration required), the aforementioned John Carmack considered switching from OpenGL to Direct3D because of the contrived use of P-buffers. However, widespread support for the "frame buffer objects" extension, which provides an OpenGL equivalent of the Direct3D method, has successfully addressed this shortcoming.
Outside of a few minor functional differences, typically with regard to rendering to textures (the "framebuffer objects" extension did not cover everything, but the ARB is working to address this), the two APIs provide nearly the same level of functionality.
[edit] Performance
Shortly after the establishment of both Direct3D and OpenGL as viable graphics libraries, Microsoft and SGI engaged in what has been called the "API Wars". Much of the argument revolved around which API offered superior performance. This question was relevant due to the very high cost of graphics accelerators during this time, which meant the consumer market was using software renderers implemented by Microsoft for both Direct3D and OpenGL.
[edit] Early debate
Microsoft had marketed Direct3D as faster based on in-house performance comparisons of these two software libraries. The performance deficit was blamed on the rigorous specification and conformance required of OpenGL. This perception was changed at the 1996 SIGGRAPH (Special Interest Group on Computer Graphics) conference. At that time, SGI challenged Microsoft with their own optimized Windows software implementation of OpenGL called CosmoGL which in various demos matched or exceeded the performance of Direct3D. For SGI, this was a critical milestone as it showed that OpenGL's poor software rendering performance was due to Microsoft's reference OpenGL implementation, and not to design flaws in OpenGL itself.
On the other hand, software rendering by the 3D API was largely irrelevant for both Direct3D and OpenGL applications. Not many DirectX applications used Direct3D's software rendering, preferring to perform their own software rendering using DirectDraw's facilities to access the display hardware. As for OpenGL applications, hardware support was expected, and the hardware was so much faster that software fallback by the OpenGL application constituted a rude surprise to the OpenGL developer.
In any case, by the time SGI had demonstrated that OpenGL software rendering performance could be competitive with that of Direct3D, software rendering was fast becoming irrelevant due to the widespread availability of inexpensive 3D graphics hardware. By 1998, even the much-maligned S3 Virge was substantially faster than the fastest Pentium II running Direct3D's MMX rasterizer.
[edit] Mode switching
A more substantive and modern performance difference arises because of the structure of the hardware drivers provided by hardware developers. Under DirectX, IHV drivers are kernel-mode drivers installed into the operating system. The user-mode portion of the API is handled by the DirectX runtime provided by Microsoft. Under OpenGL however, the IHV driver is broken into two parts: a user-mode portion that implements the OpenGL API, and a kernel-mode driver that is called by the user-mode portion.
The reason this is an issue is because calling kernel-mode operations from user-mode requires a CPU switch to kernel mode. This is a slow operation, taking on the order of microseconds to complete. During this time, the CPU is unable to perform any operations. As such, a performance optimization would be to minimize the number of times this switching operation must be performed. For example, if the GPU's command buffer is full of rendering data, the API could simply store the requested rendering call in a temporary buffer and, when the command buffer is close to being empty, it can perform a switch to kernel-mode and add a number of stored commands all at once. This is known as marshalling.
Because Direct3D IHV drivers are kernel-mode, and the user-mode code is out of the IHV's hand, there is no chance for such optimizations to occur. Because the Direct3D runtime, the user-mode portion that implements the API, cannot have explicit knowledge of the driver's inner workings, it cannot effectively support marshalling. This means that every D3D call that sends commands to the hardware must perform a kernel-mode switch. This has led to a number of behaviors with regard to using D3D, the most important being the need for submitting large batches of triangles in one function call [1].
Since OpenGL's IHV drivers have a user-mode component to them, IHVs have the ability to implement marshalling, thus improving performance. There is still kernel-mode switching, but the theoretical maximum number of switches under OpenGL implementations is simply equal to the Direct3D standard behavior.
Direct3D 10, the release included with Windows Vista, allows portions of drivers to run in user-mode, thus allowing IHVs to implement marshalling, thus bringing the two back into relative performance parity. The Mac OS X OpenGL system implements a very similar system, where IHVs implement a simpler version of the OpenGL API (with both user and kernel mode components), and Apple's additions to the runtime provide the direct interface to the user code, as well as some basic work to make IHVs' jobs easier.
[edit] Structure
OpenGL, originally designed for then-powerful SGI workstations, includes a number of features that are only useful for workstation applications. The API as a whole contains about 250 calls, but only a subset of perhaps 100 are useful for game development. However, no official gaming-specific subset was ever defined. MiniGL, released by 3Dfx as a stopgap measure to support glQuake, might have served as a starting point, but additional features like stencil were soon adopted by games, and support for the entire OpenGL standard continued. Today, workstations and consumer machines use the same architectures and operating systems, and so modern incarnations of the OpenGL standard still include these features, although only special workstation-class video cards accelerate them.
OpenGL is designed as a feature rich API regardless of hardware support. The specification often drives the implementation of hardware acceleration for these features. For example, when the GeForce 256 graphics card came out in 1999, games like Quake III Arena could already benefit from its acceleration of transform and lighting, because the API was designed to provide this feature. Meanwhile, Direct3D developers had to wait for the next version of Direct3D to be released before they could take advantage of hardware-based Transform and Lighting.
The advantage of OpenGL's inclusive, extensible approach is limited in practice, however. Due to the market dominance Direct3D has achieved, games nowadays have rarely implemented features until Direct3D has supported them.[citation needed] Also, graphics cards vendors have been reluctant to implement features that current or upcoming versions of Direct3D will not support.[citation needed]
[edit] Extensions
The OpenGL extension mechanism is probably the most heavily disputed difference between the two APIs. OpenGL includes a mechanism where any driver can advertise its own extensions to the API, thus introducing new functionality such as blend modes, new ways of transferring data to the GPU, or different texture wrapping parameters. This allows new functionality to be exposed quickly, but can lead to confusion if different vendors implement similar extensions with different APIs. Many of these extensions are periodically standardized by the OpenGL Architecture Review Board, and some are made a core part of future OpenGL revisions.
On the other hand, Direct3D is specified by one vendor (Microsoft) only, leading to a more consistent API, but denying access to vendor-specific features. NVIDIA's UltraShadow[2] technology, for instance, is not available in the stock Direct3D APIs at the time of writing. It should be noted that Direct3D does support texture format extensions (via FourCC codes). These were once little-known and rarely used, but are now used for DXT texture compression.
When graphics cards added support for pixel shaders (known on OpenGL as "fragment programs"), Direct3D provided a single "Pixel Shader 1.1" (PS1.1) standard which the GeForce 3 and up, and Radeon 8500 and up, claimed compatibility with. Under OpenGL the same functionality was accessed through a variety of custom extensions.
In theory, the Microsoft approach allows a single code path to support both brands of card, whereas under OpenGL the programmer had to write two separate systems. In reality, though, because of the limits on pixel processing of those early cards, Pixel Shader 1.1 was nothing more than a pseudo-assembly language version of the NVIDIA-specific OpenGL extensions. For the most part, the only cards that claimed PS 1.1 functionality were NVIDIA cards, and that is because they were built for it natively. When the Radeon 8500 was released, Microsoft released an update to Direct3D that included Pixel Shader 1.4, which was nothing more than a pseudo-assembly language version of the ATi-specific OpenGL extensions. The only cards that claimed PS 1.4 support were ATi cards because they were designed with the precise hardware necessary to make that functionality happen. In terms of early Pixel shaders, D3D's attempt at a single code path fared no better than the OpenGL mechanism.
Fortunately, this situation only existed for a short time under both APIs. Second-generation pixel shading cards were much more similar in functionality, with each architecture evolving towards the same kind of pixel processing conclusion. As such, Pixel Shader 2.0 allowed a unified code path under Direct3D. Around the same time OpenGL introduced its own ARB-approved vertex and pixel shader extensions (GL_ARB_vertex_program and GL_ARB_fragment_program), and both sets of cards supported this standard as well.
[edit] Users
[edit] Professional graphics
OpenGL has always seen more use in the professional graphics market than DirectX, while DirectX is used mostly for computer games. (The term professional is used here to refer to the professional production of graphics, such as in computer animated films, as opposed to games where the graphics produced by the game are for the user's personal, rather than professional, use.)
At one point many professional graphics cards only supported OpenGL, however, nowadays all the major professional card manufacturers (NVIDIA, ATI Technologies and Matrox) support both OpenGL and Direct3D.
The reasons for OpenGL's advantage in the professional market is partly historical. Many professional graphics applications (for example, Softimage|3D, Alias PowerAnimator) were originally written in IRIS GL for high-end SGI workstations, then ported to OpenGL. Even long after SGI ceased to dominate the market, many professional graphics cards only supported OpenGL.
The many extra features of OpenGL that were previously mentioned as not useful for game development are also a factor in OpenGL's professional market advantage, because many of them are useful in professional applications.
The other reason for OpenGL's advantage is marketing and design. DirectX is a set of APIs that were not marketed towards professional graphics applications. Indeed, they were not even designed with those applications in mind. DirectX was an API designed for low-level, high-performance hardware access for the purpose of game development. OpenGL is a much more general purpose 3D API, so it provides features that aren't necessarily exclusive towards any particular kind of user.
[edit] Gaming
The principal reason for Direct3D's dominance in the gaming industry is historical. In the earliest days of hardware-accelerated 3D graphics, 3dfx was the dominant force, and their Glide API was used by far more games than D3D or OpenGL. Glide was much more lower-level than D3D or OpenGL, and thus its performance was greater than either. Performance is the most important facet for game developers, so the less easy to use Glide API was preferred over the other two. This helped catapult 3DFx into the forefront of 3D hardware in those days.
As hardware got faster, however, the performance advantages of Glide began to be outweighted by the ease of use. Also, because Glide was restricted to 3dfx hardware, and 3dfx was not being as smart about hardware design as its main competitor NVIDIA, a hardware neutral API was needed. The very earliest versions of Direct3D (part of DirectX version 3) was not the simplest API to use. The next Direct3D version (in DirectX 5) was much more lucid. As interest in making Glide only games or games with multiple renderers dropped, there was a choice to make: OpenGL or Direct3D 5.
Making games that use OpenGL while using the non-Direct3D portion of the DirectX API is no more difficult than making a game using all of the DirectX API. The decision to use Direct3D over OpenGL was made from simple pragmatism: in those days, OpenGL implementations were difficult to work with. Writing an OpenGL implementation requires implementing every feature of OpenGL, even if the hardware doesn't support it. If the hardware can't do it, you have to write a software rasterizer that can handle that feature. This feature is very useful if performance is not a primary goal, such as in professional graphics applications or off-line renderers; it guarantees the existence of functionality. However, in a game situation, where a loss of performance can destroy the feeling of the game, it is more desirable to know that the functionality doesn't exist and to simply avoid using it.
Different GL implementations would, when activating some feature, spontaneously go into a slow software renderer. Because OpenGL has no mechanism for telling the user whether or not a feature, or combination of features, will kick the renderer into software mode, users of OpenGL had to carefully test everything that they did on every piece of hardware that they were going to support.
Adding to that is the fact that an OpenGL implementation is a complex piece of code. It is much more than a simple graphics driver that is just a low-level interface to hardware registers. It needs to keep track of a great deal of state information, and that requires a lot of code. In the early days of OpenGL implementations, the implementations themselves were quite buggy. Indeed, a perfectly functioning game could break when downloading a new graphics driver; this is a complication that many game developers didn't want to have to deal with.
Direct3D didn't have these problems. A Direct3D driver is (or, was in those days) just a low-level interface to hardware registers. Though this led to a performance issue as noted above, it also allows D3D drivers to be clean, simple and stable, compared to their OpenGL counterparts. And D3D has a query mechanism that tells the application whether or not a particular feature is available in hardware. So game developers chose to use it because it did what they needed.
While IHVs did resolve the OpenGL bug issue to a significant degree, the issue of hardware specificity was never addressed. Even so, the need for it has decreased as more and more OpenGL specified functionality becomes implemented in hardware. Later versions of OpenGL would rarely add functionality that wasn't actually widely available in hardware. As such, the issue has, for the most part, become a non-issue.
[edit] See also
[edit] External links
- GameDev: Direct3D vs. OpenGL
- Paul Hsieh: Direct3D vs. OpenGL
- XMission.com: Direct3D vs. OpenGL
- OpenGL to be fully supported by Vista
- MSDN blog on Vista implementation of OpenGL
Categories: NPOV disputes | Articles lacking sources from October 2006 | All articles lacking sources | Articles with unsourced statements since March 2007 | All articles with unsourced statements | 3D computer graphics | Debates | Computing comparisons | Application programming interfaces | Microsoft APIs