Skip to content

Archive

Tag: iTouch

Hairlock - dev picUpdate: Antistar 3D: Rising is now available on the app store!

Why is a 13 year old dreaming of metal cities?
What lies in the dark forest beyond Klinnburg?

Anticipating the success of the Twin Star Saga,
Antistar 3D offers stylish anime action and adventure.

>> Watch the video
>> More screenshots

Join the buzz or check discussions on Touch-Arcade forums.

With an exciting title putting experienced and new players on fair ground, we’ve just proven that mobile entertainment owes nothing to game-boxes:

Hairlock - dev pic

  • Realtime, fullscreen interactive 3D
  • Unique mix of adventure and arcade
  • Unexpected allies and opponents
  • innovative ‘no grind’ gameplay
  • An original cast of haunting, magic creatures.

From the quaint emptiness of a marooned village to a mice gang’s lair, become a child without memories,
armed with only courage and a forward attitude to solving life’s little annoyances – not having a clue what’s going on, not having a chance against oversize wildlife and getting captured by really bad guys.

With procedural landscapes, three dimensional growth and beautifully detailed models,
Antistar 3D: Rising pushes the limits of 3D on mobile platforms and will seamlessly adapt to your device’s capabilities.

Main Contributors: T.E.A de Souza, Chan Zhang, Karen Xu; Music: Matt Hansen (Calpomatt), Justin R. Durban (Edgen), Mark. SFX: Mark E Buckland, Robert Gacek (FXProSound), Joel Carli, Sith Master, Starmanltd, The_lone1, T$_Technologies.

Antistar 3D: Rising will be distributed as a universal app taking advantage of all device’s capabilities:

  • Basic rendering optimized to run smoothly on iTouch
  • Antialiasing (iPhone 3GS)
  • Retina Display (x1.5 iTouch definition 3D view)
  • 1004×768 full-screen on iPad

Visit the product homepage for a quick description.

On a mobile platform, memory is to be considered seriously. Unlike a desktop PC where we have 2, 4 (8?) GB to live on, the general feeling about the earlier iPhone and iTouch is that we have around 20MB to play with. Tiny sandbox.

The bottom line

If you start with one of the iPhone OS templates/examples, you likely have a view controller with an empty method like this:

- (void)didReceiveMemoryWarning {}

The bottom line is that it seems safer to arrange that your app does not trigger a memory warning under normal usage conditions. I haven’t really seen this written anywhere, just commonsense, where normal conditions would mean:

  • You haven’t just rebooted the device. If you’ve just rebooted, you are in ‘perfect conditions’. At the moment I tested my app and it triggers the memory warning 12 times or so. If I reboot and perform the same test, the warning never gets called.
  • You are not testing right after another app has crashed. Maybe this makes no difference, but it feels like abnormal conditions.
  • Your test involves normal gameplay, and lasts for the maximum expected duration for a play session.
  • You are testing on the tightest configuration possible (e.g. iTouch 2nd gen, 8GB, running OS4)

You can ‘recover’ from a memory warning – maybe you just need to free enough memory, and since my app did not crash after receiving 12 memory warnings, you might even think it’s OK. Now, do you really want to be running on the edge of disaster? I don’t think so.

What Instruments say

When I get a memory warning, instruments are displaying memory as follows:

  • 30 MB (process allocation) in Activity Monitor
  • 20 MB (live bytes) used by my process in ObjectAlloc

These values are consistent with the rumored 20MB, and also consistent with repeated complaints that different instruments provide different values. ObjectAlloc measures  live bytes – memory used by an app; activity monitor measures (a variable amount of) memory allocated to a process. I tend to give more consideration to what ObjectAlloc says, because this is easier to understand, easier to predict and easier to control. There are additional conditions that will cause a process to use more memory:

  • If we keep allocating / deallocating blocks of various sizes, we fragment memory and promote semi-transient waste.
  • It may be nearly impossible not to leak any memory over time (especially if we need a system library that leaks memory). Leaked memory is lost forever, and won’t show in ObjectAlloc.

So what do we need to do?

I am targeting 15MB max as peak allocation in ObjectAlloc. I think it should be possible to play my game end to end without exceeding this value and use this as ‘maximum expected play session duration’. I have fixed all known and known to be fixable memory leaks in my product; I want to have a go and try to find out if I can work around leaks in system libraries. I don’t expect to be able to fix all of them.

