Direct3D
Direct3D is part of DirectX (set of multimedia libraries) owned by Microsoft. It consists of an application programming interface (API) for 3D graphics. It is available for 32-bit and 64-bit Windows systems, as well as Xbox line consoles.
The objective of this API is to facilitate the handling and drawing of elementary graphic entities, such as lines, polygons and textures, in any application that displays 3D graphics, as well as to transparently perform geometric transformations on said entities. Direct3D also provides a transparent interface to graphics hardware acceleration.
It is mainly used in applications where performance is critical, such as video games, taking advantage of the graphics acceleration hardware available on the graphics card.
Direct3D's main competitor is OpenGL and its successor Vulkan, originally developed by Silicon Graphics Inc.
Architecture
Direct3D is one of the many components contained in the Windows DirectX API. It could be placed at the level of Windows GDI, presenting a level of abstraction between a 3D graphics application and the graphics card drivers (see attached graphic). With architecture based on Microsoft's COM, the greatest advantage that Direct3D presents over GDI is that Direct3D communicates directly with the display drivers, achieving better results in the representation of graphics on the screen than the former.
Direct3D is made up of two major APIs. The retained mode and the immediate mode. Immediate mode supports all 3D rendering primitives that graphics cards allow (lights, materials, transformations, depth control, and others). The retained mode, built on the previous one, presents a higher level abstraction offering pre-built graphics functionalities such as hierarchies or animations. Retained mode offers very little freedom to developers, with immediate mode being the most widely used.
Direct3D's immediate mode works primarily with so-called devices. They are in charge of rendering the scene. The device offers an interface that allows different rendering options. For example, a mono device allows rendering in black and white while an RGB device allows the use of colors. We can classify devices into three main classes:
- Abstraction layer device hardware (HAL, English hardware abstract layer): allows hardware acceleration. It's the fastest device.
- Reference Device: The previous installation of the Direct3D software development kit (SDK) is necessary to use this type of device. It allows software simulation of a rendering type and is very useful when the hardware still does not have new rendering features. A very specific case of the reference device is the null reference device whose function is to present the screen in black. It is used by default when you try to use a reference device and you do not find the SDK.
- Connection devices software: allows rasterization options by software. Previously the device had to be obtained through the method RegisterSoftwareDevice. This type of devices were not used until DirectX 9.0.
Each device has one or more exchange chains associated with it. These strings are made up of several surface buffers, considering a surface as a set of pixels plus all the attributes associated with each of them, such as depth, color, transparency (alpha channel), etc.
In addition, devices are also associated with a collection of specific resources or data needed to perform rendering. Each of these resources has the following attributes:
- Type: defines the type of resource in question: surface, volume, texture, cube texture, volume texture, surface texture, vertices buffer or index buffer.
- Store: describes where the resource is stored during execution. By default indicates that it is stored together with the device; managed that is saved in the memory of the system and copied on the device when it needs it; system memory which is found exclusively in the memory of the system, as well as virtual memory, ignoring the latter the restrictions of the graphic card.
- Format: describes the format in which the resource is stored in memory. The most important information is regarding the storage of pixels in memory. An example of format value is D3DFMT_R8G8B8 which indicates that a depth of 24-bit color (the eight more weight for the red, the eight in the middle for the green and the eight less weight for the blue).
- Using a list of flags indicates how the resource will be used. It also allows to distinguish static resources, those that once loaded only interest their value, from dynamic resources, whose value is modified repeatedly.
Graphic Pipeline
The attached figure shows a simplified version of the Direct3D graphics pipeline.
The different stages of the rendering process are:
- Input frame: provides input data (lines, points and triangles).
- Vertic hat: handles the operations of vertices (ilumination, textures, transformations). Try the vertices individually.
- Geometry Hat: performs operations with primitive entities (lines, triangles or vertices). From a primitive, the geometry hat can rule it out, or return one or more new primitives.
- Output flow: stores the output of the previous stage in memory. It is useful to refuel the pipe with already calculated data.
- Rasterizer: converts 3D image into pixels.
- Pixel hat: operations with pixels.
- Exiter: it is responsible for combining the output of the pixel shader with other types of data, such as depth patterns, to build the final result.
Direct3D allows reconfiguration of all stages, greatly increasing the flexibility of this pipeline.
Example
Example of how to draw a triangle in Direct3D:
/* Definition of a polygon of 3 vertices */ D3DLVERTEX v[3]; /* Establish a vertex */ v[0]=D3DLVERTEX(D3DVECTOR(0.f, 5.f, 10.f), 0x00FF0000, 0, 0, 0, 0); /* Establish a vertex */ v[1]=D3DLVERTEX(D3DVECTOR(0.f, 5.f, 10.f), 0x0000FF00, 0, 0, 0, 0); /* Establish a vertex */ v[2]=D3DLVERTEX(D3DVECTOR(0.f, 5.f, 10.f), 0x000000FF, 0, 0, 0, 0); /* Call to function to draw the triangle */ pDevice-negativeDrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_LVERTEX, v, 3, 0);
Display modes
Direct3D supports two display modes:
- Exclusive full screen: thanks to Direct3D having direct connection to the screen controller, the Direct3D device makes exclusive use of the screen. No other application can make use of the screen while in this mode.
- In window: the result is displayed within a Windows window. Direct3D has to collaborate with the GDI to finalize such representation. Although this mode is slower than the previous one, not blocking the screen and allowing the use of other applications, it is very comfortable in debugging mistakes.
History
In 1992, Servan Keondjian founded RenderMorphics, a company that developed a 3D graphics API called Reality Lab. This API was used in CAD programs and medical imaging rendering. In February 1995, Microsoft bought RenderMorphics, bringing Keondjian into the company to implement a graphics engine for Windows 95. The result was the first version of Direct3D, included in DirectX 2.0 and DirectX 3.0.
Initially, Direct3D was implemented on top of two APIs: the retained mode API and the immediate mode API. The retained mode was a graphical scenarios API based on Microsoft's Component Object Model (COM) which met with poor reception. Game developers requested more direct control over hardware activities than allowed in held mode. Only the game Lego Island was based on that API, so Microsoft abandoned the evolution of that mode after DirectX 3.0, and it has remained intact ever since.
The first version of Direct3D immediate mode consisted of an execution buffer-based programming model. Microsoft relied on such buffers to be directly supported by hardware vendors claiming that they would be stored in memory and parsed by hardware, in order to perform 3D rendering. These buffers turned out to be very difficult to program, slowing adoption of the new API and generating a wave of opinion calling for the adoption of OpenGL as the official one for 3D rendering at Microsoft. Microsoft decided to keep improving Direct3D, not only to be competitive with OpenGL, but also to compete more effectively against other proprietary APIs like 3dfx's Glide. A team in Redmond was tasked with taking over development of Direct3D's immediate mode, while the RenderMorphics team continued work on retained mode, abandoned not long after as stated.
Direct3D 5.0 introduced the DrawPrimitive set of primitives which eliminated the need for applications to build execution buffers.
Direct3D 6.0 introduced numerous features for hardware abstraction (such as multiple textures and pattern buffers), optimized the use of geometry pipelines for x87, SSE, and 3DNow!, and optional texture management to simplify programming.
Direct3D 7.0 introduced the DDS texture format and support for hardware acceleration of transformations and lights. It also added the ability to store vertex buffers in hardware memory. Vertex hardware buffers were the first substantial improvement over OpenGL in DirectX history. Support for multiple textures was also increased. Although Direct3D 7.0 was very powerful, it was so complicated to program that it required a new programming model to showcase the shading capabilities the hardware provided.
Direct3D 8.0 introduced programmability in the form of vertex and pixel shaders, allowing developers to write code without worrying about hardware. Programming simple shaders equated to simple tasks, and more complex shaders were used for more complex tasks. The display driver compiled these shaders into instructions understandable by the hardware. Direct3D 8.0 also removed the DirectDraw API, absorbing it. Fixed many usability issues. Also, very powerful features like fog, topological mapping and texture mapping were included.
Direct3D 9.0 added a new version of High Level Shading Language (HLSL), HDR support, multi-object rendering, and vertex buffer indexing.
Direct3D 10 achieves a considerable increase in performance by eliminating the so-called object overhead, which consists of making calls between the API and the driver using the CPU. These calls began to produce a bottleneck due to the increase in the complexity of the scenes and measures such as shader status blocks have been included to be able to reference groups of shader variables through a single ID instead of sending a single ID. to one among other things. Direct3D 10 also incorporates support for the model 4 shader, which means that geometry shaders can be used.
It also incorporates a new Stream Out function; This new feature allows buffering output information from geometry shaders allowing multi-pass operations on the geometry shader, which could be translated for the user into full physics simulations on the GPU and it is now possible to feed back the pipeline shader from the vertex shader.
Virtualization of the graphics memory has been included and the programmer has more control over what kind of memory he wants to allocate his resources. Through the geometry shaders it is possible to generate geometry on the GPU itself, for example to convert a sequence of points into camera-oriented polygons for a particle effect, previously it was done on the processor and now it is also calculated by the GPU.
Another important point is the removal of the fixed pipeline from DirectX 10, which is a serious problem for novice programmers, and a considerable increase in the complexity of the API, giving as an example the need to create a specialized object called input layout for each combination of vertex format and vertex shader to be used (which was automatic in Direct3D 9.0), which is a small performance gain at the cost of requiring more laborious use of the API. The main problem with DirectX 10 is that it only worked with the Windows Vista operating system, while DirectX 9.0 worked with the entire Windows family starting with Windows 98, due to this, it is rumored that Microsoft plans to either support it in XP or release a special version of DirectX 9 that implements some features. The DirectX 10 SDK has been available since February 2007.