Added texture loading functionalities.
authorchsieh <chester.developer@hotmail.com>
Sun, 19 Dec 2010 20:50:15 +0000 (12:50 -0800)
committerchsieh <chester.developer@hotmail.com>
Sun, 19 Dec 2010 20:50:15 +0000 (12:50 -0800)
12 files changed:
Classes/Foundation/Common/Assert.h
Classes/Foundation/Common/GlobalDefines.h
Classes/Foundation/GraphicsServices/OpenGLServices.h
Classes/Foundation/GraphicsServices/OpenGLServices.mm
Classes/Foundation/GraphicsServices/RenderTarget.h
Classes/Foundation/OSInterface/EAGLView.h
Classes/Foundation/OSInterface/EAGLView.m
Classes/Foundation/OSInterface/LittlestAppDelegate.h
Classes/Foundation/OSInterface/LittlestAppDelegate.m
Classes/Foundation/OSInterface/LittlestViewController.h
Classes/Foundation/OSInterface/LittlestViewController.m
Littlest.xcodeproj/project.pbxproj

index d72fd4a..bf465fa 100755 (executable)
@@ -62,6 +62,7 @@
 \r
 #else\r
 \r
+// Note that the expression is still evaluated, since we declared this as an inlined function, rather than a macro.\r
 slInline void Assert(bool expression) {}\r
 slInline void AssertMsg(bool expression, char* msg, ...) {}\r
 \r
index d3faf15..7dde617 100755 (executable)
@@ -77,7 +77,7 @@
 \r
 #define IS_POWER_OF_TWO(x)        ( ((x) & -(x)) == (x) )\r
 \r
-#pragma warning(disable:4146) // =(\r
+//#pragma warning(disable:4146)     // =(\r
 #define ALIGN_UP(x, ALIGNMENT)    ( ((x) + (ALIGNMENT) - 1) & -(ALIGNMENT) )\r
 #define ALIGN_DOWN(x, ALIGNMENT)  ( (x) & -(ALIGNMENT) )\r
 \r
index 28c736d..819ba12 100644 (file)
@@ -4,15 +4,19 @@
  * This is a wrapper class around all OpenGL API calls in iOS. This completely abstracts
  *  away all mixes between the OS-specific calls in Objective-C and the C-style inteface of
  *  OpenGL.
+ *
+ * Since iPhone/iPad will be single/dual cores for the near-term future, we'll basically
+ *  only allow a single rendering context to exist at any given point in time. Therefore,
+ *  we should never need to set context other than during startup or shutdown.
  *****************************************************************************************/
 
-#include "Foundation/Common/GlobalInclude.h"
-
 #include <OpenGLES/ES1/gl.h>
 #include <OpenGLES/ES1/glext.h>
 #include <OpenGLES/ES2/gl.h>
 #include <OpenGLES/ES2/glext.h>
 
+#include "Foundation/Common/GlobalInclude.h"
+
 //----------------------------------------------------------------------------------------
 // Some forward declarations
 @class EAGLContext;
@@ -27,10 +31,28 @@ typedef GLuint TextureHandle;
 class OpenGLServices
 {
 public:
-       bool init();
+  enum
+  {
+    kMaxTextureSize = 512 * 512 * 4,
+  };
+  
+  OpenGLServices();
+  
+       bool init( EAGLContext* mainContext );
+  void destroy();
+  
+  bool initScratchMem();
+  void destroyScratchMem();
   
   bool setRenderTarget( RenderTarget& renderTarget );
+  bool present( RenderTarget& renderTarget );
+  
+  TextureHandle loadPNGTexture( const char* fileName );
+  void destroyTexture( TextureHandle texture );
        
 private:
-  EAGLContext* mGLContext;
+  EAGLContext*  mGLContext;
+  void*         mScratchMem;
+  
+  void setContext( EAGLContext* newContext );
 };
index d89147e..236059e 100644 (file)
+#import <QuartzCore/QuartzCore.h>
+#import <CoreGraphics/CoreGraphics.h>
+
 #include "OpenGLServices.h"
 #include "RenderTarget.h"
 
-#import <QuartzCore/QuartzCore.h>
+//----------------------------------------------------------------------------------------
+OpenGLServices::OpenGLServices() : mGLContext(NULL), mScratchMem(NULL)
+{
+}
+
+//----------------------------------------------------------------------------------------
+bool OpenGLServices::init( EAGLContext* mainContext )
+{
+  if ( mGLContext )
+  {
+    return false;
+  }
+
+  mGLContext = [mainContext retain];
+  Assert( [EAGLContext setCurrentContext:mGLContext] );
+  
+  initScratchMem();
+  
+  // Enable some common states.
+  glEnable( GL_TEXTURE_2D );
+
+  glEnable( GL_BLEND );
+
+  // We will premultiply alpha into the color channels of all textures (so no alpha animation).
+  // This is basically the A over B alpha scheme.
+  glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
+
+  glEnable( GL_DEPTH_TEST );
+  
+  return true;
+}
+
+//----------------------------------------------------------------------------------------
+void OpenGLServices::destroy()
+{
+  if ( !mGLContext )
+  {
+    return;
+  }
+
+  destroyScratchMem();
+  [mGLContext release];
+  [EAGLContext setCurrentContext:nil];
+}
+
+//----------------------------------------------------------------------------------------
+bool OpenGLServices::initScratchMem()
+{
+  if (!mScratchMem)
+  {
+    mScratchMem = malloc( kMaxTextureSize );
+    return mScratchMem != NULL;
+  }
+  return true;
+}
+
+//----------------------------------------------------------------------------------------
+void OpenGLServices::destroyScratchMem()
+{
+  if (mScratchMem)
+  {
+    free( mScratchMem );
+    mScratchMem = NULL;
+  }
+}
 
 //----------------------------------------------------------------------------------------
 bool OpenGLServices::setRenderTarget( RenderTarget& renderTarget )
 {
-#if defined(DEBUG)
   if (!renderTarget.getFramebuffer() || !glIsFramebuffer( renderTarget.getFramebuffer() ))
   {
     return false;
   }
-#endif
   
   glBindFramebuffer( GL_FRAMEBUFFER, renderTarget.getFramebuffer() );
   return true;
 }
+
+//----------------------------------------------------------------------------------------
+bool OpenGLServices::present( RenderTarget& renderTarget )
+{
+  GLuint colorBuffer = renderTarget.getColorBuffer();
+  if (!colorBuffer || !glIsRenderbuffer( colorBuffer ))
+  {
+    return false;
+  }
+
+  glBindRenderbuffer( GL_RENDERBUFFER, colorBuffer );
+  return [renderTarget.getContext() presentRenderbuffer:GL_RENDERBUFFER];
+}
+
+//----------------------------------------------------------------------------------------
+TextureHandle OpenGLServices::loadPNGTexture( const char* fileName )
+{
+  GLuint textureHandle;
+  glGenTextures( 1, &textureHandle );
+  if (!textureHandle)
+  {
+    return textureHandle;
+  }
+  
+  glBindTexture( GL_TEXTURE_2D, textureHandle );
+  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_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 );
+
+  // http://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-part-6_25.html
+  NSString* nsFileName = [NSString stringWithUTF8String:fileName];
+  NSString* nsPath = [[NSBundle mainBundle] pathForResource:nsFileName ofType:@"png"];
+  NSData* fileData = [[NSData alloc] initWithContentsOfFile:nsPath];
+  UIImage* image = [[UIImage alloc] initWithData:fileData];
+  AssertMessage( image != nil, "Image failed to load!\n" );
+
+  GLuint width  = CGImageGetWidth( image.CGImage );
+  GLuint height = CGImageGetHeight( image.CGImage );
+  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+  Assert( width * height * 4 <= kMaxTextureSize );
+  CGContextRef context = CGBitmapContextCreate( mScratchMem, 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, mScratchMem );
+  glGenerateMipmap( GL_TEXTURE_2D );
+
+  CGContextRelease(context);
+  [image release];
+  [fileData release];
+  
+  return textureHandle;
+}
+
+//----------------------------------------------------------------------------------------
+void OpenGLServices::destroyTexture( TextureHandle texture )
+{
+  glDeleteTextures( 1, &texture );
+}
+
+//----------------------------------------------------------------------------------------
+void OpenGLServices::setContext( EAGLContext* newContext )
+{
+  if (mGLContext != newContext)
+  {
+    mGLContext = newContext;
+    [EAGLContext setCurrentContext:newContext];
+  }
+}
index d9cb866..aad5d43 100644 (file)
@@ -1,12 +1,12 @@
 #pragma once
 
-#include "Foundation/Common/GlobalInclude.h"
-
 #include <OpenGLES/ES1/gl.h>
 #include <OpenGLES/ES1/glext.h>
 #include <OpenGLES/ES2/gl.h>
 #include <OpenGLES/ES2/glext.h>
 
+#include "Foundation/Common/GlobalInclude.h"
+
 @class EAGLContext;
 @class CAEAGLLayer;
 
@@ -45,9 +45,11 @@ public:
   bool          init( RenderTargetInitParams& params );
   void          destroy();
   
-  uint32_t      getWidth()  { return mRenderBufferWidth; }
-  uint32_t      getHeight() { return mRenderBufferHeight; }
-  GLuint        getFramebuffer() { return mFramebuffer; }
+  EAGLContext*  getContext() const { return mContext; }
+  uint32_t      getWidth() const  { return mRenderBufferWidth; }
+  uint32_t      getHeight() const { return mRenderBufferHeight; }
+  GLuint        getFramebuffer() const { return mFramebuffer; }
+  GLuint        getColorBuffer() const { return mColorBuffer; }
 
 protected:
   EAGLContext*  mContext;
index 277392d..e8cf435 100644 (file)
@@ -1,10 +1,4 @@
-//
-//  EAGLView.h
-//  Littlest
-//
-//  Created by Doris Chen on 12/4/10.
-//  Copyright 2010 __MyCompanyName__. All rights reserved.
-//
+#pragma once
 
 #import <UIKit/UIKit.h>
 
@@ -19,7 +13,7 @@
 @interface EAGLView : UIView
 {
 @private
-    EAGLContext *context;
+    EAGLContext* context;
     
     // The pixel dimensions of the CAEAGLLayer.
     GLint framebufferWidth;
@@ -29,7 +23,7 @@
     GLuint defaultFramebuffer, colorRenderbuffer;
 }
 
-@property (nonatomic, retain) EAGLContext *context;
+@property (nonatomic, retain) EAGLContext* context;
 
 - (void)setFramebuffer;
 - (BOOL)presentFramebuffer;
index 4fb0237..8b79804 100644 (file)
@@ -1,11 +1,3 @@
-//
-//  EAGLView.m
-//  Littlest
-//
-//  Created by Doris Chen on 12/4/10.
-//  Copyright 2010 __MyCompanyName__. All rights reserved.
-//
-
 #import <QuartzCore/QuartzCore.h>
 
 #import "EAGLView.h"
 // You must implement this method
 + (Class)layerClass
 {
-    return [CAEAGLLayer class];
+  return [CAEAGLLayer class];
 }
 
 //-----------------------------------------------------------------------------------------------------------
 //The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:.
 - (id)initWithCoder:(NSCoder*)coder
 {
-    self = [super initWithCoder:coder];
+  self = [super initWithCoder:coder];
        if (self)
-    {
-        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
-        
-        eaglLayer.opaque = TRUE;
-        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
-                                        [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
-                                        kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
-                                        nil];
-    }
-    
-    return self;
+  {
+    CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
+
+    eaglLayer.opaque = TRUE;
+    eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
+                                    [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
+                                    kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
+                                    nil];
+  }
+
+  return self;
 }
 
 //-----------------------------------------------------------------------------------------------------------
 - (void)dealloc
 {
-    [self deleteFramebuffer];    
-    [context release];
-    
-    [super dealloc];
+  [self deleteFramebuffer];    
+  [context release];
+  
+  [super dealloc];
 }
 
 //-----------------------------------------------------------------------------------------------------------
 - (EAGLContext *)context
 {
-    return context;
+  return context;
 }
 
 //-----------------------------------------------------------------------------------------------------------
 - (void)setContext:(EAGLContext *)newContext
 {
-    if (context != newContext)
-    {
-        [self deleteFramebuffer];
-        [context release];
-               
-        context = [newContext retain];
-    }
+  if (context != newContext)
+  {
+    [self deleteFramebuffer];
+    [context release];
+    
+    context = [newContext retain];
+    [EAGLContext setCurrentContext:nil];
+  }
 }
 
 //-----------------------------------------------------------------------------------------------------------
 - (void)createFrameBuffer
 {
-    if (context && !defaultFramebuffer)
-    {
-        [EAGLContext setCurrentContext:context];
-        
-        // Create default framebuffer object.
-        glGenFramebuffers(1, &defaultFramebuffer);
-        glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
-        
-        // Create color render buffer and allocate backing store.
-        glGenRenderbuffers(1, &colorRenderbuffer);
-        glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
-        [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
-        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
-        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);
-        
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
-        
-        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
-            NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
-    }
+  if (context && !defaultFramebuffer)
+  {
+    [EAGLContext setCurrentContext:context];
+    
+    // Create default framebuffer object.
+    glGenFramebuffers(1, &defaultFramebuffer);
+    glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
+    
+    // Create color render buffer and allocate backing store.
+    glGenRenderbuffers(1, &colorRenderbuffer);
+    glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
+    [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
+    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
+    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);
+    
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
+    
+    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+      NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
+  }
 }
 
 //-----------------------------------------------------------------------------------------------------------
 - (void)deleteFramebuffer
 {
-    if (context)
+  if (context)
+  {
+    [EAGLContext setCurrentContext:context];
+    
+    if (defaultFramebuffer)
     {
-        [EAGLContext setCurrentContext:context];
-        
-        if (defaultFramebuffer)
-        {
-            glDeleteFramebuffers(1, &defaultFramebuffer);
-            defaultFramebuffer = 0;
-        }
-        
-        if (colorRenderbuffer)
-        {
-            glDeleteRenderbuffers(1, &colorRenderbuffer);
-            colorRenderbuffer = 0;
-        }
+      glDeleteFramebuffers(1, &defaultFramebuffer);
+      defaultFramebuffer = 0;
     }
+    
+    if (colorRenderbuffer)
+    {
+      glDeleteRenderbuffers(1, &colorRenderbuffer);
+      colorRenderbuffer = 0;
+    }
+  }
 }
 
 //-----------------------------------------------------------------------------------------------------------
 - (void)setFramebuffer
 {
-    if (context)
-    {
-        [EAGLContext setCurrentContext:context];
-        
-        if (!defaultFramebuffer)
-            [self createFrameBuffer];
-        
-        glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
-        
-        glViewport(0, 0, framebufferWidth, framebufferHeight);
-    }
+  if (context)
+  {
+    [EAGLContext setCurrentContext:context];
+    
+    if (!defaultFramebuffer)
+      [self createFrameBuffer];
+    
+    glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
+    
+    glViewport(0, 0, framebufferWidth, framebufferHeight);
+  }
 }
 
 //-----------------------------------------------------------------------------------------------------------
 - (BOOL)presentFramebuffer
 {
-    BOOL success = FALSE;
+  BOOL success = FALSE;
+  
+  if (context)
+  {
+    [EAGLContext setCurrentContext:context];
     
-    if (context)
-    {
-        [EAGLContext setCurrentContext:context];
-        
-        glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
-        
-        success = [context presentRenderbuffer:GL_RENDERBUFFER];
-    }
+    glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
     
-    return success;
+    success = [context presentRenderbuffer:GL_RENDERBUFFER];
+  }
+  
+  return success;
 }
 
 //-----------------------------------------------------------------------------------------------------------
 - (void)layoutSubviews
 {
-    // The framebuffer will be re-created at the beginning of the next setFramebuffer method call.
-    [self deleteFramebuffer];
+  // The framebuffer will be re-created at the beginning of the next setFramebuffer method call.
+  [self deleteFramebuffer];
 }
 
 @end
index 8303682..7f66aca 100644 (file)
@@ -1,22 +1,17 @@
-//
-//  LittlestAppDelegate.h
-//  Littlest
-//
-//  Created by Doris Chen on 12/4/10.
-//  Copyright 2010 __MyCompanyName__. All rights reserved.
-//
+#pragma once
 
 #import <UIKit/UIKit.h>
 
 @class LittlestViewController;
 
-@interface LittlestAppDelegate : NSObject <UIApplicationDelegate> {
-    UIWindow *window;
-    LittlestViewController *viewController;
+@interface LittlestAppDelegate : NSObject <UIApplicationDelegate>
+{
+    UIWindow* window;
+    LittlestViewController* viewController;
 }
 
-@property (nonatomic, retain) IBOutlet UIWindow *window;
-@property (nonatomic, retain) IBOutlet LittlestViewController *viewController;
+@property (nonatomic, retain) IBOutlet UIWindow* window;
+@property (nonatomic, retain) IBOutlet LittlestViewController* viewController;
 
 @end
 
index d38cd14..ad097b4 100644 (file)
@@ -1,11 +1,3 @@
-//
-//  LittlestAppDelegate.m
-//  Littlest
-//
-//  Created by Doris Chen on 12/4/10.
-//  Copyright 2010 __MyCompanyName__. All rights reserved.
-//
-
 #import "LittlestAppDelegate.h"
 #import "LittlestViewController.h"
 
index 1d29ba7..1a5327e 100644 (file)
@@ -1,10 +1,4 @@
-//
-//  LittlestViewController.h
-//  Littlest
-//
-//  Created by Doris Chen on 12/4/10.
-//  Copyright 2010 __MyCompanyName__. All rights reserved.
-//
+#pragma once
 
 #import <UIKit/UIKit.h>
 
index b1ad024..784c79c 100644 (file)
@@ -1,11 +1,3 @@
-//
-//  LittlestViewController.m
-//  Littlest
-//
-//  Created by Doris Chen on 12/4/10.
-//  Copyright 2010 __MyCompanyName__. All rights reserved.
-//
-
 #import <QuartzCore/QuartzCore.h>
 
 #import "LittlestViewController.h"
index aa0e0a8..95f441e 100755 (executable)
@@ -26,6 +26,7 @@
                4B90648612B426FE00655D84 /* Standard.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 4B90648512B426FE00655D84 /* Standard.fsh */; };
                4BA0CDCE12BD655200EBB6F0 /* OpenGLServices.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BA0CDCD12BD655200EBB6F0 /* OpenGLServices.mm */; };
                4BA0CDF112BD6FE100EBB6F0 /* RenderTarget.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BA0CDF012BD6FE100EBB6F0 /* RenderTarget.mm */; };
+               4BA0CF4C12BEA74F00EBB6F0 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA0CF4B12BEA74F00EBB6F0 /* CoreGraphics.framework */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -77,6 +78,7 @@
                4BA0CDCD12BD655200EBB6F0 /* OpenGLServices.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenGLServices.mm; sourceTree = "<group>"; };
                4BA0CDEF12BD6EB200EBB6F0 /* RenderTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTarget.h; sourceTree = "<group>"; };
                4BA0CDF012BD6FE100EBB6F0 /* RenderTarget.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RenderTarget.mm; sourceTree = "<group>"; };
+               4BA0CF4B12BEA74F00EBB6F0 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
                8D1107310486CEB800E47090 /* Littlest-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Littlest-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
@@ -89,6 +91,7 @@
                                1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
                                28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */,
                                28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */,
+                               4BA0CF4C12BEA74F00EBB6F0 /* CoreGraphics.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                29B97323FDCFA39411CA2CEA /* Frameworks */ = {
                        isa = PBXGroup;
                        children = (
+                               4BA0CF4B12BEA74F00EBB6F0 /* CoreGraphics.framework */,
                                28FD15070DC6FC5B0079059D /* QuartzCore.framework */,
                                28FD14FF0DC6FC520079059D /* OpenGLES.framework */,
                                1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,