Loading textures on Android and iOS: libpng or Bitmap/UIImage?

Started by
2 comments, last by Ed Welch 11 years, 3 months ago
I'm in the process of porting a C++ SDL/OpenGL desktop game to both Android and iOS. While SDL 1.3 covers both platforms and works pretty well for me, I feel uncomfortable using some random untested Mercurial revision of it, so I've decided to handle the creation of the OpenGL context, input and image/audio loading myself.

The only way to load texture assets from native code in Android 2.2 seems to be opening the .apk with libzip and loading the image with libpng, which is what I've done. I've not started with the iOS port yet, but based on some research, it seems that I can just read the textures from storage and load them with libpng there as well.

While this works, it's a lot of code I don't fully understand yet, so I'm wondering if it isn't better to use each platform's canonical means of loading images, namely Bitmap in Android, UIImage in iOS and SDL_image on desktop. That sounds like inviting a bunch of platform-specific bugs though, I like the idea of having as much shared code as possible.

Does anybody have experiences with either approach? Can't decide which one to go with.
Advertisement

I recommend using libpng for both which will allow you to make all of it platform-independent. Since you already have the libpng implementation working for Android, this also seems to be the easiest route for you.

Since you already have the libpng implementation working for Android, this also seems to be the easiest route for you.

Well, that's only half true, still have to figure out how to deal with NPOT textures with libpng :( That's mainly why I'm wondering if I want to go with that approach, to know if it's worth tearing more hair out before I start tearing :)

Either way is fine.

This is the code I use:


void ImagePNG::Load(const string& fileName)
{
	NSString *nsFileName = [[NSString alloc] initWithUTF8String:fileName.c_str()];
    NSData *texData = [[NSData alloc] initWithContentsOfFile:nsFileName];
    UIImage *spriteImage = [[UIImage alloc] initWithData:texData];
    if (!spriteImage) 
	{
        cout << "Failed to load image " << fileName;
        RacException("can't read compressed texture from file ", fileName);
    }
    
    m_width = CGImageGetWidth(spriteImage.CGImage);
    m_height = CGImageGetHeight(spriteImage.CGImage);
    

    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    // Allocate memory for image
    void *imageData = malloc( m_height * m_width * 4 );
    CGContextRef imgcontext = CGBitmapContextCreate(imageData, m_width, m_height, 8, 4 * m_width, colorSpace,
                                                    kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
    CGColorSpaceRelease(colorSpace );
    CGContextDrawImage(imgcontext,
                        CGRectMake( 0, 0, m_width, m_height ), spriteImage.CGImage );
    
    CGContextRelease(imgcontext);
    

	//Now generate the OpenGL texture object
	glEnable(GL_TEXTURE_2D); 
	glGenTextures(1, &m_textureID);	
	glBindTexture(GL_TEXTURE_2D, m_textureID); 
	glTexImage2D(GL_TEXTURE_2D,0, GL_RGBA, m_width, m_height, 0,
		GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)imageData);

	// Free Stuff
    free(imageData);
    [spriteImage release];
    [texData release];

	int err = glGetError();
	if (err != GL_NO_ERROR)
	{
        cout << "Failed to load image " << fileName;
	}

}

This topic is closed to new replies.

Advertisement