Wrong On The Internet!

I saw a post on the internet yesterday saying that the SSE implementation of inverse square root was 4x faster than the ‘marvelous‘ method of computing it. My internal thought process was along the lines of: “Of course it is! It’s going 4 floats at a time!” and so I decided… someone on the internet MAY be wrong!

Duty Calls

So I spent an ill-advised hour or so trying to figure out how to get vector intrinsics to work with the version of GCC that I had installed.

I eventually ended up with code that generated OK-looking x86 assembly (although it does make me miss the PS3/360 vector intrinsics!):

void inv_sqrt_marvelous_sse(float* begin, float* end, float* output)
{
    v4sf onePointFiveFloat = {1.5f, 1.5f, 1.5f, 1.5f};
    v4sf zeroPointFiveFloat = {0.5f, 0.5f, 0.5f, 0.5f};
    v4si intConst = {0x5f3759df, 0x5f3759df, 0x5f3759df, 0x5f3759df};
    v4si intShift = {0x1u, 0x1u, 0x1u, 0x1u};

    union {
        v4sf f;
        v4si i;
    } x;

    v4sf *v4out = (v4sf*)output;

    for(; begin < end; begin+=4, v4out++){
        v4sf orig = *((v4sf*)begin);
        v4sf half = zeroPointFiveFloat * orig;
        x.f = half;
        x.i = intConst - (x.i >> intShift);
        *v4out = x.f * (onePointFiveFloat - half * x.f * x.f);        
    }
}

I didn’t actually get the >> operator to work: my version of gcc on Mac is a bit out of date and so doesn’t support all of the magic vector operations (despite the fact someone may be wrong, I decided that potentially breaking XCode would be taking things too far). So I subbed in a cheap nop and… those SSE implementers made that approximate inverse square root pretty fast! The marvelous version naively vectorized as above was about 2x slower with what I guess would be around an order of magnitude more error. It’d be a lot harder to tell and I’d have to use a much better benchmark than the one I was using to say for sure, but it was enough for me to concede. Regardless… go SSE!

So in this case… I was wrong on the internet! :) At least I learned a bit about gcc intrinsics along the way.

(Update: this guy went into it in much more thorough detail if you’re interested!)

(not) Working From Home

A quick look around the internet and you can come across a wide variety of people relating their experiences with working from home. The first month I was working, I’d say I was pretty much exactly as productive as I would hope. I was working more days than not, making solid progress every day.

And then my house-guests came… and it’s safe to say I haven’t done anywhere close to as much work as I’d like to.

The interesting part to me is that I probably still had the same amount of ‘possible’ work time during the week, it was just broken into smaller chunks. Which actually made it so that I was not doing anything at all. Some things work better in small manageable chunks, but programming is not one of them. I’m starting to realize I need a few hours at a time to actually make progress. Sometimes an office doesn’t look so bad… :)

Rendering text on iPhone with OpenGL

So far on my project I’ve been using SDL, a library I’ve used over the years for small projects. I use it as a quick way to get a cross-platform OpenGL context created, so I figured I’d use it in the same manner for my current game. SDL on iOS has a few quirks to work through, but if you’re using OpenGL with shaders it’s not much work to have the same code working on iOS with OpenGL ES 2.0.

One of the strengths of SDL is its lightweight and easy to use ‘standard’ libraries. I’ve used these before to get some basic sound, image loading and text rendering working. Image loading worked quite nicely (because this guy added a nicer version that uses the built in support, thanks man!), but SDL_ttf, the font renderer, relies on being able to link against FreeType, a nifty open source font rendering library. It’s certainly doable to link against it and some people have built it for iOS, but it’s a bit of a procedure and it’s yet another library to have to keep up to date.

It also seemed a bit… grating to have to use a separate library. Apple has historically placed an above average emphasis on having nice fonts and the iPhone is no exception. Its built-in font rendering lets you choose from the decent selection of built in fonts (Helvetica!) and also allows you to bring your own font to the dance. A roadblock arises when you realize you need to render the fonts to OpenGL textures and not to some mysterious UIGraphicsContext. Luckily I’m not the first one on the internet to have these concerns and I found a blog post about mixing UIKit and OpenGL.

