The editor and wxWidgets

November 17, 2009 by isometrictiger

The latest progress on the game is probably the font rendering which is based around D3DXFont. Apparently I was way wrong when I thought that it wouldn’t be easy to adapt as I wanted to, when I read the documentation I realized that it was really awesome. Out of the box it has access to all the fonts installed in the system, and by calling AddFontResourceEx you can even add custom fonts to this pool. Another feature is that it’s possible to get automatic word wrapping, clipping and also change the alignment of the text.

Lately I’ve started thinking about an editor for the game, which means that I will need a rather sophisticated GUI system. At first I started implementing a GUI with my own in game components and it sure has the potential to work really good. But I figured that the editor will be a ton easier to use with a native interface, so I started looking towards wxWidgets.

wxWidgets appeared to be almost totally worthless at the first glance, the only documentation on how to initialize the application told me to use some macro IMPLEMENT_APP which would create a main() function and initialize the application to use some wxWidgets main loop. That would not fit into my structure at all. I started reading the wxWidgets code to find out how to use it without having it hijack my main loop and my message pump. Initializing it without the macro appeared to be quite easy (after reading code for a couple of hours) (sorry about the formatting):

class CrazEdApplication : public Craze::Win32Application, public wxApp
{
....
};

bool CrazEdApplication::VInitialize()
{
wxApp::SetInstance(this);

int argc = 0;
wxEntryStart(argc, (char**)0);

if (!Craze::IApplication::VInitialize())
return false;

OnInit();

VShowCursor(true);

return true;
}

bool CrazEdApplication::VCreateWindow(int width, int height, bool windowed)
{
m_pMainFrame = new wxFrame(NULL, -1, _T("CrazEd - Craze Engine Level Editor"), wxDefaultPosition, wxSize(1024, 768));
m_pMainFrame->Show(true);
SetTopWindow(m_pMainFrame);

wxEventLoop::SetActive(new wxEventLoop());

wxPanel* pPanel = new wxPanel(m_pMainFrame, 0, 0, width, height, wxSUNKEN_BORDER);

m_hWnd = (HWND)pPanel->GetHWND();

m_WindowWidth = width;
m_WindowHeight = height;

CreateUI();

return true;
}
void CrazEdApplication::VMessagePump()
{
//Steal our own messages before wxWidgets does so :]
Craze::Win32Application::VMessagePump();

while (Pending())
{
if (!Dispatch())
{
Shutdown();
}
}

while (ProcessIdle());

}

