My first thought when planning to make a 2D game for the iPhone was to find a way to not re-invent the wheel. I did some web searching and came across the website for Cocos2D, a port of the library to the iPhone. Great, looks like just what I needed…well, not so much. After messing with the samples and starting to write some prototyping code I figured out a few things that concerned me not only about the library but texture handling in general.
Sprites with Cocos2D rely on the Texture2D class created by Apple to do their drawing as does the “game” code that Apple released at WWDC. It didn’t register at first that this would be a problem until I looked through the code to see how textures are handled. Non-compressed textures, like pngs, are first expanded to an equal power of two and dropped into a newly created texture in the correct swizzled format. Coming from a game development background, I knew that swizzling textures or doing any sort of conversion work at load or runtime is a waste so I turned my direction to the PVRCT format. This is the native texture format that can be essentially load and go. Using the new compressed texture format eliminated the conversion step but still required the power of two texture. Fine, not a problem, many sprites or frames are commonly dropped into a single texture anyway. Most video hardware require a power of two texture so this in itself didn’t surprise me, the requirement that it be an “equal” power of two though did. Meaning, a texture of 256×128 just isn’t possible. Turns out this is a limitation of the PowerVR MBX chipset (you can get the docs and SDK at the Imgtec.com website). Alright, I can work around this. Just drop multiple sprites into a single texture and move around the U,V coordinates to access the invididual images I need. This will eliminate the texture state change and speed up rendering anyway. Wait a second, Cocos2D doesn’t support this. They have a strict one texture to one sprite set up. This is the easiest way to get someone up and running quickly but is horribly inefficient when writing game code. The iPhone is very restrictive on the amount of memory available for an application.
So, In my haste to try and use existing technology I’ve discovered that I’m pretty much back at the beginning. I tossed out the Cocos2D library (it would have been more trouble than it was worth to change their code) and tossed out Apple’s Texture2D class and Apple’s version of the texture compression tool and started writing my own code. I wasted about three days exploring other options but it did give the opportunity to learn more about the hardware that I’m working on.
So far I now have the underlying texure handling and resource manager complete and am about halfway through the sprite code, all written in C++. Most of the code is platform agnostic with only bits and pieces requiring porting when converting to other platforms.
I’ll post more info as I continue my iPhone exploration.
5 Responses for "OpenGL ES Sprites…"
I just discovered the same thing about Cocos2D! So. Disappointed. Seriously. Didn’t these folks ever see a sprite sheet? Guess it’s back to my own sprite lib. I’ve written one before, so it’s not so scary.
Cocos2D is interesting and a good start, but I really wish it had more useful functionality. I went ahead and wrote up my own sprite system. I prefer maintaining my own code anyway.
Hi Wendy, Great post! It’s given me some useful insight into how PVRCT and png are utilized by the Cocos2d-iphone game engine. I’m wondering if you could perhaps commit a patch to the engine to help those of us who are still using it? One of my favorite things about the engine is its friendly community, and its other users would appreciate your work as well.
Agree but I must say that an approach to keep one texture for the sprite has its advantages if you need for example strong screen pixel to texel accuracy. Unfortunately I started my own development with keeping a set of sprites in one texture of size 512×512 but mentioned a problem that at some positions my pieces of texture accessed by U and V drawn at 1 texel to 1 pixel leaded to problem of doubling a texel to 2 pixels or viceversa not drawing a texel, so the final image looked ugly. This happens because of not enough precision of float numbers and unfortunately we can’t access any exact texel we want
Even GL_FIXED doesn’t work
I found the same problem in cocos2d and I’m writing my own engine for my game. But I’m using Apple’s Texture2D right now because I don’t have enough knowledge to write by myself yet.This could be a potential problem for me because my code are all C++ and I’m going to port my engine to other platform. Do you mind to share your code regarding with texture loading? Or provide some suggestions? Thanks.
Leave a reply