iPhone OpenGL Texture loader issues - iphone

Ok, what I'm trying to achieve is to load an image as a single resource and then save different parts of it as a number of different textures (basically chopping the image into smaller squares and then saving them separately).
For my game, simply mapping different sections of the original image to my shapes won't work and being able to have each 'tile' as a separate texture would be awesome.
Below is the code I'm using for my texture loader. I've tried messing round with the width and height of the texture being loaded but getting some weird results.
Any suggestions would be much appreciated.
Thanks
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
NSString *path =
[[NSBundle mainBundle] pathForResource:#"checkerplate" ofType:#"png"];
NSData *texData = [[NSData alloc] initWithContentsOfFile:path];
UIImage *image = [[UIImage alloc] initWithData:texData];
GLuint width = CGImageGetWidth(image.CGImage);
GLuint height = CGImageGetHeight(image.CGImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *imageData = malloc( height * width * 4 );
CGContextRef context = CGBitmapContextCreate(
imageData, width, height, 8, 4 * width, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
CGColorSpaceRelease( colorSpace );
CGContextClearRect( context, CGRectMake( 0, 0, width, height ) );
CGContextTranslateCTM( context, 0, height - height );
CGContextDrawImage( context, CGRectMake( 0, 0, width, height ), image.CGImage );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, imageData);
CGContextRelease(context);
free(imageData);
[image release];
[texData release];

Ok, just in case anyone wants to achieve this, i figured it out. All you need to do is modify the line CGContextDrawImage and alter the width and height parameters.
This results in the whole texture being loaded in but then will only draw the area specified on this line.
Basically,
CGContextDrawImage( context, CGRectMake(0, 0, width*2, height*2 ), image.CGImage );
will draw 1/4 of the image (as its height and width are being doubled past the textures size).
:)

Related

Optimizing OpenGl Rotation of a 2D grayscale image on iphone

I am rotating an image on the iPhone. It is a full size grayscale image (3264 by 2448 on the 4s). OpenGl appears to be roughly twice as fast as core graphics by my measurements, running about 1.22 seconds as opposed to 2.6 seconds. But this is not fast enough for my needs, I need sub-second rotation, if it is possible. (If not, we go to Plan B which involves rotating a subsection of the image, which is more elegant perhaps but has it's own issues.)
I should make clear that this only for internal processing of the image, not for display purposes.
I would like to make sure that I am doing this correctly and not making any obvious beginner's mistakes. Here is the code, I would appreciate any hints for improvements if possible.
Thank you,
Ken
void LTT_RotateGL(
unsigned char *src,
unsigned char *dst,
int nHeight,
int nWidth,
int nRowBytes,
double radians,
unsigned char borderColor)
{
unsigned char *tmpSrc = (unsigned char *)malloc( (nWidth * nHeight) );
memcpy( tmpSrc, src, (nWidth * nHeight) );
CGContextRef context2 = CGBitmapContextCreate(
tmpSrc, nWidth, nHeight, (size_t)8, nRowBytes,
CGColorSpaceCreateDeviceGray(),
kCGImageAlphaNone );
CGImageRef imageRef2 = CGBitmapContextCreateImage( context2 );
UIImage *image2 = [[UIImage alloc] initWithCGImage:imageRef2];
GLuint width = CGImageGetWidth(image2.CGImage);
GLuint height = CGImageGetHeight(image2.CGImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
void *imageData = malloc( height * width);
CGContextRef context = CGBitmapContextCreate( imageData, width, height, 8, width, colorSpace, kCGImageAlphaNone );
CGColorSpaceRelease( colorSpace );
CGContextTranslateCTM( context, 0, height - height );
CGContextRotateCTM(context, -radians);
CGContextDrawImage( context, CGRectMake( 0, 0, width, height ), image2.CGImage );
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_LUMINANCE, imageData);
CGContextRelease(context);
memcpy( dst, imageData, (nWidth * nHeight) );
free( tmpSrc );
}

How to give animation for the texture in open gl iphone?

I am new to iphone development. Currently I am working on a project where opengl is used and I need to animate a part of the view. For that I have taken the screen shot and then created the texture.
This is my code
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_SRC_COLOR);
UIGraphicsBeginImageContext(self.introductionTextLabel.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
GLuint texture[1];
glGenTextures(1, &texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
GLuint width = CGImageGetWidth(viewImage.CGImage);
GLuint height = CGImageGetHeight(viewImage.CGImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *imageData = malloc( height * width * 4 );
CGContextRef contextTexture = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
CGColorSpaceRelease( colorSpace );
CGContextClearRect( contextTexture, CGRectMake( 0, 0, width, height ) );
CGContextTranslateCTM( contextTexture, 0, height - height );
CGContextDrawImage( contextTexture, CGRectMake( 0, 0, width, height ), viewImage.CGImage );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
CGContextRelease(contextTexture);
free(imageData);
I have searched a lot but could not find a good method for giving an animation for the texture.
Can any one suggest me good method. If I am doing wrong please point out.
Thanks in advance.
The only way I can recommend you to modify the texture is to use glTexImage2D() for full frame update and glTexSubImage2D() for partial update. Of course it will be better if you will use preloaded and compressed type of textures...

Iphone - Masking JPG images

I am coding a jigsaw puzzle and I need to mask the images to create puzzle pieces.
I am using pictures from an online server and they are *.JPG. When I mask them, the area that should be transparent is black.
Can I add the alpha channel programmatically? If yes, can you show me how?
Thanks a lot,
Andrei
I found the answer:
CGImageRef imageRef = self.CGImage;
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
// The bitsPerComponent and bitmapInfo values are hard-coded to prevent an "unsupported parameter combination" error
CGContextRef offscreenContext = CGBitmapContextCreate(NULL,
width,
height,
8,
0,
CGImageGetColorSpace(imageRef),
kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
// Draw the image into the context and retrieve the new image, which will now have an alpha layer
CGContextDrawImage(offscreenContext, CGRectMake(0, 0, width, height), imageRef);
CGImageRef imageRefWithAlpha = CGBitmapContextCreateImage(offscreenContext);
UIImage *imageWithAlpha = [UIImage imageWithCGImage:imageRefWithAlpha];
// Clean up
CGContextRelease(offscreenContext);
CGImageRelease(imageRefWithAlpha);
return imageWithAlpha;

Creating UIImage with per-pixel alpha from GL buffer

I'm trying to take my gl buffer and turn it into a UIImage while retaining the per-pixel alpha within that gl buffer. It doesn't seem to work, as the result I'm getting is the buffer w/o alpha. Can anyone help? I feel like I must be missing a few key steps somewhere. I would really love any advice on this.
Basically I do:
//Read Pixels from OpenGL
glReadPixels(0, 0, miDrawBufferWidth, miDrawBufferHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
//Make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, len, NULL);
//Configure image
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGImageRef iref = CGImageCreate(miDrawBufferWidth, miDrawBufferHeight, 8, 32, (4 * miDrawBufferWidth), colorSpaceRef, kCGBitmapByteOrderDefault, provider, NULL, NO, kCGRenderingIntentDefault);
// use device's orientation's width/height to determine context dimensions (and consequently resulting image's dimensions)
uint32* pixels = (uint32 *) IQ_NEW(kHeapGfx, "snapshot_pixels") GLubyte[len];
// use kCGImageAlphaLast? :-/
CGContextRef context = CGBitmapContextCreate(pixels, iRotatedWidth, iRotatedHeight, 8, (4 * iRotatedWidth), CGImageGetColorSpace(iref), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, miDrawBufferWidth, miDrawBufferHeight), iref);
UIImage *outputImage = [[UIImage alloc] initWithCGImage:CGBitmapContextCreateImage(context)];
//cleanup
CGDataProviderRelease(provider);
CGImageRelease(iref);
CGContextRelease(context);
return outputImage;
Yes! Luckily apparently someone has solved this exact problem here: http://www.iphonedevsdk.com/forum/iphone-sdk-development/23525-cgimagecreate-alpha.html
It boiled down to an extra kCGImageAlphaLast flag being passed into the CGImageCreate to incorporate the alpha (along with the kCGBitmapByteOrderDefault flag). :)

Loading image into OpenGL ES from c++ code in iPhone

I'm creating an iPhone game and I need to load an image from a PNG file into OpenGL (and bind it as a texture). I'm using function glTexImage2D to achieve this goal.
I know how to load an image into OpenGL using UIImage (by converting it into CGImage and afterwards drawing into a context).
How can I call my Objective-C code from within C++ code (I'm coding in .mm file)?
Here's the code I'm using and that would work in Objective-C:
NSString *path = [[NSBundle mainBundle] pathForResource:#"texture" ofType:#"png"];
NSData *texData = [[NSData alloc] initWithContentsOfFile:path];
UIImage *image = [[UIImage alloc] initWithData:texData];
if (image == nil)
NSLog(#"Do real error checking here");
GLuint width = CGImageGetWidth(image.CGImage);
GLuint height = CGImageGetHeight(image.CGImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *imageData = malloc( height * width * 4 );
CGContextRef context = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
CGColorSpaceRelease( colorSpace );
CGContextClearRect( context, CGRectMake( 0, 0, width, height ) );
CGContextTranslateCTM( context, 0, 0 );
CGContextDrawImage( context, CGRectMake( 0, 0, width, height ), image.CGImage );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
CGContextRelease(context);
free(imageData);
[image release];
[texData release];
Is there a way to call those UI and Core Graphics functions from C++ code? What files do I have to include?
Thank you in advance.
Solved the problem. Had to find manually and add the Core Graphics framework.