Cargando imagenes
Aquí va una breve rutina para cargar imágenes en una textura, lista para usar en OpenGL, el código está sacado de uno de los samples básicos .. no se si era GlSprite o alguno de esos, lo he dejado como un método statico para nuestra clase de utilidades en OpenGL
El código nos da un warning en la linea 6, dice que es un error de casting, pero como todavía no me aclaro mucho con esto del Objective pues me tendré que aguantar. si alguien sabe como arreglarlo que me lo diga.
| C | | copy code | | ? |
| 01 | +(GLuint) load:(StringPtr)cadena |
| 02 | { |
| 03 | GLuint spriteTexture = 0; |
| 04 | |
| 05 | // Creates a Core Graphics image from an image file |
| 06 | CGImageRef spriteImage = [UIImage imageNamed:cadena].CGImage; |
| 07 | |
| 08 | |
| 09 | if(spriteImage) |
| 10 | { |
| 11 | // Get the width and height of the image |
| 12 | size_t width = CGImageGetWidth(spriteImage); |
| 13 | size_t height = CGImageGetHeight(spriteImage); |
| 14 | // Texture dimensions must be a power of 2. If you write an application that allows users to supply an image, |
| 15 | // you'll want to add code that checks the dimensions and takes appropriate action if they are not a power of 2. |
| 16 | |
| 17 | // Allocated memory needed for the bitmap context |
| 18 | GLubyte *spriteData = (GLubyte *) malloc(width * height * 4); |
| 19 | // Uses the bitmatp creation function provided by the Core Graphics framework. |
| 20 | CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width * 4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast); |
| 21 | // After you create the context, you can draw the sprite image to the context. |
| 22 | CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), spriteImage); |
| 23 | // You don't need the context at this point, so you need to release it to avoid memory leaks. |
| 24 | CGContextRelease(spriteContext); |
| 25 | |
| 26 | // Use OpenGL ES to generate a name for the texture. |
| 27 | glGenTextures(1, &spriteTexture); |
| 28 | // Bind the texture name. |
| 29 | glBindTexture(GL_TEXTURE_2D, spriteTexture); |
| 30 | // Speidfy a 2D texture image, provideing the a pointer to the image data in memory |
| 31 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData); |
| 32 | // Release the image data |
| 33 | free(spriteData); |
| 34 | } |
| 35 | |
| 36 | return spriteTexture; |
| 37 | } |
Como podeís ver es una función muy básica, le pide a OpenGL que le de espacio para un textura y luego la updatea, para hacer un juego no es lo más optimo porque estaríamos fragmentando mucho la memoria con la carga de cada imagen. Si necesitamos leer muchas imágenes es mejor pedir espacio suficiente para cargar todas y luego meterlas una detrás de otras
Actualización: 05/07/2010
Bueno … llevo mucho tiempo desconectado del blog pero no creáis que no hago cosas .. en casa sigo currando, sigo peleándome con el XCode y sigo haciendo cosillas. Hace tiempo que perfeccioné este método para pasarle un NSString como parámetro y así ya no tenemos errores de carga. Os pasteo el code
| C | | copy code | | ? |
| 01 | + (GLuint)loadTexture:(NSString *)filename |
| 02 | { |
| 03 | CGImageRef image = [UIImage imageNamed:filename].CGImage; |
| 04 | if (image == nil) |
| 05 | { |
| 06 | NSLog(@"Failed to load texture image"); |
| 07 | return 0; |
| 08 | } |
| 09 | |
| 10 | NSInteger imageWidth = CGImageGetWidth(image); |
| 11 | NSInteger imageHeight = CGImageGetHeight(image); |
| 12 | GLubyte *imageData = (GLubyte *)malloc(imageWidth * imageHeight * 4); |
| 13 | |
| 14 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); |
| 15 | CGContextRef context = CGBitmapContextCreate( |
| 16 | imageData, imageWidth, imageHeight, 8, imageWidth * 4, |
| 17 | colorSpace, kCGImageAlphaPremultipliedLast); |
| 18 | CGColorSpaceRelease(colorSpace); |
| 19 | CGContextClearRect(context, CGRectMake( 0, 0, imageWidth, imageHeight )); |
| 20 | CGContextTranslateCTM(context, 0, 0); |
| 21 | CGContextDrawImage(context, CGRectMake( 0, 0, imageWidth, imageHeight ), image); |
| 22 | |
| 23 | // Subimos la imagen a la memoria del GL en el id indicado |
| 24 | GLuint textureId; |
| 25 | glGenTextures(1, &textureId); |
| 26 | glBindTexture(GL_TEXTURE_2D, textureId); |
| 27 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData); |
| 28 | |
| 29 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 30 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 31 | |
| 32 | CGContextRelease(context); |
| 33 | free(imageData); |
| 34 | |
| 35 | return textureId; |
| 36 | } |
| 37 |
| C | | copy code | | ? |
| 1 | |
| 2 | // y para cargar una textura: |
| 3 | GLuint texture = [GlSprite loadTexture:@"Image.png"]; |
| 4 |
2 Comments
neofar on July 5th, 2010
Gracias por el mensaje @Zelios … a veces necesitamos un empujoncito para corregir las cosas

Zelios Ariex on July 5th, 2010
Hola me ha gustado mucho tu blog, espero que sigas asi ;D ,en fin en la linea 6 creo que se solucionaria si en vez de:
“CGImageRef spriteImage = [UIImage imageNamed:cadena].CGImage;”
sería:
“CGImageRef spriteImage = [UIImage imageNamed:@"cadena"].CGImage;”
Bueno espero que aya ayudado y ánimo sigue asi