Archive for October, 2010

SF Weekly SF Weekly

October 27th, 2010

I had the strangest feeling of deja vu after opening a copy of the latest SF Weekly.

Wraps coming off Mission National Bank

October 27th, 2010

In case you haven’t been by recently, the wraps are finally coming off Mission National Bank’s flagship 16th St. location!

Mission National Bank

Restoration on the building’s exterior has been going on for roughly a year now, but the result is totally worth it. The restored facade adds some prestige to the often sketchy part of 16th between Mission and Valencia.

Inanimate Racer

October 22nd, 2010

Today I was surprised to find a (semi-serious) review of a game I created back in high school, “Inanimate Racer.” The point of the game was that you could only race objects that didn’t move.

Here’s the review:

If you’re interested in playing(?) Inanimate Racer, there’s also a Flash remake of the game available here.

Obnoxious tourists

October 22nd, 2010

Don’t get me wrong, when people get lost and need help I enjoy giving directions. I know the city pretty well and have a good sense of direction, and failing that I have an iPhone with Google Maps.

But sometimes, tourists in the city are just completely obnoxious. You know it’s always a bad sign when they ask how to get to Fisherman’s Wharf.

Fire Truck

October 20th, 2010

This may be the greatest paint job ever on a fire truck. Click the image and zoom for more detail.

Fire Truck

Spotted at Townsend and 2nd.

Tuesday

October 20th, 2010

This was someone’s Tuesday night. Looks like they had a great time!

Tuesday

Spotted just outside of 330 Ritch.

No Smoking, No Spitting, No Exit

October 15th, 2010

These are the signs on the noisy Italian streetcars on the F Market line. A rough translation (thanks to Google) is in the title of this post.

Vietato Fumare

Vietato Sputare

Vietato Scendere

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.

Ghin Lon / Transcope

October 12th, 2010

Five years ago, a permanent “Ghin Lon/Transcope,” otherwise known as a kaleidoscope without the colorful beads, was installed by artist Wang Po Shu on Market and Octavia.

Let’s take a look at this device and through its lens, shall we?

photo.JPG photo.JPG

photo.JPG photo.JPG

photo.JPG photo.JPG

Links:
Artist’s page
SF Arts Commission

Worst day on Muni ever

October 11th, 2010

Heading between the Mission and North Beach shouldn’t be an aggravating experience. After all, it’s roughly four miles. There’s several public transit routes one could take.

Easy, right?

Well no; if there’s one thing that’s worse than taking Muni, it’s taking Muni on the weekends. But it turned out to be much worse than I thought.

Heading to the party
On the way to a Fleet Week airshow party, my girlfriend and I decided on Google’s suggested route; take the Metro to Powell and then take the cable car towards Hyde St. Simple, right?

Well the line at the cable car roundabout was incredibly long. We realized this was an impossibility so we hiked up to the Union Square stop. Here, we waited while one full cable car after another went by without stopping. The one (out of five) that DID stop only let six people on. The line was moving fast, but only because everyone was bailing out.

One couple in line swore they’d never return to San Francisco, and with service like that who could blame them?

We gave up to and hiked over to the 30 stop on Stockton. We ran, making it just in time to get on a crowded bus. The 30 took off and then suddenly made an unexpected turn onto California St. There was no announcement as to why we had just gone off route. Everyone pushed and shoved off the bus. We decided to get off as well, as it seemed like the bus was going out of service. But actually it was simply being re-routed with NO announcement as to why or where it was heading.

There was a guy in a Muni vest at the intersection directing the bus. Passengers were asking him where the 30 was going, and he wouldn’t tell them; instead he just said “it’s a long story” and “tell me where you’re going.” Well jeez, thanks a lot!

Why there was no announcement wasn’t explained. It was also not explained why there were no fliers or maps to show where the bus was being re-routed to. Or why there were no signs at bus stops.

We got back on the next 30 to try our luck. Eventually it turned out the 30 Stockton went down California and took a right at Van Ness. With a little uphill hiking we made it to our destination.

After the party
On the way back, we were again divided between the 30 Stockton and the cable car. NextBus said the 30 would come first, so we waited at the 30 stop… and watched as the cable car went by. D’oh! Finally the 30 came, but of course it was full and passed us by. We started walking, and eventually caught up with the full bus and forced our way on.

At Market St. we headed down to the Metro platform only to find that there was a problem with the “switching” or the “computer” depending on who you listened to. Or to put it another way, “we’re completely incompetent and have no clue how to run this system.” Just like every day on the Metro, basically.

I said forget it, we’re taking the F. So we went upstairs and waited at the F stop, while NextBus counted down for the arrival. And then we waited as the times started counting backwards. 8 minute way? Nope, try 9 minutes. Oh, 9 minute wait? How about 10?

It wasn’t coming. Time to head back down to the Metro platform. We made it down just in time to catch a J back to my place.

Conclusion
If anyone with any sense whatsoever was running Muni, they would spend time on outreach. Telling people what’s going on is as simple as printing up some fliers and handing them out. This isn’t rocket science.

As for the daily problems with the Metro, this system has been running for THIRTY YEARS. If you can’t figure out how to operate it by now, it’s time to either find a new vendor and/or just fire everyone and start over. There’s no excuse for having the same problem every fucking day.

If there’s one thing that’s clear, it’s that the people at the top don’t care about the people they serve.