Well the first method looks better, but there are maybe some pitfalls? Do you have any sigestions about this?
IMHO, you are thinking way too low level. It sounds like you are using native API calls through your application, which is, again just in my oppinion a bad choice since this leads to harder to maintain code. Of course, I'm using #defines to for choosing the correct API, but I hardly require any use of them actually in the clients code. The advantage of this is that I can write code using my own API, and whether I use OpenGL or DirectX it usually runs right away with little tuning needed. As for your examples:
Some custom case
#if RENDER_D3D11
GraphicsDevice()->GetD3D11NativeDevice()->Something();
#else
glFoo();
Why have it like this? Why don't have:
void Wrapper();
// somewhere hidden in a cpp-file
void Wrapper()
{
#if RENDER_D3D11
GraphicsDevice()->GetD3D11NativeDevice()->Something();
#else
glFoo();
}
Then you basically have one call, and whether API you use the call is made correctly. Do you see what I'm talking about? It seems like you want to cluster your code with case-handling about which API to use, when really you'd much rather have abstraction classes and/or functions to handle this kind of stuff. On your lowest level, hidden way behind those high level abstraction classes, you can have different classes for DX or OGL. That way, instead of having an interleaved format like:
enum PRIMITIVE_TOPOLOGY
{
#if defined RENDER_D3D11
PRIMITIVE_TOPOLOGY_TRIANGLELIST = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
#else
PRIMITIVE_TOPOLOGY_TRIANGLELIST = PT_TRIANGLES
#endif
};
you'd make your own independant enum
enum class PRIMITIVE_TOPOLOGY
{
TRIANGLE_LIST, LINE_LIST
};
And use this on the high-level to interact with say your mesh. Instead of doing
#ifdef RENDER_D3D11
D3DMesh mesh(PRIMITIVE_TOPOLOGY_TRIANGLELIST);
#else
OGLMesh mesh(PRIMITIVE_TOPOLOGY_TRIANGLELIST);
#endif
you'd then do
IMesh* pMesh = CreateMesh(Topology::TRIANGLE_LIST);
pMesh->FillVertices(...); // this calls implementation is dependant on the selected API based on which child class was returned, but you don't need to have some #define here.
// factory function:
IMesh* CreateMesh(Topology top)
{
#ifdef RENDER_D3D11
return D3DMesh(top);
#else
return OGLMesh(top);
#endif
}
If you are concerned about speed or likewise, you can still typedef the currently used mesh instead of using a parent IMesh-type, but the point is, you really don't want to use those #ifdef-directives in your client-code, and you also want to reduce the usage of them in your low-level facilities.