There are a few important things which are noteworthy here:

  • The call to wxApp::SetInstance registers the this pointer to be the wxApp which is used. I don’t remember what the call to wxEntryStart does, but be sure to not use wxEntry since it starts its own main loop.
  • wxEventLoop::SetActive is the line that enables wxWidgets to dispatch messages.
  • The HWND from the panel created is stored and later sent into the graphics engine for creation of the Direct3D device.
  • The message pump starts with taking the window messages sent to its own HWND first and then lets wxWidgets take care of the rest. It’s possible that I should call my own message pump between each call to wxWidgets’ Dispatch().
  • Well, that’s basically it. Now I’ve just got to design an awesome looking interface in wxWidgets and think of all the functionality that I want to have in the editor.

     

    ~Daniel

    Stereoscopic rendering

    October 29, 2009 by isometrictiger

    This is so cool that it deserves another post today. I was reading a topic on a forum about 3D-rendering using red/blue glasses and other techniques when I remembered about stereoscopic images using the cross eye technique ( http://en.wikipedia.org/wiki/Stereoscopy ). I thought that this would be pretty cool and rather easy to implement in my game so I went ahead and gave it a shot (in a new branch ;) ) and this is the result:

    1

    It works pretty good for me and it’s rendered in real time, I just had to tweak the camera offset distance a bit to get it at least decent. I have been a bit lazy so user interface is not rendered at both sides (which is because I use the interface to render the sides) which produces a pretty irritating effect but it’s still something which you can disregard from.

    ~Daniel

    The main menu and the stack based state system

    October 29, 2009 by isometrictiger

    Previously I kept track of the current game state by simply having a state manager with a pointer to the active state. This active state could then be changed by simply typing for example:
    pStateManager->SetState("PlayState");
    All the states are created by the game at startup and are given a name and then stored by the manager so that it’s sufficient to use a string for changing the state. This has worked pretty okay so far but when I created the main menu state it simply didn’t quite fit in for some reason which I can’t remember. I thought about this for some time and then I remembered an old state system which I used for a game server for a simple flash game I wrote a couple of years ago which used a stack based state system.

    The stack based state system works something like this: you push a state onto the top of the stack and it will then be considered the active state this will also have the state manager call the OnStart function which should allocate the needed resources, this is the state which will receive update calls each frame. The state which was previously on the stack will get its OnPause function called so it can release the allocated resources or at least hide the resources which are visible on the screen. When you call PopState the state manager will call OnStop for the game state on the top and then pop the internal stack and call OnResume on the new active state.

    How does this fit in so flawlessly in my current design? Well, recently I coded a loading screen (which normally is visible for around 2 frames, or less than 0.1 seconds) and it was quite tricky to made it work, I had to move a lot of code around and actually set the loading state to request all the models and create a world and create the player. This was not good at all. In this new state system all the code for loading stuff can be anywhere in a game state and then I can simply push the loading game state, it will display the loading screen and wait until the texture manager has loaded all the resources and then it pops itself to resume to the previous game state. Works like a charm and while it’s a slightly more complicated solution than my previous one it for sure is a lot easier to use in practice while keeping the code at logical places.

    Oh, and I coded a main menu with two buttons; new game and exit game. I also entered the project into a perforce repository hosted at my computer so I can have some source control, it’s practically the first time I use such a system and I have a great feeling about this. My previous attempt to using source control was with an automated backup system (SyncBack, lovely program and it’s free to use the most lightweight version) which made a new time stamped copy of the source code directory each day to a USB-flash drive, of course this is also in order to avoid losing all my code. Oh, and perforce, which by the way is free for anything less than three users, is integrated into visual studio so it’s really handy to use; files get automatically checked-in when you edit them etc.

    Other improvements of the game since my last update is that I have used knowledge gained from my very recent course in computer graphics and written ray intersection testing since my pixel perfect sprite collisions are now just not working since it’s a 3d game. I have also added a dialog game state which adds a nice border at the top and the bottom of the screen. My next step till probably be to create a better (better = more adapted to my specific purposes, D3DX is otherwise great) font rendering engine so that I can display some text too.

    Fresh screenshot (note the cool water reflections, but please don’t note the artifacts ;) ), the swat soldier is Jakob’s (the artist) creation and is still yet not animated which is why he looks like he is hunting for a hug:
    Screenshot1

    ~Daniel

    Possible slight change in style

    September 22, 2009 by isometrictiger

    I’m currently studying a course in computer graphics and we can either choose to do some tutorials (boring ;]) or create a bigger project. Not surprisingly I chose the latter and decided to keep on working on this game and add my graphics effects that I had in a separate branch and also create a few new graphics “effects”. Lately I’ve been working on the water and trying to make it look cool. I’m pretty happy with how it looks, the only problem is some really ugly minification artifacts which occurs because I’m using a sine function to generate the normals. I might want to throw a normal map at it instead, or I’ll just have to make sure that distant water isn’t covering large areas, or I’ll have to increase the wave size just a bit. The latest thing I’ve added to the water is an effect that makes it fade towards a water color (almost black, just a little blue) when the distance to the surface below increases, I’ve also added Fresnel reflectance so it looks pretty sweet.

    The very latest addition I’ve been working on for two or three days is support for animated skinned meshes (hardware skinning) with a little… “help” from D3DX. To be honest, I definitely think it would have been easier to roll my own system but then I would have to write code to export meshes from some modeling software and I would also have to create some file type and models to test the animation system on. Thus, it would really take a long time so I decided to go with D3DX. I’m not going to describe the loading process in detail, there are documentation and also some samples available in the DirectX SDK, but it was quite the pain and a really complicated beast of code to work with. It didn’t really help the case that I made a small typo in my code that made the bone matrices not multiply correctly and I had to spend a lot of time debugging the whole thing (that wasn’t the only problem though). Now all those problems are fixed and it’s working pretty good, I’ll just have to create a way to render the skinned mesh for my shadow map as well, but that will be really quick. Of course I also had the classic skinning problems making my model look really funny :].

    Since we are studying computer graphics, Jakob and I have started to get interesting in using 3D models instead of 2D sprites. It actually feels like it might be simpler to do so since everything is adapted for 3D now anyway. We have decided to stick with the top down camera and also not allow the user to move it, I really love static cameras so I don’t have to mess around with the camera myself and also allowing the game to be made for a static camera.

    Screenshot (slightly mspainted)!
    Slightly MsPainted Screenshot

    ~Daniel

    Updating the tile system

    September 9, 2009 by isometrictiger

    I simply can’t resist rewriting existing components with better functionality, today I’ve decided to remake the tile system. While I was thinking about how I wanted the tiling system to work I realized that my current implementation of the sprite class might be in the way. It used to automatically resize the sprites to adapt to the texture size automatically with a hard coded value for pixels per unit, I have realized that such behavior is quite the pain to work with and that you often want more control. Now the sprite has options for setting width and height and also center point which is a new feature, and the autosizing is done only when the user calls the AutoSize function.

    The plan is to batch more tiles together (like 10×10 tiles or something like that), right now I draw every single tile with a DrawIndexedPrimitive call for each one – and if different textures are set for the tiles I also have to change the texture. Well, as you may see this has the potential of being horribly slow so I decided to batch the tiles together and create a texture atlas for the textures. I will miss the culling of a few (up to 90 tiles) but I’m quite positive that having like 200 fewer draw calls each frame (right now I’m rendering 24 * 9 tiles for full screen coverage) will outweigh that pretty much. Actually, the most important reason why I did it this way is because when I was painting a new ground texture and wanted to make tiles out of it I just felt it was too much trouble cutting it out manually so I decided to recode the tile system so that I could stretch out large textures over several tiles. The texture atlas algorithm I am using is the one that can be found here: http://www.blackpawn.com/texts/lightmaps/default.html and so far it seems to work pretty well. I haven’t put it to heavy testing yet though.

    The house in the attached image is my latest artistic creation:
    House
    ~Daniel

    Character model

    September 7, 2009 by isometricpoacher

    A female warrior with sword and shield. Will probably be the main female player character model, and we’ll simply edit the armor to give different looks.

    I’ve been checking out the access to free motion capture libraries, and I’ve found one that’s very extensive and is easy to use with 3dsmax. I’ve been trying to use their animations for this project, but it appears to require a lot of tweaking before looking acceptable. It will probably be easier to just animate the traditional way but I may perhaps use the library’s animations as reference. Meh, I thought I had found a cheap way out of having to animate myself :(
    actiongirl
    /Jakob

    Really cool function pointers!

    September 7, 2009 by isometrictiger

    I’ve just recently started working on this game again and yesterday I reenabled the pixel perfect picking, which was quite a pain to be honest. When I first tried it, it didn’t work at all – well it almost worked at some parts of the image while it was completely off at other parts. It took me a few good hours of debugging which mostly consisted at staring at one line of code:

    unsigned char* pPixel = (unsigned char*)m_LockedRect.pBits +
    		pixelY * m_LockedRect.Pitch + pixelX * 4;

    Then I suddenly realized that DirectX might be resizing my textures to the closest 2^n, which it aparently did (didn’t do it before but I have switched to windows 7 and I suspect that might be the cause). It was easily fixed and after that it worked like a charm, now I’m just waiting for the DirectX august 2009 SDK which is supposed to fix a few problems many people have with windows 7 and DirectX, like not being able to create a hardware device with the debug run time enabled.

    Now for the most interesting part! Yesterday I got tired of all my ugly switch()es and if()s to check for events and other things, so now I’m just going to slightly change it into using function pointers, std::tr1::function to be precise. I looked into it today and thought it would be awesome if I could just point to a member function of a class directly so that I don’t have to create separate C function and mess around with that so while I was browsing around the documentation for tr1 I found the lovely functions mem_fn and bind. Look at this piece of code (this code is called from within a BattlecrazePlayState):

    std::tr1::function<Craze::Core::IPlayer*()> f = std::tr1::bind(std::tr1::mem_fn(&BattlecrazePlayState::VCreatePlayer), this);
    Craze::Core::IPlayer* pTest = f();

    It works perfectly, and I feel that it’s going to be really useful later on. So, how does it work? Well, first I create a member function pointer with std::tr1::mem_fn. This function works just like the original function except that it takes a pointer to the this object as a first argument. That is pretty handy, but it’s quite the pain having to keep track of that when you need to callback to the function, that where std::tr1::bind comes in handy. This function takes a function and a list of values and returns a new function that when called automatically fills in the first arguments from the list specified when creating the bind. In the case above I bind the this pointer so that it will be automatically included when the std::tr1::function is called and then it’s done! Calling it is really easy as you see, I can’t wait to play around with this after school today but first I have a lecture in computer graphics.

    EDIT: Fixed that this blag software removed my template parameter.

    ~Daniel

    New cursor

    September 1, 2009 by isometrictiger

    I scrapped the redesign. While it was a lot better in almost all ways (using shared_ptr / weak_ptr, avoiding unnecessary inheritance and being more streamlined for 2d usage) I felt that it was too much work for too little result, I’ll just have to bare with using 3d positions. After I reverted the project to the state it was before I started messing around I took 20 minutes to implement a cursor, and then another 40 minutes to create a nice image to use as a cursor and the result was very pleasing.

    There have been a lack of progress on the 2D game, that is since I’ve started trying some awesome 3D effects in the same engine, but in a new branch. Most recently I implemented perlin noise and added that to my water effect. I also have effects for HDR/bloom, skydome and shadow mapping. I’ve included a screenshot in this post, the black edges around the sprites is because I haven’t bothered rendering everything in quite the correct order yet.

    Water

    Back for a redesign!

    August 5, 2009 by isometrictiger

    As the end of the summer is getting closer I’ve slowly begun coding again. Just before my summer break I decided to rewrite the graphics engine to have a more genuine 2D interface, right now I have to set every position in 3D and I also need to mess around with rotation matrices for my sprites and I really want to get rid of that. While I’m at it I’ll also convert at least the graphics engine into using std::tr1::shared_ptr and std::tr1::weak_ptr, I think it will be worth it in the end (hopefully).

    The only problem is that I’ve been reading in real time rendering during the summer about lighting and shadowing and other really cool stuff that I really want to try out, which means that I proceed with coding some of it I will have less time for the game. On the other hand I’m having a course in computer graphics this fall so I guess I gotta do some experimenting at home.

    ~Daniel

    TextureManager finished! Almost…

    May 13, 2009 by isometrictiger

    The texture manager is basically finished, at least I won’t do much work on it for quite a while. The result came out really nice, the templated stuff is gone and I have ported all my texture usage to use the new texture manager. I’ve also been working on a sprite class, this is the class which is responsible for rendering the textures on the screen. The sprite class has a new trick that wasn’t performed previously; the textures are now resized according to how big the images are to better match the pixel size of the screen.

    The textures are kept until more space is needed, then the oldest texture is removed. The oldest texture is the one that haven’t been used for the longest. This is done in a quite simple way, I’ve wrapped a class around the std::map where I store the textures. When I need to remove an element I search through the list for the oldest element. I have done a post about this previously and I figured this would be the best way I could make up for an aging algorithm, another option I had was to use a reference counting mechanism instead. The performance would be equal, but in the end I thought it would be easier to pass around an unsigned int than a shared_ptr (or weak_ptr). Here is the code for the AgeMap I’m using:

    template <typename, typename> class AgeMap;
    
    /**
    Helper for the AgeMap class. Simply contains the age.
    */
    template <typename Tkey, typename Tval>
    class _AgeMapEntry
    {
    friend AgeMap<Tkey, Tval>;
    protected:
    _AgeMapEntry(Tkey k, Tval v) : key(k), data(v), age(0) {}
    _AgeMapEntry() : age(0) {}
    Tkey key;
    Tval data;
    unsigned int age;
    
    public:
    bool operator== (const _AgeMapEntry<Tkey, Tval>& e) const
    {
    return data == e.data;
    }
    bool operator< (const _AgeMapEntry<Tkey, Tval>& e) const
    {
    return data < e.data;
    }
    };
    
    /**
    The AgeMap keeps track of the ages of all elements stored in the map and provides a way
    to fetch the oldest element. The elements are considered changed when they are fetched, and the
    oldest element is the element that haven't been changed for the longest.
    */
    template <typename Tkey, typename Tval>
    class AgeMap
    {
    public:
    
    AgeMap() : m_Counter(0) { }
    
    /**
    Returns the value associated with the key and renews the age of the element.
    @param key The key of the element to fetch.
    @return Optional object that might be containing the element, check optional.Valid() to see if the element was found.
    */
    optional<Tval> Get(Tkey key)
    {
    
    _AgeMap::iterator elem = m_Map.find(key);
    if (elem == m_Map.end())
    {
    return optional<Tval>();
    }
    
    (*elem).second.age = m_Counter;
    
    return optional<Tval>((*elem).second.data);
    }
    
    /**
    Adds a new element to the age map.
    @param key The key of the element to add.
    @param val The value of the element to add.
    */
    void Add(Tkey key, const Tval& val)
    {
    _Entry entry(key, val);
    entry.age = m_Counter;
    m_Map.insert(std::make_pair(key, entry));
    
    }
    
    /**
    Removes the oldest item from the age map and returns the item.
    @return An optional containing the value of the oldest element.
    */
    optional<Tval> RemoveOldest()
    {
    if (Size() == 0)
    {
    return optional<Tval>();
    }
    
    unsigned int oldest = m_Counter + 1;
    _AgeMap::iterator oldestElem;
    
    for (_AgeMap::iterator i = m_Map.begin(); i != m_Map.end(); ++i)
    {
    if ((*i).second.age < oldest)
    {
    oldestElem = i;
    }
    }
    
    optional<Tval> ret = optional<Tval>((*oldestElem).second.data);
    
    m_Map.erase(oldestElem);
    
    return ret;
    }
    
    /**
    @return An optional containing the value of the oldest element.
    */
    optional<Tval> GetOldest()
    {
    if (Size() == 0)
    {
    return optional<Tval>();
    }
    
    unsigned int oldest = m_Counter + 1;
    _AgeMap::iterator oldestElem;
    
    for (_AgeMap::iterator i = m_Map.begin(); i != m_Map.end(); ++i)
    {
    if ((*i).second.age < oldest)
    {
    oldestElem = i;
    }
    }
    oldestElem->second.age = m_Counter;
    
    return optional<Tval>(oldestElem->second.data);
    }
    
    /**
    @return Number of elements in the AgeMap.
    */
    unsigned int Size() const
    {
    return m_Map.size();
    }
    
    /**
    Updates the age map by increasing the timer by one step.
    */
    void Update()
    {
    m_Counter++;
    }
    
    /**
    Clears all elements from the age map.
    */
    void Clear()
    {
    m_Map.clear();
    }
    
    private:
    typedef _AgeMapEntry<Tkey, Tval> _Entry;
    typedef std::map<Tkey, _Entry> _AgeMap;
    
    _AgeMap m_Map;
    unsigned int m_Counter;
    };

    ~Daniel