Quantcast
Channel: GameDev.net
Viewing all articles
Browse latest Browse all 17625

Which is Most Verbose: OpenGL or DirectX?

$
0
0
Direct3D and OpenGL are competing application programming interfaces (APIs) which can be used in applications to render 2D and 3D computer graphics. They are the two most popular graphics APIs utilized in game development.

Probably the most recurrent debate between the two APIs has to do with their relative performances, which concern more the end user. In this post we will discuss their verbosity, which impacts more the developers using them.

Comparing the DirectX and OpenGL


To compare the verbosity of the two APIs, let’s analyse with CppDepend the Irrlicht 3D engine source code which implements both DirectX and OpenGL renders.

The Irrlicht Engine is an open-source high-performance realtime 3D engine written in C++. It is completely cross-platform, using D3D, OpenGL and its own software renderers. The Irrlicht rendering logic is implemented in the irr::video namespace, and the base interface for material rendering is
irr::video::IMaterialRender.

Let’s search for all the classes implementing directly the irr::video::IMaterialRender interface.

Attached Image: irrelicht8.png

Both DirectX and OpnGL renders are implemented. the COpenGLSLMaterialRenderer, COpenGLShaderMaterialRenderer, CD3D9ShaderMaterialRenderer and CD3D9MaterialRenderer are the base classes for all the other rendering classes.

Let's export the result of the previous query to the dependency graph:

Attached Image: irrelicht2.png

In this graph the rectangle size is proportionel to the size of code, and as we can observe the OpenGL rendering base classes are bigger than the DirectX ones.

The fact that the OpenGL base classes are bigger does not mean that the OpenGL implementation is more verbose, but it could mean that the OpenGL rendering implementation has more common rendering code than DirectX. therefore we have to compare the implementation of all the renders inheriting from these base classes.

OpenGL renders

Let's search for all classes inheriting from COpenGLSLMaterialRenderer and COpenGLShaderMaterialRenderer directly or indirectly:

Attached Image: irrelicht3.png

The OpenGL renders implementation has 548 lines of code.

DirectX renders

Let's search for all classes inheriting from CD3D9ShaderMaterialRenderer and CD3D9MaterialRenderer directly or indirectly:

Attached Image: irrelicht4.png

The DirectX renders implementation has 296 lines of code.

Like the rendering base classes, the sum of the OpenGL implementation rendering classes is more than the DirectX ones.

To investigate more this difference let’s compare the implementation of the method OnSetMaterial in COpenGLMaterialRenderer_SOLID and CD3D9MaterialRenderer_SOLID classes:

DirectX implementation

virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
{
  services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);

  if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
  {
    setTextureColorStage(pID3DDevice, 0,
    D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE);
  }

  pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
}

OpenGL implementation

virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
{
  if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
    Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
  else
    Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);

  Driver->disableTextures(1);
  Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
  
  if (resetAllRenderstates || (material.MaterialType != lastMaterial.MaterialType))
  {
    // thanks to Murphy, the following line removed some
    // bugs with several OpenGL implementations.
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  }
}

As we can observe, the logic of setting basic states for DirectX is centralized in one method, however for OpenGL we need 6 lines of code. But this difference could be due to the developers implementation choice. And maybe the setBasicRenderStates of Directx include the lines added in the OpenGL implementation.

Let's search for all setBasicRenderStates methods:

Attached Image: irrelicht7.png

The COpenGLDriver::setBasicRenderStates method is more bigger than CD3D9Driver::setBasicRenderStates. which makes the OpenGL implementation more verbose.

Number of calls needed to the OpenGL and DirectX APIs


Another more reliable indicator to check the verbosity concerns the number of calls to the external API library needed to do some treatments.

Let’s take as example the big classes irr::video::COpenGLDriver and irr::video::CD3D9Driver from the rendering logic and check how many calls they need.

Let's search for all the OpenGL functions called directly or indirectly from the COpenGLDriver class:

Attached Image: irrelicht5.png

The OpenGL driver needs 72 calls to the OpenGL API.

And concerning the CD3D9Driver class:

Attached Image: irrelicht6.png

The DirectX driver needs 66 calls to the DirectX API.

Conclusion


When searching the web for which of the two APIs is more verbose, more developers say that DirectX is the most verbose one, however it's not necessarily true, it depends more on the the developer's design and implemenation choices.

For example, in this case of the Irrlicht engine, the OpenGL implementation is more verbose than the DirectX one, and it could just as well be the inverse for other game engines.

Viewing all articles
Browse latest Browse all 17625

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>