2
\$\begingroup\$

Almost all the tutorials and books use a class wrapper for Direct3D. But I haven't found any scenario in which using more than one instance of Direct3D system (the "device" and state, et cetera) is required.

Is there any advantage to using a class instead of a namespace? Is there ever a case where using more than one is required?

| improve this question | | | | |
\$\endgroup\$
1
\$\begingroup\$

Certainly you could just wrap your D3D usage up into a namespace containing free functions and that would be fine. It's not wrong, per se, but it does have limitations. D3D is inherently object-based, and those objects store state. By hiding it behind a free-function façade you'd actually remove flexibility (you could create more D3D devices but you can't create more instances of your free-function façade).

Plus, most abstractions over D3D exist to simplify the interface, and that usually involves storing some state yourself. Doing so in a free-function API is similarly limiting (you store it in private global variables in your translation units, and you can never have more than one) or cumbersome (you implement what is essentially C-style object-orientation, passing the state object to each of your free functions, which is rather silly in C++ where you have better mechanisms to do this).

It is thus generally better to abstract D3D via wrapper classes and objects rather than namespaces, unless your needs are exceedingly trivial. This also offers the following benefits:

  • If you want, and are comfortable with both D3D and OpenGL, you can design the wrapper API such that the implementation could be swapped out, providing you both a D3D and OpenGL renderer. This is a fairly popular rationale, although it is not always done well or really necessary(*). In C++ specifically, this helps force implementation hiding which cleans the surface of your API (clients don't have to pull in D3D or GL headers themselves).

  • You can potentially mock the abstraction's implementation for testing purposes. It's usually rather difficult to unit test rendering, but the ability to build automated, not-strictly-unit tests to avoid bug regressions is useful.

  • You don't unnecessarily pessimize your system into assuming only a single instance of this API can exist when you really don't have a rationale to impose that requirement.

  • Free-function APIs can't be passed to functions as arguments; objects can. This is a huge win, in my experience, because it forces you to have explicitly-specified dependencies in your APIs. It's obvious from some other API if it depends on the renderer because it will take instances of the renderer in its parameters (or something). This helps self-document your code, and it also helps you notice when you have a problem of overly-promiscuous dependencies (the design problem where you find that you have to "pass the renderer to everything").

(*) With modern OpenGL, I'd argue that new projects should just use OpenGL and abandon D3D. That was before the announcement of D3D12, and once more concrete information about D3D12 is available I might revise that argument.

| improve this answer | | | | |
\$\endgroup\$
1
\$\begingroup\$

Game engines often provide an interface for their renderer. This hides specific implementations for Direct3D/OpenGL/GCM render code. The main advantage to this is that you can have classes/wrappers for each graphics API but you only ever use the same renderer interface regardless of the target platform.

Classes are generally used for their polymorphism functionality where the interface class is an abstract class and is inherited by each graphics API class.

| improve this answer | | | | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.