Category Archives: Coding

Simple billboard orientation in world space

I had a great deal of difficulty in working out how to do billboards properly, simply because I don’t have the mental agility to handle the descriptions usually given in 3D programming tutorials. The method I’ve managed to figure out is related to gluLookAt: and uses a similar method to work out the rotation matrix needed to map one vector to another.

Here’s how the process works:
Continue reading Simple billboard orientation in world space

LOD

More LOD than you can shake a STICK at
Procedurally generated terrain

I think I’ve come up with a new definition for “optimisation” in the context of writing a 3D engine, where it means “to painstakingly claw back some of your frame budget, and then immediately blow it on a new engine feature”. Hence the above looks pretty but currently runs at 10 frames per second on a SNB Core i5 MacBook Air.

New features include LOD-heavy instanced grass rendering, deferred lighting, cloud shadows and BLOOOOOOOOOOOM. Once I’ve “optimised” those features as well, I’ll do some write-ups – the instanced rendering method using matrix buffers which I picked up here is particularly cool.

Fast Enumeration, Massive Inefficiency

Cocoa makes use of a system called Fast Enumeration, which allows you to write array loops in a compact fashion and is also supposed to speed things up by getting [myArray nextObject] rather than getting [myArray objectAtIndex:nextIndex] on each pass through the loop. Here’s an example:

for (NSObject *anObject in myArrayOfObjects) {
    //do stuff
}

Because I’m an idiot, I had been using Fast Enumeration in situations where I needed to know the index of each object because I couldn’t be bothered to write out the code for incrementing an index. This resulted in incredibly readable stuff like the excrescence below:

for (NSObject *anObject in myArrayOfObjects) {
    if ([myArrayOfObjects indexOfObject:anObject] < ([myArrayOfObjects count] - 1) {
        NSObject *theNextObject = [myArrayOfObjects objectAtIndex:([myArrayOfObjects indexOfObject:anObject] + 1)];
        [self doSomethingWithObject:anObject andNextObject:theNextObject];
    }
}

In case your eyes are bleeding too much for you to be able to see how hard I’ve made things for myself, here’s a rundown of what the above code actually does:
Continue reading Fast Enumeration, Massive Inefficiency

Dealing with .csv files in Cocoa – writing an importer

Mac users who need to deal with large amounts of data might justifiably feel like they got the short end of the stick as far as Microsoft Office is concerned. The Mac version of Excel doesn’t support Visual Basic and isn’t multithreaded, meaning that:

a) as soon as you get above a couple of tens of thousands of rows, any formula more complicated than summing a column freezes the UI for a couple of minutes while it crunches the numbers, and

b) any data analysis you want to do which involves iteration results in formulae consisting of ten lines of densely nested brackets, which are nearly impossible to read or debug.

Like any bad programmer, I implicitly believe that my language of choice is the perfect tool for any job, and hence when recently confronted with a very large stack of data I needed to analyse I decided it would be easiest to Object Oriented the hell out of it with a small custom C application.

Continue reading Dealing with .csv files in Cocoa – writing an importer

NSDocument saving quirks

Let’s say you have a document-based application which worked fine under Leopard/Snow Leopard.  Each document is backed by an XML store, and hence the saving method works by exporting the contents of a number of NSTextViews into one string of XML, which is saved to disk.  You’ve been happily overriding

- (BOOL)saveToURL:(NSURL *)url ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation error:(NSError **)outError

as being a sensible point to insert your custom document-saving code – in my case, I send the NSString which holds all of the document’s data to a basic XML exporter, which does clever stuff like removing all of the illegal characters, etc.  You then use NSString’s writeToURL: atomically:encoding:error method to do the actual write.  This works fine pre-Lion.

Everything goes swimmingly until you upgrade to Lion/Mountain Lion and try to save the document in place (i.e. save rather than save as:).  Your application pops up a warning sheet saying “This document’s file has been changed by another application since you opened or saved it.

Every.  Single.  Time.

Workaround: give your application a file wrapper so that you can add some metadata, and you can trick your application into realising that the file hasn’t been altered after all. You can do this by overriding NSDocument’s fileWrapperOfType: method rather than saveToURL. This is from an application for writing questions and answers to an XML file which is then used as the data source for a quiz application, hence the funny QuestionExporter/setQuizDocument object and setter:

- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {
    QuestionExporter *exporter = [[QuestionExporter alloc]init];
    [exporter setQuizDocument:self];
    NSString *xmlString = [exporter exportQuestionsToString];
    NSFileWrapper *wrapper = [[NSFileWrapper alloc]initRegularFileWithContents:[xmlString dataUsingEncoding:NSUTF8StringEncoding]];
    return wrapper;
}

Lies, damn lies and GL_MAX_TEXTURE_UNITS

Warning: this post contains much bitching, only some of which is substantiated, and much of which probably only applies to Intel integrated graphics

So, I guess you could probably point out that I’m being a bit melodramatic and that, essentially, anybody who tries to do much in the way of multitexturing using integrated graphics gets what they deserve.

