Re: TurboSphere
Reply #401 –
And now it almost--very almost--compiles on OS X. Mostly I'm adding alternative implementations for the Linux bits that are GNU, rather than early X/Open or SYSV bits. And figuring out the standard programming and deployment guidelines for OS X, too.
If anyone is curious about how the world looks to TurboSphere, at compile-time and run-time (especially gfx and threading) configuration, here is what is going on:
At compile time, there are two kinds of machines: Unix and Windows.
Or at least, there are machines were we have common Unix headers (we specifically look for the SYSV versions, although we also check in the X/Open locations), and there are machines with the MSVC runtime library. This isn't dependent on the compiler.
There are two kinds of compilers: GNU compilers (these include Clang and MingW) and MSVC compilers (this includes the Intel Compiler and formerly DMC). This just affects the specific switches we give the compilers.
OS X is a special case of Unix--while we normally go through some configuration to check for header locations and versions, we just use the OS X standard locations when we are running on an OS that identifies itself as Darwin.
At run time, it's a little different. TurboSphere has a composite architecture--that is, there are a series of interfaces in the code, and for each one we select a certain implementation to use for that interface. Most of the time the interfaces are to abstract Windows from Unix, although not always. For instance, when you call Delay() from script it becomes a Win32 call in Windows, an X/Open call (usleep2) in Linux, and a Mach kernel call in OS X.
There are also a couple places with multiple libraries that can be used. For instance, the new drawing API can use the Intel Thread Building blocks concurrent queue implementation, or the Microsoft implementation, or (if neither are available) simply a handmade queue wrapped-in-a-mutex. Similarly, when available we use the Intel TBB atomics, but lacking those we use C++11 atomics. Lacking even those, we fall back to SDL2's spinlock atomics.
At run time, TurboSphere recognized three kinds of machines: Machines with OpenGL 3.2, machines with OpenGL 2.0, and machines with OpenGL ES 2. We don't really support pure GL 2.0, we require certain ARB extensions for a some functions (specifically non-pot textures, vertex buffers, and vertex arrays), but we do get along without shaders and use the older initialization system. In GL ES, we remove some calls, and again rely on the GL driver being more than just a core implementation.
TurboSphere does not use any extra OpenGL headers, only the very core GL/gl.h, which isn't much. When we need more advanced functions--so basically everything but generating GL textures--we use run-time loaded function pointers. This has some advantages over just using headers--we never blindly try to use something that isn't there--and over extension querying, which (more often than you'd think) under-reports the implementation. Extension querying also is especially unreliable if you aren't using the default GL version and profile, which TS almost never does.