From 6e0c216e96310c771ec601a994b465ba45dd0de9 Mon Sep 17 00:00:00 2001 From: chsieh Date: Sun, 19 Dec 2010 12:50:15 -0800 Subject: [PATCH] Added texture loading functionalities. --- Classes/Foundation/Common/Assert.h | 1 + Classes/Foundation/Common/GlobalDefines.h | 2 +- .../Foundation/GraphicsServices/OpenGLServices.h | 30 +++- .../Foundation/GraphicsServices/OpenGLServices.mm | 143 ++++++++++++++++- Classes/Foundation/GraphicsServices/RenderTarget.h | 12 +- Classes/Foundation/OSInterface/EAGLView.h | 12 +- Classes/Foundation/OSInterface/EAGLView.m | 173 ++++++++++---------- .../Foundation/OSInterface/LittlestAppDelegate.h | 19 +-- .../Foundation/OSInterface/LittlestAppDelegate.m | 8 - .../OSInterface/LittlestViewController.h | 8 +- .../OSInterface/LittlestViewController.m | 8 - Littlest.xcodeproj/project.pbxproj | 4 + 12 files changed, 273 insertions(+), 147 deletions(-) diff --git a/Classes/Foundation/Common/Assert.h b/Classes/Foundation/Common/Assert.h index d72fd4a..bf465fa 100755 --- a/Classes/Foundation/Common/Assert.h +++ b/Classes/Foundation/Common/Assert.h @@ -62,6 +62,7 @@ #else +// Note that the expression is still evaluated, since we declared this as an inlined function, rather than a macro. slInline void Assert(bool expression) {} slInline void AssertMsg(bool expression, char* msg, ...) {} diff --git a/Classes/Foundation/Common/GlobalDefines.h b/Classes/Foundation/Common/GlobalDefines.h index d3faf15..7dde617 100755 --- a/Classes/Foundation/Common/GlobalDefines.h +++ b/Classes/Foundation/Common/GlobalDefines.h @@ -77,7 +77,7 @@ #define IS_POWER_OF_TWO(x) ( ((x) & -(x)) == (x) ) -#pragma warning(disable:4146) // =( +//#pragma warning(disable:4146) // =( #define ALIGN_UP(x, ALIGNMENT) ( ((x) + (ALIGNMENT) - 1) & -(ALIGNMENT) ) #define ALIGN_DOWN(x, ALIGNMENT) ( (x) & -(ALIGNMENT) ) diff --git a/Classes/Foundation/GraphicsServices/OpenGLServices.h b/Classes/Foundation/GraphicsServices/OpenGLServices.h index 28c736d..819ba12 100644 --- a/Classes/Foundation/GraphicsServices/OpenGLServices.h +++ b/Classes/Foundation/GraphicsServices/OpenGLServices.h @@ -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 #include #include #include +#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 ); }; diff --git a/Classes/Foundation/GraphicsServices/OpenGLServices.mm b/Classes/Foundation/GraphicsServices/OpenGLServices.mm index d89147e..236059e 100644 --- a/Classes/Foundation/GraphicsServices/OpenGLServices.mm +++ b/Classes/Foundation/GraphicsServices/OpenGLServices.mm @@ -1,18 +1,155 @@ +#import +#import + #include "OpenGLServices.h" #include "RenderTarget.h" -#import +//---------------------------------------------------------------------------------------- +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]; + } +} diff --git a/Classes/Foundation/GraphicsServices/RenderTarget.h b/Classes/Foundation/GraphicsServices/RenderTarget.h index d9cb866..aad5d43 100644 --- a/Classes/Foundation/GraphicsServices/RenderTarget.h +++ b/Classes/Foundation/GraphicsServices/RenderTarget.h @@ -1,12 +1,12 @@ #pragma once -#include "Foundation/Common/GlobalInclude.h" - #include #include #include #include +#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; diff --git a/Classes/Foundation/OSInterface/EAGLView.h b/Classes/Foundation/OSInterface/EAGLView.h index 277392d..e8cf435 100644 --- a/Classes/Foundation/OSInterface/EAGLView.h +++ b/Classes/Foundation/OSInterface/EAGLView.h @@ -1,10 +1,4 @@ -// -// EAGLView.h -// Littlest -// -// Created by Doris Chen on 12/4/10. -// Copyright 2010 __MyCompanyName__. All rights reserved. -// +#pragma once #import @@ -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; diff --git a/Classes/Foundation/OSInterface/EAGLView.m b/Classes/Foundation/OSInterface/EAGLView.m index 4fb0237..8b79804 100644 --- a/Classes/Foundation/OSInterface/EAGLView.m +++ b/Classes/Foundation/OSInterface/EAGLView.m @@ -1,11 +1,3 @@ -// -// EAGLView.m -// Littlest -// -// Created by Doris Chen on 12/4/10. -// Copyright 2010 __MyCompanyName__. All rights reserved. -// - #import #import "EAGLView.h" @@ -25,139 +17,140 @@ // 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 diff --git a/Classes/Foundation/OSInterface/LittlestAppDelegate.h b/Classes/Foundation/OSInterface/LittlestAppDelegate.h index 8303682..7f66aca 100644 --- a/Classes/Foundation/OSInterface/LittlestAppDelegate.h +++ b/Classes/Foundation/OSInterface/LittlestAppDelegate.h @@ -1,22 +1,17 @@ -// -// LittlestAppDelegate.h -// Littlest -// -// Created by Doris Chen on 12/4/10. -// Copyright 2010 __MyCompanyName__. All rights reserved. -// +#pragma once #import @class LittlestViewController; -@interface LittlestAppDelegate : NSObject { - UIWindow *window; - LittlestViewController *viewController; +@interface LittlestAppDelegate : NSObject +{ + 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 diff --git a/Classes/Foundation/OSInterface/LittlestAppDelegate.m b/Classes/Foundation/OSInterface/LittlestAppDelegate.m index d38cd14..ad097b4 100644 --- a/Classes/Foundation/OSInterface/LittlestAppDelegate.m +++ b/Classes/Foundation/OSInterface/LittlestAppDelegate.m @@ -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" diff --git a/Classes/Foundation/OSInterface/LittlestViewController.h b/Classes/Foundation/OSInterface/LittlestViewController.h index 1d29ba7..1a5327e 100644 --- a/Classes/Foundation/OSInterface/LittlestViewController.h +++ b/Classes/Foundation/OSInterface/LittlestViewController.h @@ -1,10 +1,4 @@ -// -// LittlestViewController.h -// Littlest -// -// Created by Doris Chen on 12/4/10. -// Copyright 2010 __MyCompanyName__. All rights reserved. -// +#pragma once #import diff --git a/Classes/Foundation/OSInterface/LittlestViewController.m b/Classes/Foundation/OSInterface/LittlestViewController.m index b1ad024..784c79c 100644 --- a/Classes/Foundation/OSInterface/LittlestViewController.m +++ b/Classes/Foundation/OSInterface/LittlestViewController.m @@ -1,11 +1,3 @@ -// -// LittlestViewController.m -// Littlest -// -// Created by Doris Chen on 12/4/10. -// Copyright 2010 __MyCompanyName__. All rights reserved. -// - #import #import "LittlestViewController.h" diff --git a/Littlest.xcodeproj/project.pbxproj b/Littlest.xcodeproj/project.pbxproj index aa0e0a8..95f441e 100755 --- a/Littlest.xcodeproj/project.pbxproj +++ b/Littlest.xcodeproj/project.pbxproj @@ -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 = ""; }; 4BA0CDEF12BD6EB200EBB6F0 /* RenderTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTarget.h; sourceTree = ""; }; 4BA0CDF012BD6FE100EBB6F0 /* RenderTarget.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RenderTarget.mm; sourceTree = ""; }; + 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 = ""; }; /* 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; }; @@ -157,6 +160,7 @@ 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( + 4BA0CF4B12BEA74F00EBB6F0 /* CoreGraphics.framework */, 28FD15070DC6FC5B0079059D /* QuartzCore.framework */, 28FD14FF0DC6FC520079059D /* OpenGLES.framework */, 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, -- 1.7.0.4