- (void)createGLTexture:(GLuint *)texName fromCGImage:(CGImageRef)img
{
GLubyte *spriteData = NULL;
CGContextRef spriteContext;
GLuint imgW, imgH, texW, texH;
imgW = CGImageGetWidth(img);
imgH = CGImageGetHeight(img);
// Find smallest possible powers of 2 for our texture dimensions
for (texW = 1; texW < imgW; texW *= 2) ;
for (texH = 1; texH < imgH; texH *= 2) ;
// Allocated memory needed for the bitmap context
spriteData = (GLubyte *) calloc(texH, texW * 4);
// Uses the bitmatp creation function provided by the Core Graphics framework.
spriteContext = CGBitmapContextCreate(spriteData, texW, texH, 8, texW * 4, CGImageGetColorSpace(img), kCGImageAlphaPremultipliedLast);
// Translate and scale the context to draw the image upside-down (conflict in flipped-ness between GL textures and CG contexts)
CGContextTranslateCTM(spriteContext, 0., texH);
CGContextScaleCTM(spriteContext, 1., -1.);
// After you create the context, you can draw the sprite image to the context.
CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, imgW, imgH), img);
// You don't need the context at this point, so you need to release it to avoid memory leaks.
CGContextRelease(spriteContext);
// Use OpenGL ES to generate a name for the texture.
glGenTextures(1, texName);
// Bind the texture name.
glBindTexture(GL_TEXTURE_2D, *texName);
// Speidfy a 2D texture image, provideing the a pointer to the image data in memory
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texW, texH, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
// Set the texture parameters to use a minifying filter and a linear filer (weighted average)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Enable use of the texture
glEnable(GL_TEXTURE_2D);
// Set a blending function to use
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
// Enable blending
glEnable(GL_BLEND);
free(spriteData);
}