Posts Tagged ‘programming’

Programming in Vala

January 18th, 2011

As some of you may know, I work for an open source software non-profit called Yorba. Our best known product is Shotwell, a photo management application that’s similar to Picasa or iPhoto, but created for Linux. It’s the default photo app these days in both Ubuntu and Fedora.

What many of our users don’t know is we don’t develop our software in C or C++… we use Vala.

So what the hell is Vala?

The cool thing about Vala is that it’s a fully compiled, statically typed OOP language designed to be built for Gtk applications. The syntax is very similar to Java or C#, but the garbage collection is based entirely on reference counting. In other words, you get the simplicity of a modern language with the speed of a fully compiled program. Vala bindings are already available for Gtk, Gdk, GLib, Gee, and many other libraries. Or you can create your own bindings when needed by creating a Vapi file. There’s a documentation program, Valadoc, which generates pretty HTML documentation for your classes.

The entire Vala package is available under an LGPL license, which is a free software/open source license. You’ll never have to worry about Microsoft or Oracle stepping on your toes.

Here’s the “Hello World” app from the Vala tutorial.

class Demo.HelloWorld : GLib.Object {
    public static int main(string[] args) {
        stdout.printf("Hello, World\n");
        return 0;
    }
}

Save your file as hello.vala. You can compile from the command line with:
valac hello.vala
Now watch closely… the Vala compiler actually just creates a .c file! It’s what’s called a “source compiler” in that it converts source code from one language to source code in a different language.

Next, valac automatically invokes GCC to compile the .c file into an executable binary.

Run your demo code with:
./hello

Simple, huh?

Vala syntax includes the language constructs you’d expect in 2011, including:

  • interfaces
  • single inheritance
  • non-nullable variables
  • foreach loops
  • delegates
  • signals
  • reflection
  • built-in multidimensional arrays
  • type inference

There’s plenty more sample code and tutorials on Gnome’s Vala site.

Documentation for some of the most common library bindings is available at Valadoc.org.

Okay, ready for the bad news? Despite being a relatively feature-complete language, there’s really no perfect IDE for Vala yet. If you’re used to powerful graphical debuggers, class browsers, and jumping around the code like in Eclipse and Visual Studio, you’re out of luck.

The only Vala IDEs at the moment are:

  • MonoDevelop: A great start, but for the features it’s rather heavy.
  • Valide: I was never able to get this one to even compile! But the screenshots look promising.
  • Valencia: This is Yorba’s GEdit plugin, which provides only barebones Vala functionality on top of GEdit, including jump to definition and autocomplete.

So there you go, that’s Vala. It’s still a young language, but it takes away the headaches of developing Gtk apps in C, and it doesn’t have the uncomfortable legacies of C++. Give it a shot!

Accelerated 2D graphics with OpenGL and SDL: part 1

October 13th, 2010

As some of you know, I’m working on an old-school puzzle game with Hryx. This game makes use of OpenGL’s graphics capabilities, but not for 3D graphics. Nope, the game is entirely two dimensional.

So why OpenGL? Because it’s really, really fast on most systems. Much faster than the slowpoke graphics in SDL.

This is going to be part one of a two part series on doing 2D graphics using OpenGL. And step one? Getting some 2D sprites loaded.

Loading the sprite with SDL_image
Now since we’re using SDL for our game, we decided on the excellent SDL_image to do the image loading.

Using SDL_image to load a sprite into memory is absurdly easy.

string filename = "myImage.png";
SDL_Surface* surface = IMG_Load( filename.c_str() );

That’s it!

But wait… that loads the graphic into an SDL surface. We need it to be an OpenGL texture! Damn.

OpenGL textures
In OpenGL, there’s no such thing as a “sprite.” You just have “textures.” So we’ll need to take our sprite and map it to a texture. The texture will be referenced with an integer (a GLuint) rather than a pointer.

But there’s an interesting restriction we have to work around that SDL simply doesn’t have. On most systems, OpenGL textures must have dimensions are are powers of two: 2, 4, 8, 16, and so on.

So once we load our SDL_Surface, we’ll make a new surface where we’ve rounded up the dimensions to the next highest power of two. The new surface will be filled with the alpha “color” and then we can blit (copy) over the existing image to the top left corner of our new image.

SDL_PixelFormat *format = surface->format;
Uint32 width = surface->w;
Uint32 height = surface->h;
Uint32 widthPow = (unsigned) pow( 2, ceil( log( width ) / log( 2 ) ) );
Uint32 heightPow = (unsigned) pow( 2, ceil( log( height ) / log( 2 ) ) );

// Create new empty surface.
SDL_Surface* newSurface = SDL_CreateRGBSurface( SDL_SRCALPHA,
	   widthPow, heightPow, 32,
	   rmask, bmask, gmask, amask );

// Fill sprite with alpha.
Uint32 alpha = 0;
alpha = SDL_MapRGBA( format, 0, 0, 0, amask );
SDL_Rect rect;
rect.x = 0;
rect.y = 0;
rect.h = heightPow;
rect.w = widthPow;
int ret = SDL_FillRect( newSurface, &rect, alpha);
surface->flags &= !SDL_SRCALPHA;

SDL_SetAlpha( newSurface, SDL_SRCALPHA, SDL_ALPHA_TRANSPARENT );

// Copy image data to our new surface.
ret = SDL_BlitSurface( surface, 0, newSurface, 0 );

Great, we got our surface loaded. Now it’s time to create an OpenGL texture, then take our SDL surface and copy it to the texture.

// This will be our OpenGL texture.
GLuint texture = 0;

// Bind the texture.
glPixelStorei(GL_UNPACK_ALIGNMENT,4);
glGenTextures(1, &texture );
glBindTexture(GL_TEXTURE_2D, texture);

// Convert surface to Open GL format.
gluBuild2DMipmaps(GL_TEXTURE_2D, 4,
	widthPow, heightPow, GL_RGBA,GL_UNSIGNED_BYTE, newSurface->pixels);

// Free our temporary SDL buffers.
SDL_FreeSurface( surface );
SDL_FreeSurface( newSurface );

Easy, huh?

Dealing with 24-bit surfaces
Up until now we’ve only dealt with is 32-bit images. One thing I hadn’t dealt with until now is 24-bit color-keyed images. A color-keyed image means you have RGB but no alpha or “A” channel to tell you what should be invisible. Instead, you just take one color (often black) and just say that it’s 100% transparent.

What we’re going to have to do is make the SDL_surface color keyed before we copy it to the OpenGL texture.

First, we’re going to need some functions for plotting individual pixels on an SDL texture. Unfortunately there’s no built in functions for this, so I stole some from this site.

Uint32 GetPixel( SDL_Surface *surface, int x, int y )
{
	Uint32 color = 0;
	char* pPosition = ( char* ) surface->pixels;
	pPosition += ( surface->pitch * y );
	pPosition += ( surface->format->BytesPerPixel * x );
	memcpy ( &color , pPosition , surface->format->BytesPerPixel );
	return color;
}

void SetPixel( SDL_Surface *surface, int x, int y, Uint32 color )
{
	char* pPosition = ( char* ) surface->pixels;
	pPosition += ( surface->pitch * y );
	pPosition += ( surface->format->BytesPerPixel * x );
	memcpy ( pPosition , &color , surface->format->BytesPerPixel );
}

Cool, now we can plot pixels! Feel free to go crazy and write a routine to draw circles or something!

But all we really need to do here is to take pixels that correspond with our color key and set the alpha channel to the alpha mask channel color.

if ( 24 == format->BitsPerPixel )
{
   Uint32 colorKey = format->colorkey;

   for ( int y = 0; y < surface->h; ++y )
   {
	   for (int x = 0; x < surface->w; x++)
	   {
		   Uint32 color = GetPixel( surface, x, y );
		   if ( color == colorKey )
		   {
			   SetPixel( newSurface, x, y, 0 );
		   }
	   }
   }
}

Putting it all together
Here is the final code to load an image file to a texture using SDL.

#include 
#include 
#include 
#include 
#include 

#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   static const Uint32 rmask = 0x000000FF;
   static const Uint32 bmask = 0x0000FF00;
   static const Uint32 gmask = 0x00FF0000;
   static const Uint32 amask = 0xFF000000;
#else
   static const Uint32 rmask = 0xFF000000;
   static const Uint32 bmask = 0x00FF0000;
   static const Uint32 gmask = 0x0000FF00;
   static const Uint32 amask = 0x000000FF;
#endif