However, you may find it useful to know that, despite OpenGL telling you that you have 48 texture units available, don’t, under any circumstances, try to actually use all of them. In fact, you’re playing fast-and-loose if you even try to use some. It might seem logical to you, as an OpenGL novice, to write your code so that each texture unit is only used in one of your shaders and is reserved for a particular texture function; say, I have a shader for drawing grass, to I bind my grass texture to GL_TEXTURE23, set my sampler uniform to use that texture unit, and call it a day.

Don’t do that.

In my testing, again on pretty limited integrated hardware, I halved my drawing time by using a total of less than 8 texture units and binding textures as required. This includes the fact that I use GL_TEXTURE0 both for a material’s main texture in the first pass, and for doing post-processing on the entire framebuffer in a later pass.

In short – “fewer texture units used” trumps “fewer texture binds” every time, when using limited hardware.

Two dimensional C arrays – care and feeding

C arrays are a little hard to grasp by those of us raised on the Cocoa API, because most of the really convenient stuff (like an array object being able to keep track of its own size) just isn’t there in straight C.  I went into using C arrays, in order to interact with OpenGL, with absolutely no knowledge whatsoever (a common theme of this site!) of how to even use malloc.

Why would you want to use two-dimensional arrays anyway?  In my case, although I’ve written a fair few functions where e.g. a two-dimensional grid of points is mapped to a long one-dimensional array, and I’ve simply remembered what the dimensions of the grid were when accessing the information, sometimes this is simply too much for my poor brain to understand. In this situation I’m forced to represent things as a multidimensional array in order to get the concepts down in a way which works.  I might, therefore, have one array which represents all of the values of the x dimension, containing a series of arrays which represent the y dimension; so the point in the grid at (5, 13) is retrieved by getting the 13th value from the 5th subarray in the parent array.

Fortunately there are people who are much cleverer than me who have come up with a way of handling two-dimensional C-arrays.  Unfortunately I have forgotten the attribution.  However, I had to go forum-diving to find this and I think that it might be helpful for us inexperienced types to have a more easily-searched solution.  If I find the original source again, I will provide a link.

One similar implementation was found here

//make a 2d array of floats
 
float** Make2DFloatArray(long lengthMainArray, long lengthSubArray) {
    float **newArray = (float **) malloc(lengthMainArray * sizeof(float *));
    *newArray = malloc(lengthMainArray * lengthSubArray * sizeof(float));
    for (int i = 0; i &lt; lengthMainArray; i++) {
        newArray[i] = *newArray + i * lengthSubArray;
    }
    return newArray;
}
 
//release a 2d array of floats
 
void free2DFloatArray (float **arrayToFree) {
    free(*arrayToFree);
    free(arrayToFree);
}
 
//access a value in the 2d array
 
float theFloatIWant = my2DFloatArray[indexInMainArray][indexInSubArray];

Sorting objects into an array of NSArrays

This one is pretty simple, but I had a terrible amount of difficulty working out how to do this the first time.  Cocoa makes a lot of this process pretty easy by providing the NSMutableArray class – the only real gotcha with an NSMutableArray is the “object was mutated while being enumerated” problem.  This means exactly what it says – you’ve removed an object in the array while enumerating (going through the objects one by one) the same array.  The usual workaround is to create intermediate arrays with lists of objects to delete and then enumerate over the intermediate and commit changes to your NSMutableArray.

NSArrays can only contain objects; if you want to store ints, floats etc. then you are going to need to encapsulate them in an NSObject of some sort (e.g. in this case, an NSNumber would be a suitable fit).  All of the objects in an NSArray need to be of the same class.

Say I want to make a very simple hierarchical data store which will provide the data for part of the user interface for an app; for example, a UITableView.  I want my tableView to have sections which are organised by date – you can see this sort of arrangement in, for example, email programs which sort your incoming mail by Today, Yesterday, Last Week, etc.  One simple way to do this is to establish a hierarchical structure of arrays, like so:

Master array       –> section array –> content object

–> section array (empty)

–> section array –> content object

–> content object
–> content object

Continue reading Sorting objects into an array of NSArrays

Hello world!

Those (few) of us who got our start in graphics coding in OS X have probably noticed a few wrinkles in the process:

  • Apple’s OpenGL/GLSL implementation is always a year or two out of date
  • OpenGL tutorials on the internet are always 5 years out of date, and actually written for DirectX anyway
  • Books on the subject cost £50 for a hard-to-search collection of stuff you already knew which is inevitably dependant on some library or other (which they don’t explain) to do all of the magic
  • GLSL is, as Shamus Young so rightly pointed out, folk knowledge
  • As soon as you want to interact with OpenGL, you have to leave your cosy Cocoa haven and delve into straight C – which is moon language to those of us raised on NSExtremelyVerboseFunctionNameWithAttributes:

Hence I’ve made this site to put up some of the more obscure – or so obvious nobody has ever bothered to put up a working implementation for us newbies to pore over – code which took me hours of googling to figure out.  It’s so much easier to learm by breaking a working implementation than to mess about with something originally written in a different language which might not even work in the first place.

In the process, I’m going to build one of those procedural environment things.  This was going to be a simple 2D Artificial Stupidity project, but the graphics sort of took over.

There will be bugs.  There will definitely be memory leaks.  Much of this stuff will be apocryphal, or at least wildly inaccurate.  Your video card will probably crash at some point, and I’m definitely not going to buy you a new one.

Enjoy!