I have implemented didReceiveMemoryWarning – so I have a mechanism to release unused resources. Once we’ve done that, we want to release resources more often, so we stay under the maximum we choose (in my case 15MB). If we’re really tight, we might want to arrange assets to be lighter (e.g. use models with a lower poly count if we’re talking 3D apps)

A quick case study

My game is a 3D game. the bundle is about 17MB worth of data, including 1MB worth of code. I’m not using textures; I’m loading models on the fly, so I have no loading times.

I have two problems:

  • Except procedurally generated geometry, my allocations never expire unless a warning triggers the release mechanism
  • Most resources reload almost immediately. Why? because I test bounds for visibility (and other things). However bounds are not stored in separate files. In fact bounds are evaluated when an object loads. While the processing overhead is negligible, bounding boxes are released along with geometry.

If it was to do all over again, I might just store bounds separately. This might help deferring loading an object, so my ‘loading time’ for a stage would drop from about 1 second to nearly nothing – or maybe not – at the moment it doesn’t even seem asset loading is the main cost in scene setup.

As it stands, I am not doing it all over again; instead I want to retain bounds when I release assets, and release assets in a timely manner. While I’m doing this I also want to never release geometry that needs be displayed at the next frame. My resource release mechanism doesn’t know about that.

How to know when a resource is ready to be released?

In my rendering loop, there is a procedure that checks whether objects are likely to enter the viewing range. This is a quick and dirty way to skim the complete list of objects in the 3D scene. This procedure gets called less often than a regular visibility check – so the renderer needn’t check all the scene all the time (there are significantly better ways to code this).

So my first idea is, use a skip count. If an object hasn’t entered the near range for a while, we’re OK to release. I wouldn’t set the skip count too low – no need to release resources to often, as whenever we reallocate them, we actually incur memory (fragmentation) and performance (loading) overheads.

It looks good enough, nothing super-clever but OK. But… there is a catch.

Surely geometry is shared – in my implementation, Element is just a token representing an instance of an Object3D – shared geometry reused over and over. That’s where reference count comes in play, right? Whenever an Element instance determines that it doesn’t need its geometry, it releases its instance of Object3D and when the reference count reaches zero, Object3D gets deallocated, correct?

geometry is also mapped from file paths. So when a new element is created, we get the model from the map. Needless to say the map is also retaining each object once. As it is, all elements may release their instance of a geometry object, the map won’t know about it and we still haven’t got the geometry to deallocate.

There are ways around this problem, but we want to do things without wasting either time or too much memory, or changing the existing structures. Here’s the plan:

  1. Each geometry node will have used flag. Not a counter, just a boolean.
  2. Initially the used flag is clear (false).
  3. Whenever we update the display list, every object that’s nearby sets the used flag.
  4. From time to time (every 1 to 5 minutes, say), we iterate the list of values in the map, then…
  5. We release all models for which the used flag is clear – these models haven’t been used in a while, likely we won’t need them soon.
  6. We clear the flag for all remaining models.

