ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ControlEngine / iPhone / Classes / OpenGLSprite.m
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 (file)
index 0000000..ca815f0
--- /dev/null
@@ -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