Uint32 GetPixel( SDL_Surface *surface, int x, int y )
{
	Uint32 color = 0;
	char* pPosition = ( char* ) surface->pixels;
	pPosition += ( surface->pitch * y );
	pPosition += ( surface->format->BytesPerPixel * x );
	memcpy ( &color , pPosition , surface->format->BytesPerPixel );
	return color;
}

void SetPixel( SDL_Surface *surface, int x, int y, Uint32 color )
{
	char* pPosition = ( char* ) surface->pixels;
	pPosition += ( surface->pitch * y );
	pPosition += ( surface->format->BytesPerPixel * x );
	memcpy ( pPosition , &color , surface->format->BytesPerPixel );
}

GLuint loadTexture( std::string filename )
{
	SDL_Surface* surface = IMG_Load( filename.c_str() );

	if ( NULL == surface )
	{
	   // Error!
	   return 0;
	}

	SDL_PixelFormat *format = surface->format;
	Uint32 width = surface->w;
	Uint32 height = surface->h;
	Uint32 widthPow = (unsigned) pow( 2, ceil( log( width ) / log( 2 ) ) );
	Uint32 heightPow = (unsigned) pow( 2, ceil( log( height ) / log( 2 ) ) );

	// Create new empty surface.
	SDL_Surface* newSurface = SDL_CreateRGBSurface( SDL_SRCALPHA,
		   widthPow, heightPow, 32,
		   rmask, bmask, gmask, amask );

	// Fill sprite with alpha.
	Uint32 alpha = 0;
	alpha = SDL_MapRGBA( format, 0, 0, 0, amask );
	SDL_Rect rect;
	rect.x = 0;
	rect.y = 0;
	rect.h = heightPow;
	rect.w = widthPow;
	int ret = SDL_FillRect( newSurface, &rect, alpha);
	surface->flags &= !SDL_SRCALPHA;

	SDL_SetAlpha( newSurface, SDL_SRCALPHA, SDL_ALPHA_TRANSPARENT );

	// Copy image data to our new surface.
	ret = SDL_BlitSurface( surface, 0, newSurface, 0 );

	// Change color key to alpha transparency.
	// Used for 24-bit images.
	if ( 24 == format->BitsPerPixel )
	{
	   Uint32 colorKey = format->colorkey;

	   for ( int y = 0; y < surface->h; ++y )
	   {
		   for (int x = 0; x < surface->w; x++)
		   {
			   Uint32 color = GetPixel( surface, x, y );
			   if ( color == colorKey )
			   {
				   SetPixel( newSurface, x, y, 0 );
			   }
		   }
	   }
	}

	// This will be our OpenGL texture.
	GLuint texture = 0;

	// Bind the texture.
	glPixelStorei(GL_UNPACK_ALIGNMENT,4);
	glGenTextures(1, &texture );
	glBindTexture(GL_TEXTURE_2D, texture);

	// Convert surface to Open GL format.
	gluBuild2DMipmaps(GL_TEXTURE_2D, 4,
		widthPow, heightPow, GL_RGBA,GL_UNSIGNED_BYTE,
                newSurface->pixels);

	// Free our temporary SDL buffers.
	SDL_FreeSurface( surface );
	SDL_FreeSurface( newSurface );

	return texture;
}

That’s it! Next time: displaying our new OpenGL texture on the screen as a 2d sprite.

Programming is a lot like writing

August 28th, 2009

Computer programming is a lot like writing. You use the same tools to do both (chair, computer, scraps of paper) and you have to follow a similar set of rules.

What sort of rules? There’s the strict rules, like syntax, grammar, and spelling. Then there’s the not-so-strict rules, like style and taste. Same idea, slightly different type of language.

Your program also has to “tell a story” in the sense that it’s telling the computer what to do. The stories have varying levels of complexity, but they often involve the same basic overall structure. Both tend to re-use tried and true plot devices that change the story as it goes along.

What are some differences between programming and writing?

  • No matter how great you think your program is, it will never be printed out on paper. (Unless you’re writing a book about programming, in which case you’re writing as well so ha!)

  • If nobody understand your book, it could still be a bestseller. If a computer doesn’t understand your program, nobody will buy it.
  • Writers don’t have SCO filing patent claims on their work.

Next week’s post: Driving a car into a lake is a lot like making silly analogies.