Unfortunately his example code didn’t work for me. The code looks fine and seems straightforward and runs without error. It just wasn’t actually rendering anything into the buffer. After adding every CGContext state setting function I could find I stumbled upon a combo that sets up enough state to render with only a basic SDL OpenGL window set up. Hopefully Google will bring people here to save themselves the hour of randomly setting states to get it to render… :)

Caveats: it doesn’t word wrap, or do any other fancy tricks. For now, I’m using it to aid in debugging and provide frame times and the ilk.

//from bit twiddling hacks
inline uint32_t nextPowerOfTwo(uint32_t v)
{
    v--;
    v |= v >> 1;
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16;
    v++;
    return v;
}

GLuint CreateTextureFromText(const char* text, const sRGBA &rgba, int &out_width, int &out_height)
{    
    NSString *txt = [NSString stringWithUTF8String: text];
    UIFont *font = [UIFont fontWithName:@"Helvetica-Bold" size:16.0f];

    CGSize renderedSize = [txt sizeWithFont:font];

    const uint32_t height = nextPowerOfTwo((int)renderedSize.height); out_height = height;
    const uint32_t width = nextPowerOfTwo((int) renderedSize.width); out_width = width;
    const int bitsPerElement = 8;
    int sizeInBytes = height*width*4;
    int texturePitch = width*4;
    uint8_t *data = new uint8_t[sizeInBytes];
    memset(data, 0x00, sizeInBytes);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGContextRef context = CGBitmapContextCreate(data, width, height, bitsPerElement, texturePitch, colorSpace, kCGImageAlphaPremultipliedLast);

    CGContextSetTextDrawingMode(context, kCGTextFillStroke);

    float components[4] = { rgba.r, rgba.g, rgba.b, rgba.a };
    CGColorRef color = CGColorCreate(colorSpace, components);
    CGContextSetStrokeColorWithColor(context, color);    
    CGContextSetFillColorWithColor(context, color);
    CGColorRelease(color);    
    CGContextTranslateCTM(context, 0.0f, height);
    CGContextScaleCTM(context, 1.0f, -1.0f);

    UIGraphicsPushContext(context);

    [txt drawInRect:CGRectMake(0, 0, width, height) withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft];

    UIGraphicsPopContext();

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);    

    GLuint textureID;
    glGenTextures(1, &textureID);    

    glBindTexture(GL_TEXTURE_2D, textureID);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);     

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);

    delete [] data;

    return textureID;
}

You generally don’t want to be creating textures very often, so you’ll want to have some sort of caching for the texture ID that’s being returned.

A few people wrote me to ask for more details about using the texture that’s returned. It’s just a normal quad with the dimensions given by the out_width and out_height parameters. I made a simple C++ class header that should get your most of the way. If you include this header in a .mm file, create the class after your OpenGL initialization and bind a shader which has texturing, it should™ render your text! It requires you to be using OpenGL ES 2.0. I’ve also as of 2013 updated it to use the iOS 6.0 text alignment enums as XCode was complaining.

simplerender.h

Here we go!

Mmm… a blog!

I haven’t had a website to actually write on for awhile. I’ve gotten lazy in my old age… my first website was back in junior high and it remained updated for nearly a month I think. Ahhhh the good old days, when under-construction gifs littered abandoned websites instead of comment spam.

However in a stunning blow to nostalgia, the days today seem pretty good! I woke up at the mostly respectable time of 11 AM and ate my shreddies on the stairs in the backyard. I have already beaten the internet at least twice today, so I’m ahead of schedule. And I’m finally writing this first blog post, which has been on my todo list for a week now.

So! What’s this blog going to be? Well the plan as it stands is for it to be where I share news about the project I’m working on. I quit my job of five years at EA Montreal in June, wandered around Europe for a month or two, and am now happily plugging away on a game of my own. I won’t go into it in this first post, but the goal is to put something I’m proud of out on the App Store; sooner rather than later. Maybe it will make money, maybe it won’t, but I’ve already learned a lot and am generally having fun doing it.

I’ll either run out of money or get bored. We’ll see which happens first… :)