I can generalize this a little bit checking accesses from Element3D.

    Implementation?

    I tried to implement the above quickly. Maybe a little too quickly. Ghosting bounds (retaining the bounds after geometry has been unloaded) went fine. Trying to automate memory release (based on the used flag) looked good in theory; in practice, it didn’t really work this time.

    So I did the simple thing. Force release (using the existing mechanism for handling memory warnings) manually when reaching a new stage in the game or performing a key action. The results are displayed below.

    Test Results

    I tested on an iPhone 3GS, mainly to save time. I use more memory on the 3GS because the rendering surface is bigger than the display (so I can antialias). The test glitched a little because I’d introduced a bug that failed the release mechanism between stage 3 and 4 in my game.

    • Startup: 0.6MB
    • Stage 1: 3.8-4.3MB
    • Force release as much as possible: 1.76MB
    • Stage 2: 4.67-10.06 (until Klinnburg village); 5.5 after picking the bread; climb to 12-13 MB
    • Stage 3: 13 – 20.6 (but fails to show chapter 3 notice and release memory when starting)
    • After releasing resources: 5.0mb
    • Stage 4: 12.18-16MB

    Conclusion

    The results of the test suggest that the resource release mechanism is somewhat inefficient. It looks like, if I had just 6 stages like the ones above, I’d hit the 20MB limit.

    Meanwhile, I don’t expect running into problems for this release. I don’t think my app leaked about 20MB in 40 minutes. I’ve done several passes to eliminate all leaks in the app code. One of the latest steps before submitting the app will be checking for leaks again, and looking into leaks generated by system libraries.

    Here’s what you need:

    • Audacity, maybe with the Lame MP3 Encoder. Audacity can open and edit / filter
    • iCaf – a beautifully small and efficient utility to convert mp3/wav to iPhone’s CAF format.

    Scouring royalty free sound sites for stuff takes a long time. Checking usage rights with artists takes roughly the time it takes to find songs in the first place (especially on low bandwidth). So what’s a long time? I’ve spent 2 or 3 days finding less than 20 samples. The music and effects are definitely better than what I would have come up with. More often than not, I find that I need to edit the sound (fade-in/out and level tuning), so I needed something like Audacity.

    On the cool side, I found that artists I contacted (when they reply) are most friendly and approachable, so maybe checking free sites for stuff you can use is a good step towards the better way into sound and music: work with an artist you already know.

    I also got slightly shocked finding that some of these guys drop a couple of sounds on a free site, then move on their merry way and become known for what they do, sometimes even signing up trailers and music for blockbusters. One thing about the internet is that it’s a huge collective memory, where the early experiments of gifted talents are beautifully preserved.

    Hey. I’m way out of it. Next time I’ll explain two or three classes, no more, that can help you integrate sound and background loops into your iPhone game.

    Hairlock - dev picBy the calendar, I fixed many obvious bugs in my game engine up to the 1st of March. Since last week, and for hopefully no more than another dozen days, I’ll only be working on game assets.

    Guess it’s time to post a pic then – the project still goes by the codename Hairlock - not as good as it used to be since the hairlock incident proper has been moved to a proposed sequel.

    I started modeling a couple of months back, among worries that the rendering wouldn’t follow. Now the question is different: can the artwork follow?

    One question that comes to me over and over about the artwork is, why don’t I borrow/buy stock models? I doubt whether this would actually be feasible granted my geometry has to stand for (no) textures, and game models following the twist may be hard to find. But that’s not it. Nor taking the challenge (well yeah, in part…). I just have this feeling that even amateur artwork will be more interesting than even professionally produced stock models – granted it is designed to be coherent and originally produced.

    Sure I could use borrow or buy artwork for little things – one chair here, a house there, and so forth but…

    The actual cost for me is characters. The little guys on the right took me about 15 hours to get done with. And we don’t want to borrow characters, do we?

    Artwork is expensive, but we don’t need to pay every time

    The bottom line is…

    1. Since a game is its own universe, it may be a good idea to create original artwork for it.
    2. Within the game, reusing artwork elements increases consistency without compromising quality.

    One of the great advantages of 3D is that 3D is vector graphics. While the cost of a new model is high, dressing up a model in different ways, or just changing it a little, is fairly cheap – if you’re using Blender and you’re out making actual geometry for clothes or hair, retopology may be worth a try. That, and a little patience.

    So while I enjoy making new stuff, I also look forward to just pulling models off the hat later on, so I can focus more on story and game mechanics.

    About the screenshot…

    Here we’re running at around 13 FPS. The models use no textures, so everything you see is (un-decimated) geometry.

    • Our little heroine on the left renders 1,588 vertices / 1623 faces
    • The wise guy with the bed-head boasts 1,812 vertices / 1790 faces

    This goes on top of the 15,836 faces sent to render the environment (hardly any of this actually intersects the viewport) using 7 calls to glDrawElements.

    I don’t know about textured scenes – you can do a lot without textures (in fact, a lot more than what is demonstrated here). For now here’s a quick break down of how this renders:

    • 36.3% rendering the terrain
    • 12.5% rendering actors (frame interpolation doesn’t generate overheads in this particular case since I got the actors to pose for the pic)
    • 19% hit testing to keep the camera somewhere reasonable (oh no!)
    • 5% running game logic
    • 10% (!) refreshing the text box (this gets done quite often just to display the frame rate…)

    I’m not worried yet about the terrain rendering time – I might have to eventually. Hit testing overheads are to go away altogether (not the hit testing, just overheads). I’m not planning yet on using distance based LOD – overall, I hope these stats make you feel that it’s possible to run at frame rate with detailed geometry on an iPod Touch, and if doesn’t, let’s wait until we get better screenshots :)

    In space, nobody will hear you geek

    There you are. I’ve just completed core gameplay programming for the first episode of… well… let me think up a name for it.

    This looks like a small adventure/action game in real time 3D. Core gameplay can be summarized as follows:

    • 4 player actions
    • 9 different NPCs
    • 6 items to collect
    • 5 stages
    • dialogues, here and there, to orient the player towards the right solution

    There’s a lot to get the game done, but I still hope this won’t spread over more than another month (part-time). What do I leave out from ‘core gameplay’?

    • Bugs. Many bugs.
    • Non-committal gameplay elements – more dialogues here and there, minor NPCs without complex behavior and so forth. Non-commital gameplay elements are important. That’s added value on my game. But one needs something they can add value to, right?
    • Game tuning – mostly timing / measurements related.
    • Prettier rendering
    • Production level artwork
    • Decent Sound

    Technical Design, Methodology

    Given the above, you bet I didn’t bother with either of the following:

    1. Getting stories ‘done done
    2. Unit tests
    3. … other nice things

    Why? Is the nice, agile stuff not nice more? Why is missing the ‘done done’ over and over so irritating while doing team work, but somehow left out when geeking in a small studio? Do unit tests not warrant code quality and so forth? Or is it just that it’s faster to do without all this stuff?

    Here are a few things I surely didn’t leave out:

    1. Story driven. Even though I had to build an engine before I could even get to thinking of a game, I’ve kept a steady emphasis on getting valuable items done.
    2. Separation. Didn’t write big classes, usually separated state from behaviors in the core model, defined a pseudo scripting interface (short of a scripting language integration) atop my game engine. Did write a small engine versus just a game, and so forth…
    3. Integrated workflow. I arranged that I could update my assets in one click. No muddling through with cumbersome export procedures. The same goes with poor code and documentation. Poor code might be OK for a while. Poor undocumented code is worth nothing. Good, undocumented code doesn’t generate integrated workflow – not knowing how the code works doesn’t flow much faster than no code, or code that doesn’t run to spec.
    4. Optimization. I did follow the time honored (ignored?) command: do not optimize your code… …unless you have to. So I always wrote first the simplest code that did a job, and faithfully relied on a profiler to help me frame-rate on a powerful, yet mobile platform.

    Where is Attitude?

    In a well funded team project (as in, bucks per hour), earning money needn’t be the primary motivator, but in the long run, there is no clear ‘finish line’ for your staff. They will work on and on, and get happy to get stories done done – work well done completed every one two three weeks.

    In a solo project such as this one, or a small, non funded team project, getting the product done is the primary goal for the team, or the ghost out the machine. Psychologically, having half of the product done done half-way through feels much tougher (at least to me) than having the product about half-done half-way through.

    So I what felt like was, OK, if I just sit and polish every detail one by one, I’ll be overwhelmed by the task at some point, whereas by attacking frontally every sizable, unavoidable task, I’d get to a point where it would be such a horrible shame not to finish that I’ll definitely manage.

    Poor code, OK design

    Do you remember your first game engine? Nothing to be proud of except getting a job done, right? Same here. Dead code, flawed code, even deep flaws in the design here and there, but it sort of works, and I would argue that’s enough.

    This is what refactoring is for, and to some extent this is the (maybe illusory) benefit of strong ownership and solo programming. It’s much easier to get the product done and defer refactoring if you’re soloing. After all, if you don’t get any benefits from the product, you might just as well give up the code. I felt it was OK. On the other hand, really badly design code with large classes, no separation of responsibilities and no usable game development API, that didn’t seem tractable. Not only it could be impossible to refactor, it would have made finishing the product draft prohibitively hard.

    I look forward to refactoring this stuff. In particular, I look forward to doing it while fixing the bugs. If a bug is impossible to fix with my current code, then there’s a case for redesign.

    Docs are up

    There’s been a point where I felt this stuff was so messy I’d never get out of it. Then I managed to delete a lot of dead code, crossing fingers every time that the code was really dead since I didn’t fancy getting it back from the attic, not even the recycle bin. That I mostly threw away whole classes rather than code fragments brings the point home regarding separation.

    Then there was a point when I started designing the game, and I felt like throwing half of the working code away, because the code didn’t seem to support the design. So I did the unholy thing that you can only do if you control both the technical and artistic design – Instead of throwing my stuff away, I documented it, putting on top what seemed to actually work, and tried to redesign my game around the highest confidence bits of functionality. Finally this helped improving stuff that could be used in a design empathic to the engine, and throw stuff that was neither necessary, nor stable.

    Looking at my docs, I’m reminded of a harsh, fun comment about docs masking poor code. But actually, even docs over poor code can be better than good. If code is bad enough that it can only be used in one or two well documented ways, that’s still functionality I can flow with, never mind indexing essential behaviors that should be maintained and improved, versus stuff that needs to be forgotten and deleted.

    Spaghettis, Meatballs and a Haircut

    In the next days, I’ll try to tend this blog more often. Because I’m gonna fix this mess, and hope to find design insights worth sharing along the way.

    Until then, let’s write dirty code. Or if you can’t, get help from above.

    Yea I know… screenshots… another time.

    Note: this article isn’t a benchmark. This article investigates GL-ES rendering performance in a running game prototype (with game logic running, not just GL rendering).

    Today I’ve tested rendering performance with a simple character – ‘hit-man’ (230 vertices, 206 faces):

    • idle animation
    • walk cycle
    • hit animation

    I use indexed faces (GLDrawElements) without VBOs (glVertexPointer). I’m not sure about using VBOs for actors because I interpolate animation frames on the fly – if I want to use VBOs, I’ll have to worry about how many mesh duplicates I can buffer, when to release them and so forth…

    I animated a 100 actors this way, and it wasn’t fast – not hopelessly crawling like when I added game logic for the same 100 actors – just slow. So I did the obvious – added a boundary check to render only actors visible on-screen. That brought back an acceptable frame rate right away, without the need for further optimizations. The frame rate is still about OK with 20 actors on-screen.

    This came as a surprise since my terrain rendering (no VBOs either) generates the highest overhead in my iPhone app. Here’s a quick breakdown of processor usage (rendering related only):

    • 40% – GLDrawElements for terrain (300 tiles, about 18400 faces)
    • 20% – Frame interpolation
    • 3.5% – GLDrawElements for actors (20-25 on-screen, about 4000-5000 faces )
    • (drawing props and doing other things)

    Admittedly, my tiles are heavy. But frankly, it doesn’t add up – Getting 4 times more actors on-screen would just bring up drawing cost to 15%(1) (never mind frame interpolation), so still much less than tile rendering on the side of GL performance.

    An experiment

    I had a feeling that drawing large triangles took much longer than drawing small ones – so I iterated with basic square tiles (2 faces, 4 vertices) – here’s the result:

    • 9% – GLDrawElements for terrain (300 tiles, about 18400 faces)
    • 34% – Frame interpolation
    • 7.6% – GLDrawElements for actors (20-25 on-screen, about 4000-5000 faces )
    • (drawing props and doing other things)

    In this configuration the game runs all nice and smooth – it’s not just that the tiles had many faces – faces for a single tile covered each other as well.

    Conclusion

    Rendering more pixels slows down rendering more than rendering more faces – With an isometric view, simple tiles and detailed characters can be a good combination.

    (1) The way I evaluate this is so so – multiplying percentages this way isn’t maths

    So far I’ve had only a couple of actors on my game board. Granted I might not need more than 6 to 12 actors onscreen at the same time to bring some excitement, There are additional factors to consider:

    • It is better to be able to process interactions for a large number of characters, on and off-screen.
    • It may be simpler to be able to add all character for a game level right away, rather than having to generate NPCs on the fly.

    I’m running a mere 100 actors now and the game is already crawling on our iTouch.

    For now the rendering overhead is very low (all additional actors are just rectangles). With the help of instruments, I reduced several overheads related to game logic – I didn’t get a smooth running game again until clearing everything.

    • Actors need to find about nearby actors while idle. This allows an actor to determine what to do next using a ReflexMap class.
      • Added bound checks to reduce the overhead of finding nearby actors.
      • Removed unnecessary messaging involving type casting and type inference.
      • Removed all code associated with actors picking objects. This code may need to be optimised later but for now it is simply unused.
    • Disable debug related rendering. Just this uses 18% of the processing time (drawing strings over the 3D view using Quartz.
    • After applying the above, the game was still running pretty slow. So I randomly avoid deciding a new action for idle actors, skipping 7 frames out of 8. At this rate, actors still respond reasonably fast.
    • Remove all NSLog calls from the run loop. Don’t even think about profiling or optimizing while generating console output.

    After this, the game is running fairly smoothly, although not at a great frame rate (16fps).

    I further optimized AffectMap. This complements ReflexMap – affect map determines what happens to an actor (e.g. getting hit) versus what they choose to do. I used bounds checking with a shorter range (effects are always direct). Running AffectMap is still twice as expensive as ReflexMap, because I can’t skip any frames.

    Now I can push to 24fps and things look reasonably smooth. A hundred actors on stage, all live and interacting even when off-screen, doesn’t seem too bad.

    Having a look at the current snapshot, it’s not difficult to guess more efforts will need to be dedicated to optimizing -this app is drawing next to nothing still.

    How big can a game board be? I have currently two limiting factors:

    • Memory. I crash my iTouch with a Board bigger than 750×750
    • Loading/Generation Time. Currently, with a 750×750 Board, this takes seconds.

    Surely we can make a much larger board. It all depends how we store the data. For now I use a flat 2 dimensional array, with each cell including the following information:

    • terrain (NSString*)
    • prop (NSString*)
    • solid state (BOOL, prevents player & NPCs from occupying a cell)
    • height (float, allows offsetting tiles and props vertically)

    Since each cell is also an object, I use 4*3+1+4 = 17 bytes per cell (assuming an atomic ‘BOOL’ actually occupies a single byte and counting the cell object reference). I could:

    • encode terrain and prop as byte values (2)
    • encode height as a short (2)
    • use C arrays (I’ll probably need to do this anyway to reduce the time spent allocating memory for the board), saving the cost of a cell object reference
    • Do away with the solid state (that could be implicit to terrain)

    The resulting allocation would be 4 bytes per cell, for times less than the current allocation. Let’s not sweat it, that’s just a board twice as large.

    I consider that a ‘board size’ factor between 5 and 100 will potentially impact design opportunities – in other words, the board has to be vastly wider to change the way I think about my design.

    RLE compressing terrains and storing props as a list (versus allocating space for a single prop within each cell) may be much more effective in some cases. It’s worth noting that both methods somehow imply reduced variety in the game board. If larger means emptier, is it really worth it?

    Let’s keep in mind that, to create a massive game board, we need either to slice it (can’t hold a complete board into memory) or… …approach the problem in a quite different way.

    What’s in it for a game?

    The speed of my player character was originally 5 pix / frame. I’m not sure about the frame rate – just OK actually. At 5 pix per frame with 32×16 tiles, it takes 15 seconds to cross a 25×25 board. That’s a really small board. I’d like a board big enough for exploring. Granted a game isn’t all about hanging around and visiting places.

    A 500×500 board is 20 times wider, So it takes a round 20×15 = 300 seconds to cross it. Just about 5 minutes. But I feel 5pix/frame is too stately, so make it 8 pix per frame. Now we can cross the board in about 3 minutes.

    OK then, going ‘around the world’ is one thing. How long would it take to explore all of the board’s corners? 9 minutes? I don’t think so. If we do it ‘screen by screen’, With 30 tiles on the height of a single screen, we have 50/3 ~ 15 rows to check, making about 15×3 = 45 minutes.

    Ideally, I’d like to have a much larger board. But for now, I’ll worry more about how I populate the board, and less about how big it can be.

    Well, I was supposed to provide better support for rendering ‘dummies’ – non-commital symbols representing game actors, to be used in game prototyping so we’re not tied to producing assets whenever we need to declare new characters and props.

    Today I’m integrating realtime 3D character animations with my isometric view – how’s that for staying focused?

    Isometrics again

    While working out and testing Blender to GL export, I’ve setup my isometric view more reliably – the original setup was fiddly.

    My unit conversions are getting complicated:

    • First I worked in pixels. This is great for 2D sprites, with 32 pixels amounting to roughly 1 meter.
    • Working with blender, I usually map 1 world unit to 1 meter.
    • To save space, my models are encoded as signed short values. To do this, I premultiply everything by 1000 (smallest resolvable unit = 1 millimeter).

    Time to tidy up. Here’s my new setup for the orthographic projection:

    [EAGLContext setCurrentContext:context];

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);

    glViewport(0, 0, backingWidth, backingHeight);

    // setup an orthographic projection (no perspective)

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    // The following indicate how many world units we fit

    // in the width and height of the screen. So if you set this

    // to say, 10×15, you show 15 x 10 world units.

    //

    // I just map pixels to world units, so at this point I ensure that

    // 1 gl unit is 1 pixel.

    //

    // The depth parameter extrudes the screen into a box. Whatever’s

    // inside the box is showing, the rest isn’t.

    float width=GL_RENDER_AREA_WIDTH;

    float height=GL_RENDER_AREA_HEIGHT;

    float depth=GL_ISO_RENDER_DEPTH*5;

    glOrthof(-width/2, width/2,-height/2,height/2, -depth/2, depth/2);

    // Now we reset the ‘model view’. In other words we’re fitting the world

    // inside our box.

    // I rotate the world 30 degrees. This creates an isometric projection

    // except I’m not rotating 45 degrees on the Y axis, which would give

    // the classical ‘lozenge tile’ isometric effect.

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

    glRotatef(30,1.0f,0,0);

    // At this point I rescale by ‘pixels per metre’.

    // By default, 32 pixels is now 1 metre.

    glScalef(pixelsPerMetre,pixelsPerMetre,pixelsPerMetre);

    // Here I setup/clear the depth buffer.

    glDepthMask(GL_TRUE);

    glClearDepthf(1.0f);

    glDepthFunc(GL_LEQUAL);

    glEnable(GL_DEPTH_TEST);

    // Clear with some non-descript dark gray

    glClearColor(0.2f, 0.2f, 0.2f, 1.0f);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Render the world

    [contentRenderer render];

    // Display the result.

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);

    [context presentRenderbuffer:GL_RENDERBUFFER_OES];

    OK, now I need to correct everything down the chain. In passing, I removed a ’32′ scaling factor because both my actors and tiles already used world units. The data model still uses pixel units, I won’t touch that for now.

    Blender Sprites?

    I corrected the tile display – that’s not too important because tiles are really just make-does. I’m more excited about integrating my character animation from Blender. Pending the next serious article about the export/import code, drafted and tested this week-end, the main (and limited) interest of the integration code lies in the transformation sequence.

    In the code below, ‘actor’ refers to the data model object. actor3d is a wrapper around geometry data. Since geometry data can be rendered using various methods, I’ve defined rendering code in a separate class, ActorRenderer3D.

    This

    // eval orientation angle

    float angle=0;

    Vector* u= actor.orientation;

    if (u.length<0.001f) {

    angle=0;

    }else {

    // here the angle is tested against the y axis because

    // the orientation (from my legacy 2D isometrics) describes

    // the actor’s direction in the model’s x-y plane, so I

    // substitute y to z.

    Vector* v= [[Vector alloc]initWithX:0.0f y:1.0f z:0.0f];

    // [Vector angle::] returns the same values for x positive

    // and x negative so I flip the angle to get the

    // actual rotation.

    angle=[Vector angle_deg:u with:v];

    if (u.x<0) {

    angle=-angle;

    }

    }

    // transform and draw

    glPushMatrix();

    // we need to rescale by 32 because the model’s coordinates are in pixels

    // (eventually the rescale factor should be passed down the render graph)

    float tx=(actor.location.x-originX)/32.0f;

    float ty=(actor.location.y-originY)/32.0f;

    //

    glTranslatef(tx,0,ty);

    glRotatef(angle, 0, 1, 0);

    [Actor3DRenderer renderActor:actor3d action:@"nod" frame:actor.phase];

    glPopMatrix();


    Right – that’s it for integration so far. I’ll have more to do later in two essential areas:

    • Selecting the animation frame to be displayed. The model’s ‘phase’ should be determined by the view. This is counter-intuitive (the model should drive the view, not the reverse) but logical (the animator/designer determines the action’s duration). A this point, phase is still determined (arbitrarily) by the model.
      I could export animation durations separately, but I don’t think this is a good idea. This is data duplication, and is kind of dishonest. On the other hand, it is likely that animation durations will require tuning later, so my bet is that I should (a)actually define animation durations somewhere else and (b) provide code that remaps animation frames to actual game loop frames.
    • Mapping/Matching model actions (ids) to animation names (strings) – I’ve hardwired an action name for now because I have no safety guards against an undefined action – an action for which there is no matching animation.