Two week ago I've dusted off my long time neglected engine (after years ;)) and I've made some cleanups, adding support for different windowing systems and newer OpenGL context creation schemes (OpenGL 3.0> ), so I will drop off the SDL for good. Just because it has alot of things I don't need.
At this moment I have got early versions of windows GDI and Linux X11, when I will finish them, I will add support for Mac OS X, IOS (maybe, because i have no real devices to test) and Android OS. I have implemented one base class for window (R3D_window) with several pure virtual and non virtual methods from which all other windows are derived - glxWin for Linux and gdiWin for Windows windows. So it's a good start for other platforms.
Additionally I've got pure abstract class for context with methods like: create(), makeCurrent(), detach(), destroy() which are overriden in derived classes for GDI and GLX subsystems and simple class for Viewport creation, update, resize (which is OS independent).
I've lost alot of time when figuring out to create newer OpenGL contexts(3.0>). It turns out that before trying to create it you have to:
- Create new window with dummy, old OpenGL
- Initialise OpenGL extension function pointers (with GLEW for example),
- Destroy window and old context,
- Create brand new window with selected pixel format and new context,
After that things started to work.
I intend to do small configuration dialog for launching the engine, for now things like screen resolutions, enabling/disabling full screen mode, multisampling and vsync. Later there will be other things like input configuration (keyboards, pads, joysticks) and audio settings.
I'm really curious how things will work out. The process is bit tedious, because I have to test the code on different compilers and environments (Win XP, Linux 32 & 64 bit). Yes, this is the truth about cross platform development, writing code, recompiling, testing, switching boxes, repeat ...
After I finish all of this I will go to the problem of various input devices. But, surely I will not start from scratch here and I will use [OIS](http://sourceforge.net/projects/wgois/ "OIS - Object oriented input library") here.
There is alot of discussions about using STL containers nowadays (pros/cons/they are evil/they are good/use them/don't use them arguments and so on). To avoid headache I've set up everything that I can switch between different STL implementations at compile time. Here is my example header file which is used in all parts of my engine if WIN32 is defined:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #ifndef __WIN32DATATYPES_H__ #define __WIN32DATATYPES_H__ // common datatypes typedef signed char tCHAR8; typedef unsigned char tUCHAR8; typedef signed short tINT16; typedef unsigned short tUINT16; typedef signed int tINT32; typedef unsigned int tUINT32; typedef signed long tLONG32; typedef unsigned long tULONG32; typedef signed long long tLONG64; //non-standard! typedef unsigned long long tULONG64; //non-standard! // floats typedef float tREAL32; typedef double tREAL64; typedef unsigned char tBYTE; typedef tUINT32 tBOOL; #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif typedef size_t tMEMSIZE; // we can switch here easily between different STL implementations #ifdef STL_EASTL #include <EASTL/string.h> #include <EASTL/hash_map.h> #include <EASTL/vector.h> typedef eastl::vector<tIN32> tVectorInt32; typedef eastl::string tString; typedef eastl::hash_map<tUINT32, eastl::string> tPair; #elif defined(STLPORT) #include <stl/hash_map> #include <stl/vector> #include <stl/string> typedef _STL::vector<tIN32> tVectorInt32; typedef _STL::string tString; typedef _STL::hash_map<tUINT32, _STL::string> tPair; #else #include <hash_map> #include <vector> #include <string> typedef std::string tString; typedef std::vector<tIN32> tVectorInt32; typedef std::hash_map<tUINT32, std::string> tPair; #endif
As it's easy to see I don't use any built in data types and STL containers explicitly in my code at all. I have one header which I include everywhere and which can be different depending on platform, CPU, compiler. Adding simple define to the compiler will force use of different STL implementation (STL_EASTL, STLPORT or no define for standard STL). It's a neat trick I've picked long ago after the lecture of Cross-Platform Game Programming by Jes Goodwin, it's a really good book.
Second thing to do is removing all fixed pipeline stuff for good (or moving it somewhere where nobody will be seeing it ;)), after that I would like to create some kind of virtual file system and implement asynchronous logging.
I will try to organise the system to be multiprocessor friendly, similarly like it was described in slides from Naughty Dog. If you will read it, then you will see that most of online graphics rendering tutorials are teaching bad habits.
I have alot of ideas what to do, I hope to make with all of this small game/demo someday :). Next time I hope to show something, because talking isn't enough :).