I'm a DirectX guy by preference because it offers the most complete gaming solution for the x86 platform. OpenGL is a graphics API whereas DirectX is the whole shebang to include input devices, multimedia streaming/playback/recording, 2D/3D graphics, an extremely useful library with common 3D functions/objects/structures/classes and COM objects. The D3DX library alone should be enough for anyone in OpenGL to run like hell to DirectX. It's extremely useful.
Another point is that you see most games out there are coded for x86 platforms and usually support both GL and DX. So the issue of cross-platform is a moot point and if we are talking consoles, MS is already developing technology to port from PC to console (XBOX) and back. Their new XAct technology will greatly aid in porting code.
With DirectX you can create an entire game start to finish (from a pure code standpoint) without touching a third party library although you may wish to. The only other library I might even suggest using is the Miles sound library developed by RAD game tools. It is NOT cheap by any stretch of the imagination but it simply kicks ass. The only audio engine that surpasses it is the proprietary Bungie audio system that drives the Halo games. No one does audio like Bungie.
Also when it comes to things like shaders and effects Microsoft has an excellent effect framework that integrates seamlessly into existing engines and it is easy to develop an engine that works with it. I'm not a Microsoftie by any means but I must give credit to them for DirectX. It is sheer brilliance.
Core assembly and C/C++ code
Compiler/IDE: MSVS (most recent version of Visual Studio is .NET 2005)
Assembler: MASM or NASM
Core shader code
Shader code language: HLSL (High Level Shading Language)
Shader compiler: fxc - MS's HLSL compiler
As an example of the D3DX library take this code which sets up a world transformation matrix:
Code:
D3DXMATRIX matScale;
D3DXMATRIX matTrans;
D3DXMATRIX matRot;
D3DXMATRIX matWorld;
D3DXMatrixScaling(&matScale,m_vecScale.x,m_vecScale.y,m_vecScale.z);
D3DXMatrixTranslation(&matTrans,m_vecPos.x,m_vecPos.y,m_vecPos.z);
D3DXMatrixRotationYawPitchRoll(&matRot,m_vecRot.x,m_vecRot.y,m_vecRot.z);
D3DXMatrixIdentity(&matWorld);
matWorld*=matScale*matRot*matTrans;
m_pDevice->SetTransform(D3DTS_WORLD,&matTrans);
...
Now this can be done in OpenGL but you would need the following:
- A 3D vector class with operator overloading for common operations
- A matrix class to handle matrices
- A matrix math library to handle matrix mathematics and common matrix/matirx and matrix/vector operations
Now imagine writing code in OGL to set values in your shaders. You would need something to identify the vector, matrix, or value and then code to set the value. This is actually quite a bit of code.
In Direct3D once you have an effect created you can simply do this to set a matrix:
Code:
D3DXMATRIX matWorldViewProj;
D3DXMATRIX matView;
D3DXMATRIX matProj;
D3DXMATRIX matWorld;
m_pDevice->GetTransform(D3DTS_PROJECTION,&matProj);
//Camera would be a user class....no native camera support in D3D
m_pCamera->GetViewMatrix(&matView);
//Get world matrix from the object
m_pObject->GetWorldMatrix(&matWorld);
//Do the multiply once and transfer to shader
matWorld*=matView*matProj;
//Assumes m_pEffect is a valid ID3DXEffect interface pointer
//Created by calling D3DXCreateEffectFromFile() and passing in needed params
m_pEffect->SetMatrix("matWorldViewProj",&matWorldViewProj);
....
Done. Now your matrix matWorldViewProj in your effect file has been set and is ready for use.
So in essence the core code is already there and all you have to do is wrap these nice interfaces in classes which really speeds things up. An engine is really 3 levels or I like to think of it that way. First level is the core code that does the math, sets up the basic functions, etc, etc. The second level is the C++ code that wraps all of this into nice neat tight little classes/objects. The third level of code is the C++ code that uses the second level, or simply put, uses and expands on the wrappers and objects that wrap the core code. For instance in my engine I have the following:
- Level 1 - DirectX functions - the core set of DirectX functions/interfaces available to the application
- Level 1A- The D3DX library of functions that are available to all applications - wraps a lot of level 1 interfaces/functions
- Level 2 - CD3DXApp - wraps the core startup code, DirectX/D3DX functions/interfaces, etc, into a core application object
- Level 3 - CStarXApp - the 'game specific' derivative of the core application object that handles game-specific initialization, rendering, etc.
- Level 4 - User derived classes - CStarXApp has pointers to many more manager classes which then have pointers to vectors of base objects, user-defined objects, etc, etc.
When you begin to look at the code requirements to gain the functionality of D3DX and the effect framework you can see why people choose Direct3D. Do not let COM programming influence your decision concerning Direct3D - it has been made so simple a child could do it. Personally I think Direct3D is a cakewalk. Now getting your algorithms and all to work and your resource management system to function flawlessly and efficiently is a completely different story. Graphics are easy...but a game is 10% graphics and 90% management of resources.
If you want compatibility you can never go wrong with Microsoft. Everyone else struggles to match the compatibility of MS products. To be fair it is because they designed the OS on which their apps run. Whether or not that is fair is up to someone else to decide...but that's how it is.
But in the end its up to you. We could sit here and hash out differences but the end result will still be you must make the final decision. My recommendations based on my experience: