   Abstraction in game engines
  Hi!!In most game engine books, abstraction of the graphics API and other subsystems is one of the main concerns. This supposes the use of interfaces and DLLs, as well as having to implement our own subsystems from scratch, such as a mathematics system. But in some cases it means reinventing the wheel (DirectX already offers its Extended Library). Now my question...If we decide to use DirectX as the core technology -like many games do-, is that abstraction actually used in commercial games? For instance, many console games are platform-specific, and some PC titles like Crysis support only DirectX.However, although Crysis does not support OpenGL, I'd like to know how they manage to support DirectX 9 and 10 at the same time. CryEngine3 is being ported to consoles, so I suppose every commercial game use these abstraction layers. In that case, does it mean D3DX is not used commercial games?I'd really appreciate some clarification. Thank you guys   
  I don't know for sure, but I suspect the abstraction layers will still exist. Even if the rendering library is the same, the requirements and practices surrounding it might change based on the platform it's running on.   ;Quote:Original post by NeneIn most game engine books, abstraction of the graphics API and other subsystems is one of the main concerns.True.Quote:This supposes the use of interfaces and DLLsHell, no! Practical abstraction of graphics interfaces is targeted towards multiplatform development. That means a windows build, an XBox build, a Linux build (heh), etc. In other words, abstraction is compile-time, not runtime; no need for anything but a statically chosen graphics layer going into the executable. Choosing between DirectX and OpenGL at runtime, IMNSHO, is useless, timewasting gimmickry.Quote:If we decide to use DirectX as the core technology -like many games do-, is that abstraction actually used in commercial games?Yes, for the reasons of multiplatform capability I mentioned. But you've changed your question in the middle there. The concerns of 150-man development teams with a $60M budget are considerably different from the concerns of a five-man team with a fuckall budget. If you decide to use DirectX as the core technology, you probably do not need an all-singing all-dancing abstraction layer.   ;  Thanks! Although there is no point in switching between DirectX and OpenGL at run-time using DLLs, switching between D3D9 and D3D10 might be different. In Crysis, for example, there is only one executable and you switch from D3D10 to D3D9 passing -dx9 as a parameter. That means the corresponding DLL is loaded at initialization time, right? Or maybe embedding the two implementations in the same build is a better option, what do you think?If I decide to use DirectX 9.0c as the core technology, how can I switch to DirectX 10, 11, etc. in a future? I see exactly the same problem as if we wanted to support OpenGL and DirectX, so an API-independent layer is still required although our game is DirectX-based after all, right?Also, the D3DX library changes as well on each iteration of DirectX. Although some structures and functions remain the same, some of them do not. For example:HRESULT D3DX10CreateTextureFromFile(  // D3DX10  ID3D10Device *pDevice,  LPCTSTR pSrcFile,  D3DX10_IMAGE_LOAD_INFO *pLoadInfo,  ID3DX10ThreadPump *pPump,  ID3D10Resource **ppTexture,  HRESULT *pHResult);HRESULT D3DXCreateTextureFromFile(  // D3DX9  LPDIRECT3DDEVICE9 pDevice,  LPCTSTR pSrcFile,  LPDIRECT3DTEXTURE9 * ppTexture);Do you know what solutions use professional developers?I appreciate your answers[Edited by - Nene on June 23, 2009 12:50:39 PM];Quote:Original post by NeneIf I decide to use DirectX 9.0c as the core technology, how can I switch to DirectX 10, 11, etc. in a future?By changing your code. Writing an abstraction layer that abstracts out everything you think could possibly change between graphics systems will be both overkill and futile.   ;  If I read correctly, directx 11 will handle if dx 10 or 9 will be used depending on whether the graphic card supports dx 10...http://www.softwaretipspalace.com/blog/?p=455This means that all we got to do is learn dx 11 for those going directx, and programming dx 11 on xp should not be a problem. Correct me if I'm wrong. ><   ;Quote:Original post by Twinblad3rIf I read correctly, directx 11 will handle if dx 10 or 9 will be used depending on whether the graphic card supports dx 10...http://www.softwaretipspalace.com/blog/?p=455This means that all we got to do is learn dx 11 for those going directx, and programming dx 11 on xp should not be a problem. Correct me if I'm wrong. ><No, not on Windows XP. Direct3D 11 will run on Windows Vista, Windows 7, and all future Windows operating systems.;Quote:Original post by NeneAlso, the D3DX library changes as well on each iteration of DirectX. Although some structures and functions remain the same, some of them do not. For example:*** Source Snippet Removed ***Do you know what solutions use professional developers?I appreciate your answersWell, I can give you my solution: I created an ITexture interface that offers anything that is needed by the application in a simpler manner. Getting the width, height, aquiring a surface, etc...This ITexture can be created by IVideoDevice which is implemented for a specific subsystem (as is the ITexture ofcourse). This may not be the best solution, as every call invokes a vtable lookup, however I'm a hobby developer and I really like this approach.Another way would be to use the pimpl idom, so you only have a pointer in your ITexture interface, that points to the right implementation://ITexture.hclass ITexture{private:class pimpl *d;public:int width() const; // notice the "non-virtual" here};//ItextureDX9Impl.cppclass ITexture::pimpl{// Here's the actual implementation};You would simple switch the cpp files to use the DX9 or DX10/11 implementation. Maybe this can even be done better, but this is one approach.Abstracting in general is very important, as I really hate to deal with those ugly DirectX functions in my application. I have to look up the documentation about all those parameters and do the FAILED check, which results in 10 lines of code, at least. Abstracting this stuff is really helpful:I no have an IStaticMesh and IDynamicMesh interface that both offer all the functions I need in a much simpler manner (I only need to pass my favourite vector of choice with the vertices & indices: no more dealing with pointers).But be careful and really think what is important and what not, my "engine" underwent several changes because I invented stupid interfaces, or didn't separate enough.   ;Quote:Original post by SneftelQuote:Original post by NeneIf I decide to use DirectX 9.0c as the core technology, how can I switch to DirectX 10, 11, etc. in a future?By changing your code. Writing an abstraction layer that abstracts out everything you think could possibly change between graphics systems will be both overkill and futile.Also, programming a D3D10 app as you would a D3D9 app isn't going to gain you anything. D3D10 (and D3D11) really comes into play when you design your rendering backend to take advantages of their strengths and the API properly.Just naively converting function calls without reconsidering your rendering path isn't going to do you any favours.   ;Quote:Original post by SneftelBy changing your code. Writing an abstraction layer that abstracts out everything you think could possibly change between graphics systems will be both overkill and futile.But commercial games cannot allow being re-written for D3D9, D3D10, etc. They must work with its own rendering interface. I suppose that engines like CryEngine 2/3 have this abstraction layer, but with a rendering pipeline already set up to support full D3D10 capabilities. I guess they thought in D3D10 from the beginning of the engine design, and then added D3D9 support for compatibility purposes. When a new API iteration is released, the engine might be fully revised or rewritten. Is that what you mean?What happens with D3DX?   