I’ve been doing a fair bit of GL ES coding recently for our upcoming more graphically advanced iPhone titles.
It’s been good fun (on the whole!) even though integrating GL ES with our multi-platform render backend has possibly exposed that our long established flexible render interface doesn’t allow for certain optimisations without introducing certain restrictions (we did encounter the same thing on PS2 but it’s probably a topic for another day).
One nice and simple method for working on optimisation of usage of an API is to use wrapper functions. In terms of graphics API programs such as PIX, gDebugger and other 3D analysis/ripping tools are (for the most part) intercepting the function calls from the application and then interpreting the data themselves in a similar way.
We’ve been doing a similar thing when debugging API usage in the past and it seems a popular technique as I saw John Carmack using a similar simple GL wrapper in his Wolf 3d code (and he had a nice additional idea I’ll mention below).
The idea works by having a private header file in your own middleware or in your game which you include in every file you would use GL or other wrapped API from (or just include it in a global header if you wish).
Inside the header file you’ll have a structure like :-
// Wrap settings, uncomment these to enable.
// helper macros
# define DO_ERR_CHECK_GL(x) CheckGLError(x)
# define DO_ERR_CHECK_GL(x) (void)(x)
// wrapped implementations
// wrapping enabled, implement each function to be wrapped
static inline void _glDepthFunc(GLenum func)
lLogSys(“GLES”, “glDepthFunc(func=%s)\n”, GLenumToString( func ));
// call the actual function
// Use preprocessor to force any references to the unwrapped function to cause a compiler error (idea from Wolf3D code, nice way to catch!)
#define glDepthFunc ERROR_USE_WRAPPED_VERSION_OF_glDepthFunc
// wrapping disabled, use pre-processor to point to actual functions
#define _glDepthFunc glDepthFunc
This implementation is done for every function that you wish to wrap in the particular API.
In the above example we can perform whatever logging we want about each function call, using helper functions we can translate things like enums to human readable strings for output to HTML or other log file. Texture data can be intercepted in glTexImage2D calls and then stored out for future reference in the log (by associating it with the correct texture ref), likewise for shader programs.
Also above we perform a call to an error checking function if the relevant #define setting is set at the top of the file, this CheckGLError function takes the string name of the wrapped function it Is called from, performs a glGetError, checks its validity and then logs / spawns a debugger depending on other current settings.
The possibilities though aren’t limited to that..
There is the ability to add redundant call checking by storing the previous value that was passed to a particular function, in the above case we can track the current internal GL setting for glDepthFunc (this works on the assumption that no other piece of code could somehow set this and break our redundancy checks – in our case we know that all our code is wrapped). Some functions are harder to track redundant state sets for but if you focus on making the code re-useable you’ll find several functions in APIs have similar usage / internal state patterns .
Another feature I added to our internal wrappers was a GL call limit, at the top of each wrapper function a call (again to a function hidden by a #define MACRO meaning it could be easily disabled and compiled out of the code). The function that the macro called would return a bool of whether to continue execution of that wrapped function. This allowed me to have a ‘stop GL functions after xxx have been called’ function, I was able to trace using a simple interface in-game where certain rendering issues where introduced and also look at draw order very easily.
Related to that is overriding of certain states, because you can stop any state being set you can force things like texture sets to not go through (or to keep the texture set to a 1×1 dummy texture to test texture bandwidth impact on your framerate) or perhaps to override the colour of each batch passed to the renderer (I’m ignoring shaders in that example but again you could override a shader if you wished).
Implementing this system wasn’t something that took very long though and it can be very useful depending on what stage of development you’re at. It’s important to spend time working out how to minimise the effort needed for each wrapper function, I think the redundancy checking could be wrapped up nicely through some well thought out template usage and the whole thing could be done via more pre-processor macros to minimise typing errors (and to improve readability).
Hopefully this idea will come in use for your API debugging / logging / optimisation work!
Things we’ve been enjoying this week
- A great post with links to all you need to know on the Kinect ‘hacking’ people have been doing. I got the code compiling on Win32 when it was first being ported to libusb-win32 but haven’t had chance to do much with it since (other than hook it up to our engine). Looking forward to seeing interesting stuff from this, markerless motion capture already starting to emerge.
A slightly technical (but shorter) post tonight as it’s been a busy week of projects, various talks and meetings!
I’ve been working on optimisations on a title we’re finishing up at the moment and matrix multiplies was one area I knew needed optimising.
There have been a couple of developers (links near the bottom of the post) talking about optimising for the VFP and NEON vector processing extensions over the last few years so I was aware that the savings were significant. We’d simply not had to use these optimisations within our own math library code before now.
I’ve also recently heard a bit about Accelerate framework from WWDC so thought I’d have a look at that but my main worry was how calling a library function would avoid function call overhead (at least without fancy linker features removing such overhead).
I thought it would be interesting to do a post looking at rough timings of an operation using the various options we have.
I decided to choose the fairly common 4×4 matrix multiply. As I mentioned these timings are fairly rough, I simply set up loops to perform 100,000 matrix multiplies and (separately from the timed code) ensured results came out the same.
C (direct) is a call to a function that looks a lot like
void lSIMD_Base::Matrix4x4Mul( float * r, const float * a, const float * b )
r = (a*b) + (a*b) + (a*b) + (a*b);
C (indirect)is the same function via an operator* in our matrix class, I wanted to see at the same time whether the temporary matrix and function call were being optimised out on GCC.
VFP is a call to the vfpmathlibrary Matrix4Mul implementation. Note this is a column major matrix mul whereas the others in this rough test are row major.
NEON is code based off a post on Wolfgang Engels comments on his blog
CBLAS is BLAS Accelerate framework in iOS4.0 and above, as you’ll see we’re only going to get a result on OS4.0 and above devices.
The code was compiled using the current 4.2 SDK with the current GCC based Xcode with Thumb disabled and in default release mode (-Os I believe is the default optimisation level).
|Device / OS version
|iPhone 4 (4.1)
|iPhone 3GS (4.0.2)
|iPod v3 (3.1.3)
|iPhone 3G (3.1.2)
|iPod v1 (3.1.2)
I’ll try and remember to come back to update this table as I update OS versions and try new things!
The timings are roughly as you’d expect (though I’m not sure the 3G results should be quite that slow – I think the device is on its way out to be honest!). The Accelerate framework is a bit of a disappointment but this is mainly due to call overhead I believe, the WWDC presentation certainly had much better results for other operations and with larger operations such as a Fast Fourier Transform the call overhead becomes a much smaller % overhead of the operation you’re trying to perform. I need to try out some more things with Accelerate as I’m not sure it should be this slow.
As expected NEON is faster on the ARMv7 chips and VFP is faster on the ARMv6 chips, NEON is 10x faster than the C implementation which is quite impressive.
The chart also acts as quite a nice example of general chip speed, I incorrectly believed the iPhone 4 CPU to be faster than the iPads before seeing these results.
As promised here are some useful links relating to the above
Noel Llopis talking about floating point performance a few years ago
Wolfgang Engel’s original post on the VFP Math Library
The VFP math library itself
I believe this will be the same version here in Oolong as well as NEON implementations based off the comments posts on Wolfgangs blog.
NEON intrinsics guide
Math neon library – extensive math library implementation for NEON (LGPL)
‘iPhone VFP for n00bs’ – also covers some basics of using inline assembly on GCC
A blog at arm.com on matrix multiplication with NEON
Accelerate framework slide from WWDC 2010
- available via iOS developer centre
Things we’ve been enjoying this week
- I think on the launch titles Move is just winning for us but Kinect is interesting and I’m looking forward to seeing what comes out of the Kinect hacking going on now the open source drivers are out.
- 4k demoscene intro with code, should be interesting!
- Working 8-bit CPU in Minecraft
- Related to this blog post, efficient C code for ARM devices
- Awesome resource of 3d models intended for artists to texture and light, should be very nice looking test assets for any tech tests though!
I had been working on a bit more of a technical piece for this week but unfortunately encountered a few problems during testing on it and didn’t get as much time in front of the Mac as I wanted in the evening this week.
Instead I’m going to throw a few of the pros / cons I see with the 99c / 59p price point.
We current have a sale active on two of our apps You Are The Ref down to $1.99 from $2.99 and QuizQuizQuiz down from $1.99 to 99c. YATR is relatively new, being featured by Apple in its football (soccer) games section and Game Center ‘Hot New Games’ and QQQ is now 13 months old but still normally in the top 25 (if not top 10) trivia charts across Europe (and still nowhere in the US chart!!).
- Will generally result in a higher chart position, top 10 is predominantly 59p apps. Being high up the charts (or any particular category chart to a lesser extent) exposes you to the daily new registrations of devices who will instantly look in those places for their first apps.
- Likewise a higher chart position is likely to get the App Store gods to notice you and feature your game – it could be argued however that they probably watch the grossing charts more than the standard ‘sales’ (I’m not sure what the current formula is made up of ratings / sales wise) chart.
- More people buying your game will increase the viral spread of your game assuming those people have a positive experience and it has a ‘show off’ feature that people will be keen to show others (an important part of the viral spread).
- Once you’ve gone to 99c even as a short-term sale people will assume that you’ll drop your price again and perhaps wait till you do so. The only way to perhaps fight this would be to only do it as a launch sale. If you’ve added more content which you believe justifies NOT dropping back down to 99c that’s fine but how do you actually communicate that to people who haven’t bought your game?
- Lower pricing tends to equate to lower ratings especially on apps that aren’t top sellers. As always it’s very important to encourage people to rate the app (especially at good times during gameplay, say just after they’ve unlocked a new level or got a new highscore!).
- The normal criticism about apps pricing themselves at 99c is that the content producer appears to be valuing their content incredibly low, this is based around the suggestion that ‘price sends a signal’ to the consumer (http://www.joelonsoftware.com/items/2005/11/18.html). Of course 99c on the Apple Store isn’t necessarily the same as 99c in the real world or on other stores though – I’ll discuss this a bit more below.
- While talking about value there’s also a risk that being if you’re at a partially successful 99c game you will be compared to Angry Birds and other top selling 99c apps and the value they offer. These apps are selling such huge quantities that they’re also able to easily further increase their value over time through new levels and updates further stretching the expectation for the gamers who only buy 99c apps from the top charts.
- Not making as much money as you could, this is of course a big concern and you’ll never actually know whether you could have made much more money and have had a higher league position at $1.99.
We’re entering (if we’ve not already entered) an interesting time with all these app stores opening (and other digital distribution platforms such as STEAM, PSN/PSP Minis, DSi, WiiWare etc..). Some news articles make a lot of the price differences between various platforms for the same game and of course value for money is a big issue in the current economic climate. For developers however there are differing costs on each platform (ratings cost, development kits, pure porting time via art differences or technical requirements), a different market size and type of demographic. Some platforms also have imposed pricing structures from the powers that be.
Looking at some of the big names across the various platforms an ‘exchange rate’ could be worked out and may be of use to other developers looking at deciding on their price on a particular platform.
As we begin to move QuizQuizQuiz across to various platforms (Windows Phone 7 now at $2.99) we’ll be thinking about this issue a lot more.
Of course in the ideal future we’d have some sort of universal purchase system where users could buy an app / game once and it then runs on every platform, even though someone in the chain is likely to lose out on this (the hardware manufacturers relying on you being tied to your existing paid for apps probably) and of course total spend per user will likely be less. As a consumer it is a very appealing proposition though and we’re already seeing movies move towards multi-platform delivery (DVD/Bluray/Digital copy in the same box at a higher price!)
I’m hoping to talk more about pricing in the future with a few more stats to back things up, thanks for reading and please post any thoughts you have on the 99c price point and how you see the market going.
Things we’ve been enjoying this week
- ‘Radio for YouTube’ – finds related videos to a keyword and plays them Pandora / last.fm style. I may get addicted to this.
I’ve been away on holiday this week and despite trying to switch off for at least a little bit I’ve been doing a bit of thinking about our projects new + old.
It seemed appropriate to talk a little about my favourite brainstorming tips. As with most idea generation / thinking / processing techniques the things that work best vary between individuals but hopefully some of these may be of use or may encourage you to think about how your brain can be optimised!
Set yourself a specific question
- Much like when prototyping and aiming to answer a question, state the problem that you want to think around clearly, this gives you an easy way to assess whether you’re done and also keeps you focused on the main purpose that you started on. Of course the specific question could be a very broad subject with a huge spectrum of answers but writing down the question at the top of your piece of paper / OneNote page / middle of your mindmap is a great starting point I find.
Set your targets
- This isn’t something I do that often to be honest but is a good tip I’ve seen recommended, my target tends to be to come up with an idea (or 5!.. Or 10!) that I’m happy with in a certain timeframe rather than setting constraints of certain number of ideas generated.
Blitz your brain
- You may already fully understand the question domain when you start brainstorming about it so this may not be needed but if it’s an area you don’t work in regularly or if you want to be aware of all the latest facts (especially when thinking about game ideas / marketing) I tend to Google for a while and check my RSS feeds for every related (even slightly related) article and skim read them before starting the brainstorming. I also cheat slightly in that I tend to write down early ideas at this stage sometimes.
Focus / Flow
- Vital for any type of serious thinking, for getting into ‘flow’ I tend to get some fast music with no lyrics (or just any kind of noise to be honest) to drown out distractions much like I do when working on code for long stints.
- Generally for brainstorming I produce a mind map though I tend to not worry about how ideas are connected that much till after I’ve finished writing (or typing) ideas down. I used to always use Mindmapping software for idea generation on computer but I’ve fallen out of the habit and tend to use OneNote for most things now, I still structure my thoughts in a hierarchy but it’s less spread out (OneNote does support putting notes anywhere on a page though)
Summary / Re-organise
- After the initial pass writing ideas down I tend to go through and review them. This involves de-duplicating ideas, possibly an initial ranking of them, perhaps categorising the ideas. I tend to discover new links between ideas at this stage and this can sometimes be the really creative part of the process.
That’s my basic process for brainstorming, it was actually a harder thing to describe than I thought it would be – perhaps I should have brainstormed brainstorming a bit further (hoho!).
There are lots of other tips and tricks like these on the web if you use your Google skills but a couple of books I’d strongly recommend are
- Pragmatic Thinking & Learning
- An interesting look at how we process problems and also looks at left / right brain thinking. Talks about the idea of optimising your brain for the tasks software developers (and other creative people) face.
- The Art of Game Design by Jesse Schell
- Covers some great brainstorming tips from Jesse, my favourite of which is playing with clay or other toys to keep your mind playful as you think. This is also just a brilliant book and I would recommend to anyone.
And one particular website I thought of around this kind of thing is
- Subscribe to an RSS feed on this, not a big fan of the site look/layout but some of the content is great.
Things we’ve been enjoying this week
I’ve been thinking this week about young people looking to get into the games industry, this is mainly as we’ve had a couple of really great work experience students working with us in the office and also I’ve been doing a couple of talks at schools in our area.
I wanted to make games from the moment I got my first computer at 5/6 years old and was lucky enough to be able to teach myself BASIC through to C++ as I grow up first with the CPC and then early PCs and the internet in the very early 90s (IRC, the demoscene, newsgroups).
It’s always interesting to think about how we’re going to educate people wanting to join the industry and also what to say to young people asking what their best path would be.
The current popular path (based on CVs we receive – for programmers) is a games development course at University, in some cases with a computing course in the final years of high school perhaps covering Visual Basic or perhaps Java. For the most part though these people tend to be writing their first line of code only 3/4 years before entering the industry.
I want to say there are still people learning and coding at a much younger age (certainly the 15 year old student we had work with us this week has been programming in Flash/AS/PHP a while and was keen to learn C++ and Lua with us).
I’d like to look at a current state of play for young people wanting to learn to develop games (this has a programming tint to it apologies). I’m going to try and come up with good / bad points on the various areas to balance things out against how I found things while learning.
Obviously a massive resource of everything games development / programming related over the last 20 years, very cheap to access (even if that happens to be at a public facility like a school or library) and available everywhere with modern mobile devices.
- Access to free tools (GCC, XNA, Unity, Python, Lua, everything Open Source), tutorials and Q&A, features on games development.
- A huge community of other people learning and wanting to collaborate on projects and to encourage others.
- The ability to publish and make money via digital distribution.
- Copy + Paste culture is encouraged, googling a particular problem is likely to come up with working code and I’ve spoken to people currently learning programming admit that they’ve copied code without completely understanding what it was doing. In that particular case when they later had problems with that code they learnt the lesson about actually understanding everything they add to their project but I think we all know of people relying on Google way too much.
- Other distractions on the internet! WoW and online gaming (Minecraft!) not to mention Facebook procrastination. I used to pay for every minute of internet access so I made sure I spent my time well when online
When I was learning to program there were still lots of languages but I had to purchase compilers via shareware discs (charged per disc) so I stuck to Assembler + C. My first language was BASIC. Nowadays there is a huge variety of languages to choose from as a new programmer (despite C++ still being the primary development platform).
- Huge amount of choice is good in that people can find something that fits with their understanding or that provides the easiest learning experience. Once you have mastered one language moving to others is a lot simpler process.
- Experiencing different styles, concepts and patterns is good for your overall programming knowledge and helps you apply the best tool for the job.
- Choosing a bad language (in terms of your career) and sticking with it. This can make you end up with a set of portfolio apps that bear little relevance to the industry.
- Not mastering one particular language and just having an ok understanding of several may not help in terms of applying for jobs.
This is an area I don’t have a huge personal experience with, I planned to go into university education as a path into the industry but was fortunate enough to be offered a great job and felt that experience was worth more than education anyway (which I still believe funnily enough!).
From the point of view as a recruiter though :-
- University courses are constantly improving and in the UK at least there are moves by government and trade associations to link industry to academia.
- Industry experts are actually working more closely with universities in terms of guest lectures and we’re seeing a lot of industry veterans moving into teaching.
- I’ve seen signs of some programming being taught later on in high school and apparently LOGO Turtles are still used in primary education (controllable robots via a simple movement / pen drawing interface).
- At university level there still seem to be a lot of formerly ‘media production’ courses that are just being renamed to ‘Games development’ just to get the numbers on the courses up.
- I’d really like there to be more focus on programming / logic development at a younger age, technology is everywhere in young peoples lives and a better understanding of the logic (whether it’s through simple electronic teachings or focused on programming) would be great.
There are a huge amount of platforms and genres available now.
- There are truly games for everyone whether you prefer social games on PC, motion controller based party games or more traditional hardcore FPS games. This gives us a bigger audience of young people wanting to get into games – which hopefully includes more female developers as well as males who wouldn’t previously have been interested in games development.
- Successful (simpler) iPhone titles can be seen by people as something they could feasibly make themselves given enough time.
- I’m not sure how much of a problem this is but modern AAA games are so big with such huge budgets that perhaps getting involved with the development of them may feel out of reach to them.
Modern computers / Operating systems
This is the usual reason that gets discussed with learning programming now versus 20 or so years ago.
On pretty much every platform you were first presented with a command prompt of some kind and even running a game from disc / tape required you to enter a command. Most users nowadays wouldn’t even know about the command line let alone understand any of the goings on behind the applications they work with. The bad points to this are kind of obvious but at the same time without this uninviting command prompt (to the majority of the public) home computers have grown in popularity to make the industry what it is today.
This is by no means a full analysis of the state of things but just a few areas I’ve been thinking about, young people with the determination can easily develop their skills quickly and they have access to many experienced professionals and equally intelligent amateur developers via the internet. With better education the future should be bright for the new talent entering the industry both in terms of AAA studios and the independent teams.
Things we’ve been enjoying this week