Bookmark this on Hatena Bookmark
Hatena Bookmark - Picking a library…
Share on Facebook
Post to Google Buzz
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip
Share on FriendFeed
Picking a library…peter mares dot com

Progress is being made on MindHunters (the Trading Card Game I’m working on). In fact, progress has been really good.

Effects are working on the server, and the game is much more playable (and enjoyable) via the testbed client. Its time to move onto developing the actual game client. This is where I am, and where I’ve been since last week Friday. Well, actually, last Friday I was wondering which framework I should use (if any) for developing the client. My choices were:

  • SDL
  • SFML
  • Cinder
  • Qt
  • Write my own OpenGL framework (not really an option)

Spent Saturday playing with SDL and decided that I really did not like the library one little bit. It was too… erm… dated. Granted, I didn’t try v1.3, but thats not stable yet (but promises a ton of stuff, including iPhone and Android support).

Spent Saturday evening reading through Cinder documentation and concluded that although the library looked really amazing, it was more of a general visualisation library, not suitable for rapid game development.

Sunday, I finally downloaded SFML and fell in love. This framework is just so well put together, light, yet versatile and powerful. Within the first hour of going through the tutorial, I had a sample app with motion trails, a GLSL shader (basic) and event handling all running within approx 120 lines of code. This is what I was looking for! And then it struck me… no GUI interfaces came with the library (remember – lightweight). Sunday evening was spent investigating whether I could integrate SFML 1.6 with Qt, and although it seemed plausible, it turns out that it will only work on Windows, since Qt Cocoa (can’t work with Qt Carbon) does deferred window creation on Mac OS X, which causes the SFML Window creation to fail (Apple restriction for OpenGL windows). Trawling through the forums, it turns out that this is a know issue, and there is no suitable workaround. So that was a dud.

Looks like I’ll be shopping around for a suitable SFML GUI framework (I’ve found 2, and only one is really a candidate), or writing my own. The latter idea concerns me a little since writing basic GUI code from scratch is a lengthy process and can result in severe hair loss and late nights. If anyone has any good GUI framework/libraries that integrate with SFML (or even better, are written for SFML), please drop a line. If I do end up writing my own, I will be blogging the crap out of my site with updates as to how its going. I have an idea on how I would want to do it – by allowing ANY rendering framework to integrate with it by providing it with some methods to call for rendering/timing purposes. This would allow me to swap the library into other projects using other GUI’less frameworks in the future (there are so many!!).

I’m still curious about Cinder and will probably create a separate project that I can write around the Cinder framework and experiment with it when I have some time.

Go go SFML!!

 

 

 

 

 

 

 

 

 

 

 

 

I’ve included the code for my sample app that I wrote against the SFML engine below…
(The colorize.sfx shader can be downloaded here: http://www.sfml-dev.org/tutorials/1.6/sources/colorize.sfx)

 

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics.hpp>
#include <iostream>
#include <list>
#include <sstream>

////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////

struct Point
{
	float x, y, radius;
};

#define MAX_TRAILS 50
#define MAX_RADIUS 50
typedef std::list<Point> TrailVector;


int main()
{
    // Create main window
	unsigned long windowStyle = sf::Style::Resize | sf::Style::Close;
    sf::RenderWindow App(sf::VideoMode(1024, 768), "SFML Engine Test", windowStyle );
	sf::Color fillCol = sf::Color(255, 255, 255);
	sf::Color lineCol = sf::Color(0, 0, 255);
	TrailVector trails;
	sf::String label;
	std::stringstream ss;

	label.SetFont( sf::Font::GetDefaultFont() );
	label.SetSize(12);
	label.SetColor(sf::Color(0, 0, 0));
	label.SetScale(1.0f, 1.0f);
	
	App.SetFramerateLimit(60);
	
	float x = -MAX_RADIUS, y = -MAX_RADIUS;
	
	if ( sf::PostFX::CanUsePostFX() == false )
	{
		std::cout << "PostFX unavailable\n";
	}
		
	sf::PostFX effect;
	if ( !effect.LoadFromFile("../Resources/colorize.sfx") )
	{
		std::cout << "failed to load effect\n";
	}

    // Start game loop
    while (App.IsOpened())
    {
        // Process events
        sf::Event Event;
        while (App.GetEvent(Event))
        {
			switch ( Event.Type )
			{
				case	sf::Event::Closed:
					// Close window : exit
					App.Close();
					break;
					
				case	sf::Event::MouseMoved:
					x = Event.MouseMove.X;
					y = Event.MouseMove.Y;
					break;
			}
        }

		effect.SetTexture("framebuffer", NULL);
		effect.SetParameter("color", 1.f, 1.f, 1.f);
		
        // Clear screen
        App.Clear( sf::Color(64, 128, 255) );
		
		// draw the trails (decreasing in radius as they age)
		int i = 1;
		float radius = MAX_RADIUS / MAX_TRAILS;
		TrailVector::iterator it = trails.begin(), limit = trails.end();
		for ( sf::Uint8 alpha = (255/MAX_TRAILS) ; it != limit; ++it, alpha += (255/MAX_TRAILS), i++ )
		{
			lineCol.a = alpha;
			fillCol.a = alpha;
			App.Draw( sf::Shape::Circle( it->x, it->y, i*radius, fillCol, 5, lineCol) );
		}			

        // Draw the head circle
        App.Draw(sf::Shape::Circle(x, y, MAX_RADIUS, fillCol, 5, sf::Color::Blue));
		
		// draw the FPS counter
		ss << "FPS: " << 1.0f / App.GetFrameTime();
		label.SetText( ss.str().c_str() );
		label.SetPosition( 0, App.GetHeight() - label.GetRect().GetHeight() );
		App.Draw(label);
		ss.str("");
		
		// apply the shader effect (pulled shamelessly from the SFML tutorial)
		float X = App.GetInput().GetMouseX() / static_cast<float>(App.GetWidth());
		float Y = App.GetInput().GetMouseY() / static_cast<float>(App.GetHeight());
		effect.SetParameter("color", 0.5f, X, Y);
		App.Draw(effect);
		
        // Finally, display the rendered frame on screen
        App.Display();
		
		// update the trail vector
		while ( trails.size() >= MAX_TRAILS )
			trails.pop_front();
		
		Point pt = { x, y };
		trails.push_back(pt);
    }

    return EXIT_SUCCESS;
}

[Edit] Minor correction to the code was pointed out my a friend of mine where I was loading the effect on each loop unnecessarily. Fixed.

Share and Enjoy:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks