Since I rebooted my game engine Aether3D I've done a lot of new code into it. It now works fine on Windows (D3D and OpenGL), Linux and Mac OS X. I've also compiled it on iOS, but it needs more code to work.
OpenGL 2.1 without using anything that is deprecated in OpenGL 3 or 4. Direct3D 9. Model file format is my own, but converters exist for .obj and COLLADA. I also began coding a Blender exporter plugin.
DLL (or .so) system is implemented by having the core engine classes exporting virtual methods that are implemented by the DLLs. Hence, if the engine has method Renderer::clearScreen(), it's implemented in the OpenGL using glClear( GL_DEPTH_BUFFER_BIT ); and in the Direct3D using d3ddev->Clear(...);
Shaders are stored in asset subfolder as GLSL or HLSL source code. The engine determines which shader to use depending on material properties. At the startup, all shaders are loaded from the disk and cached.
At the moment, OpenGL backend is more optimized than D3D, but I will optimize both much more. Objects are cached when loaded from the disk so loading the same object many times is fast. When rendering, view frustum culling is performed. TODO: distance culling and sorting meshes by texture or shader.