X-Git-Url: http://git.maemo.org/git/?p=mardrone;a=blobdiff_plain;f=mardrone%2FARDrone_SDK_Version_1_8_20110726%2FControlEngine%2FiPhone%2FClasses%2FOpenGLSprite.m;fp=mardrone%2FARDrone_SDK_Version_1_8_20110726%2FControlEngine%2FiPhone%2FClasses%2FOpenGLSprite.m;h=ca815f0597b5ebd4cb1dae24149f49a08fa445f3;hp=0000000000000000000000000000000000000000;hb=9ec9bc13b75d30bc45535c54a652934debfcea92;hpb=ae0a3c2dc0898400aca0dd6b439c5db8044db7b2 diff --git a/mardrone/ARDrone_SDK_Version_1_8_20110726/ControlEngine/iPhone/Classes/OpenGLSprite.m b/mardrone/ARDrone_SDK_Version_1_8_20110726/ControlEngine/iPhone/Classes/OpenGLSprite.m new file mode 100644 index 0000000..ca815f0 --- /dev/null +++ b/mardrone/ARDrone_SDK_Version_1_8_20110726/ControlEngine/iPhone/Classes/OpenGLSprite.m @@ -0,0 +1,232 @@ +/** + * @file OpenGLSprite.m + * + * Copyright 2009 Parrot SA. All rights reserved. + * @author D HAEYER Frederic + * @date 2009/10/26 + */ +#import "OpenGLSprite.h" + +#ifdef _cplusplus +extern "C" { +#endif + unsigned long RoundPower2(unsigned long x); + void BindTexture(Texture* texture); +#ifdef _cplusplus +} +#endif + +static GLfloat const vertices[] = +{ + 1.0f, -1.0f, + -1.0f, -1.0f, + 1.0f, 1.0f, + -1.0f, 1.0f, +}; + +static GLfloat const coordinates[] = +{ + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 1.0f, + 1.0f, 0.0f, +}; + +unsigned long RoundPower2(unsigned long x) +{ + int rval=512; + // rval<<=1 Is A Prettier Way Of Writing rval*=2; + while(rval < x) + rval <<= 1; + return rval; +} + +void BindTexture(Texture* texture) +{ + // Check whether the texture has already been generated + if(texture->state == INVALID) + { + // Generated the texture + // Note: this must NOT be done before the initialization of OpenGL (this is why it can NOT be done in "InitializeTexture") + glGenTextures(1, &texture->identifier); + printf("Video texture identifier : %d\n", texture->identifier); + texture->state = GENERATED; + } + + // Bind the texture + glBindTexture(GL_TEXTURE_2D, texture->identifier); + + // Check whether the texture data have already been sent to OpenGL + if(texture->state == GENERATED) + { + // Load the texture in the GPU + glTexImage2D(GL_TEXTURE_2D, 0, texture->format, texture->widthTexture, texture->heightTexture, 0, texture->format, texture->type, texture->data); + texture->state = SENT_TO_GPU; + } +} + +void InitTexture(Texture *texture, CGSize imageSize, CGSize screenSize, eSCALING scaling) +{ + int max_size = max(RoundPower2(imageSize.width), RoundPower2(imageSize.height)); + // Define the texture format + texture->widthImage = imageSize.width; + texture->heightImage = imageSize.height; + texture->widthTexture = max_size; + texture->heightTexture = max_size; + NSLog(@"%s sizes %d, %d, %d, %d, %@\n", __FUNCTION__, texture->widthImage, texture->heightImage, texture->widthTexture, texture->heightTexture, NSStringFromCGSize(screenSize)); + if(texture->bytesPerPixel == 2) + { + texture->format = GL_RGB; + texture->type = GL_UNSIGNED_SHORT_5_6_5; + } + else + { + texture->format = GL_RGBA; + texture->type = GL_UNSIGNED_BYTE; + } + + switch(scaling) + { + case NO_SCALING: + texture->scaleModelX = texture->heightImage / screenSize.width; + texture->scaleModelY = texture->widthImage / screenSize.height; + break; + case FIT_X: + texture->scaleModelX = (screenSize.height * texture->heightImage) / (screenSize.width * texture->widthImage); + texture->scaleModelY = 1.0f; + break; + case FIT_Y: + texture->scaleModelX = 1.0f; + texture->scaleModelY = (screenSize.width * texture->widthImage) / (screenSize.height * texture->heightImage); + break; + default: + texture->scaleModelX = 1.0f; + texture->scaleModelY = 1.0f; + break; + } + texture->scaleTextureX = texture->widthImage / (float)texture->widthTexture; + texture->scaleTextureY = texture->heightImage / (float)texture->heightTexture; +} + +@implementation OpenGLSprite +@synthesize position; +@synthesize rotation; +@synthesize scale; + +- (id)initWithPath:(NSString *)path withScaling:(eSCALING)_scaling withScreenSize:(CGSize)size +{ + if ((self = [super init])) + { + // Load the image + image = [UIImage imageWithContentsOfFile:path]; + + // ScreenSize + screenSize = size; + scaling = _scaling; + + // Init rotation, translation and scale + rotation.x = 0.0; + rotation.y = 0.0; + rotation.z = 0.0; + + position.x = 0.0; + position.y = 0.0; + position.z = 0.0; + + scale.x = 1.0; + scale.y = 1.0; + scale.z = 1.0; + + texture.bytesPerPixel = 4; + texture.format = GL_RGBA; + texture.type = GL_UNSIGNED_BYTE; + texture.state = INVALID; + InitTexture(&texture, image.size, screenSize, scaling); + + NSLog(@"Default Image size : %@", NSStringFromCGSize(image.size)); + oldSize = CGSizeMake(image.size.width, image.size.height); + oldBytesPerPixel = texture.bytesPerPixel; + + // Allocate memory to store the texture data + default_image = vp_os_malloc(texture.widthTexture * texture.heightTexture * texture.bytesPerPixel); + texture.data = default_image; + + CGContextRef context = CGBitmapContextCreate(texture.data, texture.widthTexture, texture.heightTexture, 8, texture.widthTexture * texture.bytesPerPixel, CGImageGetColorSpace(image.CGImage), kCGImageAlphaNoneSkipLast); + + // Draw the image into the texture + CGContextDrawImage(context, CGRectMake(0.0f, texture.heightTexture - texture.heightImage, texture.widthImage, texture.heightImage), image.CGImage); + + // Release the context (but keep the texture data buffer to make it possible modifying the texture in real-time) + CGContextRelease(context); + } + + return self; +} + +- (BOOL)ResetTexture +{ + BOOL result = NO; + if ((oldSize.width != texture.widthImage) || (oldSize.height != texture.heightImage) || (oldBytesPerPixel != texture.bytesPerPixel)) + { + NSLog(@"%s oldSize : %d, %d - texture : %d, %d, oldBytesPerPixel : %d", __FUNCTION__, (int)oldSize.width, (int)oldSize.height, (int)texture.widthImage, (int)texture.heightImage, oldBytesPerPixel); + CGSize current_size = CGSizeMake(texture.widthImage, texture.heightImage); + InitTexture(&texture, current_size, screenSize, scaling); + texture.state = GENERATED; + oldSize = current_size; + oldBytesPerPixel = texture.bytesPerPixel; + result = YES; + } + + return result; +} + +- (void)drawSelfIfNeeded:(BOOL)needed +{ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(position.x, position.y, position.z); + + [self ResetTexture]; + + // Scale Texture + glScalef(texture.scaleModelX * scale.x, texture.scaleModelY * scale.y, scale.z); + + glRotatef(rotation.x, 1.0, 0.0, 0.0); + glRotatef(rotation.y, 0.0, 1.0, 0.0); + glRotatef(rotation.z, 0.0, 0.0, 1.0); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef(texture.scaleTextureX, texture.scaleTextureY, 1.0f); + + glVertexPointer(2, GL_FLOAT, 0, vertices); + glTexCoordPointer(2, GL_FLOAT, 0, coordinates); + + // Bind the background texture if needed, resend to gpu + if(needed) + texture.state = GENERATED; + + BindTexture(&texture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + // Draw the background quad + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +} + +- (void)dealloc +{ + // Remove the texture from the GPU + if(texture.state != INVALID) + { + glDeleteTextures(1, &texture.identifier); + } + + // Free the memory allocated to store the texture data + vp_os_free(default_image); + [super dealloc]; +} +@end