SlideShare ist ein Scribd-Unternehmen logo
1 von 143
The Best of Both Worlds:
Using UIKit with OpenGL

   Noel Llopis
   Snappy Touch

   Twitter: @snappytouch
About Me
iPhone development full time for a year and
a half. Flower Garden on the app store.
About Me
iPhone development full time for a year and
a half. Flower Garden on the app store.




 Many years in the games industry before
 that
Advantages of UIKit
Advantages of UIKit

 Lots   of saved time!
Advantages of UIKit

 Lotsof saved time!
 Familiar interface behavior
Advantages of UIKit

 Lots of saved time!
 Familiar interface behavior
 Good performance (hardware
  accelerated)
Reasons NOT To Use UIKit
Reasons NOT To Use UIKit

   Objective C
Reasons NOT To Use UIKit

 Objective C
 Not portable (beyond iPhone/iPod
  Touch/iPad/MacOS)
Reasons NOT To Use UIKit

 Objective C
 Not portable (beyond iPhone/iPod
  Touch/iPad/MacOS)
 Not as much control over memory and
  performance.
UIKit
UIKit
UIKit




        OpenGL
UIKit




        OpenGL
UIKit




        OpenGL
UIKit
           Opportunity




        OpenGL
What We’re Going To See
What We’re Going To See

   0: OpenGL view
What We’re Going To See

 0: OpenGL view
 1: Non-fullscreen
What We’re Going To See

 0: OpenGL view
 1: Non-fullscreen
 2: UIKit elements
What We’re Going To See

 0:   OpenGL view
 1:   Non-fullscreen
 2:   UIKit elements
 3:   Animations
What We’re Going To See

 0:   OpenGL view
 1:   Non-fullscreen
 2:   UIKit elements
 3:   Animations
 4:   Multiple OpenGL views
What We’re Going To See

 0:   OpenGL view
 1:   Non-fullscreen
 2:   UIKit elements
 3:   Animations
 4:   Multiple OpenGL views
 5:   Landscape orientation
What We’re Going To See

 0:   OpenGL view
 1:   Non-fullscreen
 2:   UIKit elements
 3:   Animations
 4:   Multiple OpenGL views
 5:   Landscape orientation
 6:   Content OpenGL -> UIKit
What We’re Going To See

 0:   OpenGL view
 1:   Non-fullscreen
 2:   UIKit elements
 3:   Animations
 4:   Multiple OpenGL views
 5:   Landscape orientation
 6:   Content OpenGL -> UIKit
 7:   Content UIKit -> OpenGL
The Basics: Displaying
  OpenGL Graphics
UIView
@interface GLGravityView : UIView
{
	 EAGLContext* context;
  ...
}
@interface GLGravityView : UIView
{
	 EAGLContext* context;
  ...
}


+ (Class) layerClass
{
	 return [CAEAGLLayer class];
}
@interface GLGravityView : UIView
{
	 EAGLContext* context;
  ...
}


+ (Class) layerClass
{
	 return [CAEAGLLayer class];
}

glBindRenderbufferOES(GL_RENDERBUFFER_OES,
                      bufferHandle);
[m_eaglContext renderbufferStorage:
          GL_RENDERBUFFER_OES
               fromDrawable:drawable];
UIView
Case 1:
Not Fullscreen
OpenGL
OpenGL




UITabBar
320 x 431
320 x 431

Set correct
projection
matrix
320 x 431

Set correct
projection
matrix

Set correct
viewport
Case 2:
Adding UIKit Elements
       On Top
Adding Subviews
Adding Subviews

   Can use addSubview: to add any
    children to OpenGL view.
Adding Subviews

 Can use addSubview: to add any
  children to OpenGL view.
 There used to be some vague warnings
  in the 2.x SDK docs about not doing
  that for “performance and instability”
  issues.
Hello
Performance Issues
Performance Issues

   Things were particularly bad when
    driving main loop with NSTimer (don’t
    do it!)
Performance Issues

 Things were particularly bad when
  driving main loop with NSTimer (don’t
  do it!)
 Using CADisplayLink (3.1 or higher)
  seems to help a lot.
Performance Issues

 Things were particularly bad when
  driving main loop with NSTimer (don’t
  do it!)
 Using CADisplayLink (3.1 or higher)
  seems to help a lot.
 If you display a very complex set of
  UIViews on top, disable update and
  rendering of OpenGL.
Recommendations
Recommendations

   Avoid really complex hierarchies on top
    of OpenGL
Recommendations

 Avoid really complex hierarchies on top
  of OpenGL
 Avoid large, transparent UIKit objects
Recommendations

 Avoid really complex hierarchies on top
  of OpenGL
 Avoid large, transparent UIKit objects
 Avoid objects that change very
  frequently (every frame)
Recommendations

 Avoid really complex hierarchies on top
  of OpenGL
 Avoid large, transparent UIKit objects
 Avoid objects that change very
  frequently (every frame)
 Perfect for buttons, labels, solid views
Case 3:
Animating an OpenGL
        view
Animations
Animations

   Do it like any other view! :-)
Animations

   Do it like any other view! :-)
Animations

   Do it like any other view! :-)


[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
[UIView setAnimationDelegate:self];
[UIView
setAnimationDidStopSelector:@selector(tabControlle
rDidDisappear)];
	 oldView.center = pt;
	 [m_plantCareViewController view].center =
careCenter;	
[UIView commitAnimations];
Animations
Animations

   Animating a full OpenGL view seems to
    add a significant performance hit.
Animations

 Animating a full OpenGL view seems to
  add a significant performance hit.
 If you can, disable update and render
  of OpenGL view until animation is
  complete.
Case 4:
Multiple OpenGL Views
Why Multiple OpenGL
Views?
Why Multiple OpenGL
Views?
   A lot of the time you can reuse a single
    OpenGL view. Especially if you’re just
    doing full screen.
Why Multiple OpenGL
Views?
 A lot of the time you can reuse a single
  OpenGL view. Especially if you’re just
  doing full screen.
 But sometimes you need more than
  one: flower and bouquet screens, or
  main game and character
  customization screens.
Why Multiple OpenGL
Views?
 A lot of the time you can reuse a single
  OpenGL view. Especially if you’re just
  doing full screen.
 But sometimes you need more than
  one: flower and bouquet screens, or
  main game and character
  customization screens.
 Sometimes you may even need to
  show them at the same time
  (transition or in same screen)
Multiple OpenGL Views
Multiple OpenGL Views

   Multiple ways:
Multiple OpenGL Views

 Multiple ways:
 One OpenGL context per view
  (prevents sharing of resources)
Multiple OpenGL Views

 Multiple ways:
 One OpenGL context per view
  (prevents sharing of resources)
 One render target per view (that’s
  what I did)
Multiple Render Targets
Multiple Render Targets

   Multiple render targets is extremely
    useful to render images offscreen
Multiple Render Targets

 Multiple render targets is extremely
  useful to render images offscreen
 Associate each OpenGL view with a
  new render target using that view as
  storage.
Multiple Render Targets

  Multiple render targets is extremely
   useful to render images offscreen
  Associate each OpenGL view with a
   new render target using that view as
   storage.

glBindFramebufferOES(GL_FRAMEBUFFER_OES,
buffer.m_frameBufferHandle);	
glBindRenderbufferOES(GL_RENDERBUFFER_OES,
buffer.m_colorBufferHandle);
SetViewport(Rect(0, buffer.m_height, 0,
buffer.m_width));
Multiple Render Targets
Multiple Render Targets

   Switch to each target as you render
    each view
Multiple Render Targets

 Switch to each target as you render
  each view
 Or on viewWillAppear: if you’re only
  switching between them.
Case 5:
Landscape Orientation
Landscape
Landscape

   You could treat the OpenGL view like
    any other and rotate it...
Landscape

   You could treat the OpenGL view like
    any other and rotate it...


                 UIWindow



                    UIView


           OpenGL
                             UIView
            view
Landscape
Landscape

   But Apple recommends against it (for
    performance reasons).
Landscape

 But Apple recommends against it (for
  performance reasons).
 Instead, create the OpenGL view in
  landscape mode and set rotate your
  projection matrix.
Landscape

 But Apple recommends against it (for
  performance reasons).
 Instead, create the OpenGL view in
  landscape mode and set rotate your
  projection matrix.

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glRotatef(-90, 0, 0, 1);
    glOrthof(0, 480, 0, 320, 0, 1);
Landscape and Hierarchy
Landscape and Hierarchy
   Since you’ll use other views, you’ll
    want to leave those rotated as usual.
Landscape and Hierarchy
 Since you’ll use other views, you’ll
  want to leave those rotated as usual.
 And put OpenGL view at the root.
Landscape and Hierarchy
 Since you’ll use other views, you’ll
  want to leave those rotated as usual.
 And put OpenGL view at the root.



                UIWindow
     OpenGL
      view




                 UIView



                           UIView
Case 6:
Rendering From OpenGL
       To UIKit
OpenGL -> UIKit
OpenGL -> UIKit

   Whenever you want to use something
    you rendered in OpenGL
OpenGL -> UIKit

 Whenever you want to use something
  you rendered in OpenGL
 For example, to save a screenshot to
  disk.
OpenGL -> UIKit

 Whenever you want to use something
  you rendered in OpenGL
 For example, to save a screenshot to
  disk.
 Or to update an image element on a
  button or UIView
OpenGL -> UIKit
OpenGL -> UIKit
OpenGL -> UIKit
OpenGL -> UIKit
OpenGL -> UIKit

   The easy part is getting the pixels
    back: glReadPixels
OpenGL -> UIKit

   The easy part is getting the pixels
    back: glReadPixels

	 glReadPixels(0,0,RenderTargetWidth,
RenderTargetHeight, GL_RGBA,
GL_UNSIGNED_BYTE, imageBuffer);
OpenGL -> UIKit
OpenGL -> UIKit

   The hard part is stuffing that into a
    UIImage!
OpenGL -> UIKit

          The hard part is stuffing that into a
           UIImage!
	   const float RowSize = RenderTargetWidth*4;

	   CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, imageBuffer, RenderTargetSize, NULL);
	   CGImageRef iref = CGImageCreate(RenderTargetWidth, RenderTargetHeight, 8, 32, RowSize,
	   	       	     	     	     	     	     	     CGColorSpaceCreateDeviceRGB(),
	   	       	     	     	     	     	     	     kCGImageAlphaLast | kCGBitmapByteOrderDefault, ref,
	   	       	     	     	     	     	     	     NULL, true, kCGRenderingIntentDefault);

	   uint8_t* contextBuffer = (uint8_t*)m_resources->m_scratch.Allocate(RenderTargetSize);
	   memset(contextBuffer, 0, RenderTargetSize);
	   CGContextRef context = CGBitmapContextCreate(contextBuffer, RenderTargetWidth, RenderTargetHeight, 8, RowS
	   	       	     	     	     	     	     	     	     CGImageGetColorSpace(iref),
	   	       	     	     	     	     	     	     	     kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Bi
	   CGContextTranslateCTM(context, 0.0, RenderTargetHeight);
	   CGContextScaleCTM(context, 1.0, -1.0);
	   CGContextDrawImage(context, CGRectMake(0.0, 0.0, RenderTargetWidth, RenderTargetHeight), iref);	
	   CGImageRef outputRef = CGBitmapContextCreateImage(context);

	   UIImage* image = [[UIImage alloc] initWithCGImage:outputRef];

	   CGImageRelease(outputRef);
	   CGContextRelease(context);
	   CGImageRelease(iref);
	   CGDataProviderRelease(ref);
OpenGL ->UIKit
OpenGL ->UIKit

   glReadPixels is slow
OpenGL ->UIKit

 glReadPixels is slow
 You need to create 2 temp buffers with
  the image data (in addition to the final
  UIImage). That adds up to quite a bit.
OpenGL ->UIKit

 glReadPixels is slow
 You need to create 2 temp buffers with
  the image data (in addition to the final
  UIImage). That adds up to quite a bit.
 You can use this to take higher-than-
  normal resolution screenshots.
Case 7:
Rendering From UIKit to
       OpenGL
UIKit -> OpenGL
UIKit -> OpenGL

   Need to do that whenever you want to
    create a texture with the contents you
    created in UIKit.
UIKit -> OpenGL

 Need to do that whenever you want to
  create a texture with the contents you
  created in UIKit.
 Font rendering
UIKit -> OpenGL

 Need to do that whenever you want to
  create a texture with the contents you
  created in UIKit.
 Font rendering
 Fancy Quartz2D bitmap creation/
  composition
UIKit -> OpenGL
UIKit -> OpenGL

   Once you have a UIImage, do inverse
    conversion and set texture data.
UIKit -> OpenGL

 Once you have a UIImage, do inverse
  conversion and set texture data.
 You can write to non 32-bit textures
  too.
UIKit -> OpenGL
    Code to print text directly on a texture
void TextureUtils::PrintToTexture(Texture& texture, const Rect& destRect, NSString* txt, UIFont* font, Sequ
scratch)
{
	   int width, height;
	   texture.GetDimensions(width, height);

	   CGColorSpaceRef	    colorSpace = CGColorSpaceCreateDeviceGray();
	   int sizeInBytes = height*width;
	   void* data = scratch.Allocate(sizeInBytes);
	   memset(data, 0, sizeInBytes);
	   CGContextRef context = CGBitmapContextCreate(data, width, height, 8, width, colorSpace, kCGImageAlphaNo
	   CGColorSpaceRelease(colorSpace);
	   CGContextSetGrayFillColor(context, 1.0f, 1.0f);
	   CGContextTranslateCTM(context, 0.0, height);
	   CGContextScaleCTM(context, 1.0, -1.0);
	   UIGraphicsPushContext(context);

	   	      [txt drawInRect:CGRectMake(destRect.left, destRect.bottom, destRect.Width(), destRect.Height())
	   	      	     	     	     withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignment

	   UIGraphicsPopContext();

	   texture.SetData(data, sizeInBytes);
	
	   CGContextRelease(context);
	   scratch.Reset();
}
Putting It All Together
Conclusions
Conclusions
Conclusions

   Very powerful to mix the two.
Conclusions

 Very powerful to mix the two.
 Saves lots of time and you get access
  to great tools.
Conclusions

 Very powerful to mix the two.
 Saves lots of time and you get access
  to great tools.
 Learn and appreciate Interface Builder
  (I turned it into a level editor for my
  latest project!)
Questions?

Slides and sample code on my web
site

Noel Llopis
Blog: http://gamesfromwithin.com
Email: noel@snappytouch.com
Twitter: @snappytouch

Weitere ähnliche Inhalte

Kürzlich hochgeladen

SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 

Kürzlich hochgeladen (20)

SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 

Empfohlen

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by HubspotMarius Sescu
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTExpeed Software
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 

Empfohlen (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

The Best of Both Worlds: Mixing UIKit With OpenGL

  • 1. The Best of Both Worlds: Using UIKit with OpenGL Noel Llopis Snappy Touch Twitter: @snappytouch
  • 2. About Me iPhone development full time for a year and a half. Flower Garden on the app store.
  • 3. About Me iPhone development full time for a year and a half. Flower Garden on the app store. Many years in the games industry before that
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 12. Advantages of UIKit  Lots of saved time!
  • 13. Advantages of UIKit  Lotsof saved time!  Familiar interface behavior
  • 14. Advantages of UIKit  Lots of saved time!  Familiar interface behavior  Good performance (hardware accelerated)
  • 15. Reasons NOT To Use UIKit
  • 16. Reasons NOT To Use UIKit  Objective C
  • 17. Reasons NOT To Use UIKit  Objective C  Not portable (beyond iPhone/iPod Touch/iPad/MacOS)
  • 18. Reasons NOT To Use UIKit  Objective C  Not portable (beyond iPhone/iPod Touch/iPad/MacOS)  Not as much control over memory and performance.
  • 19.
  • 20.
  • 21. UIKit
  • 22. UIKit
  • 23. UIKit OpenGL
  • 24. UIKit OpenGL
  • 25. UIKit OpenGL
  • 26. UIKit Opportunity OpenGL
  • 27.
  • 29. What We’re Going To See  0: OpenGL view
  • 30. What We’re Going To See  0: OpenGL view  1: Non-fullscreen
  • 31. What We’re Going To See  0: OpenGL view  1: Non-fullscreen  2: UIKit elements
  • 32. What We’re Going To See  0: OpenGL view  1: Non-fullscreen  2: UIKit elements  3: Animations
  • 33. What We’re Going To See  0: OpenGL view  1: Non-fullscreen  2: UIKit elements  3: Animations  4: Multiple OpenGL views
  • 34. What We’re Going To See  0: OpenGL view  1: Non-fullscreen  2: UIKit elements  3: Animations  4: Multiple OpenGL views  5: Landscape orientation
  • 35. What We’re Going To See  0: OpenGL view  1: Non-fullscreen  2: UIKit elements  3: Animations  4: Multiple OpenGL views  5: Landscape orientation  6: Content OpenGL -> UIKit
  • 36. What We’re Going To See  0: OpenGL view  1: Non-fullscreen  2: UIKit elements  3: Animations  4: Multiple OpenGL views  5: Landscape orientation  6: Content OpenGL -> UIKit  7: Content UIKit -> OpenGL
  • 37. The Basics: Displaying OpenGL Graphics
  • 38.
  • 40.
  • 41. @interface GLGravityView : UIView { EAGLContext* context; ... }
  • 42. @interface GLGravityView : UIView { EAGLContext* context; ... } + (Class) layerClass { return [CAEAGLLayer class]; }
  • 43. @interface GLGravityView : UIView { EAGLContext* context; ... } + (Class) layerClass { return [CAEAGLLayer class]; } glBindRenderbufferOES(GL_RENDERBUFFER_OES, bufferHandle); [m_eaglContext renderbufferStorage: GL_RENDERBUFFER_OES fromDrawable:drawable];
  • 46.
  • 47.
  • 48.
  • 51.
  • 52.
  • 54. 320 x 431 Set correct projection matrix
  • 55. 320 x 431 Set correct projection matrix Set correct viewport
  • 56. Case 2: Adding UIKit Elements On Top
  • 58. Adding Subviews  Can use addSubview: to add any children to OpenGL view.
  • 59. Adding Subviews  Can use addSubview: to add any children to OpenGL view.  There used to be some vague warnings in the 2.x SDK docs about not doing that for “performance and instability” issues.
  • 60.
  • 61.
  • 62. Hello
  • 64. Performance Issues  Things were particularly bad when driving main loop with NSTimer (don’t do it!)
  • 65. Performance Issues  Things were particularly bad when driving main loop with NSTimer (don’t do it!)  Using CADisplayLink (3.1 or higher) seems to help a lot.
  • 66. Performance Issues  Things were particularly bad when driving main loop with NSTimer (don’t do it!)  Using CADisplayLink (3.1 or higher) seems to help a lot.  If you display a very complex set of UIViews on top, disable update and rendering of OpenGL.
  • 68. Recommendations  Avoid really complex hierarchies on top of OpenGL
  • 69. Recommendations  Avoid really complex hierarchies on top of OpenGL  Avoid large, transparent UIKit objects
  • 70. Recommendations  Avoid really complex hierarchies on top of OpenGL  Avoid large, transparent UIKit objects  Avoid objects that change very frequently (every frame)
  • 71. Recommendations  Avoid really complex hierarchies on top of OpenGL  Avoid large, transparent UIKit objects  Avoid objects that change very frequently (every frame)  Perfect for buttons, labels, solid views
  • 72. Case 3: Animating an OpenGL view
  • 74. Animations  Do it like any other view! :-)
  • 75. Animations  Do it like any other view! :-)
  • 76. Animations  Do it like any other view! :-) [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:0.3]; [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(tabControlle rDidDisappear)]; oldView.center = pt; [m_plantCareViewController view].center = careCenter; [UIView commitAnimations];
  • 78. Animations  Animating a full OpenGL view seems to add a significant performance hit.
  • 79. Animations  Animating a full OpenGL view seems to add a significant performance hit.  If you can, disable update and render of OpenGL view until animation is complete.
  • 82. Why Multiple OpenGL Views?  A lot of the time you can reuse a single OpenGL view. Especially if you’re just doing full screen.
  • 83. Why Multiple OpenGL Views?  A lot of the time you can reuse a single OpenGL view. Especially if you’re just doing full screen.  But sometimes you need more than one: flower and bouquet screens, or main game and character customization screens.
  • 84. Why Multiple OpenGL Views?  A lot of the time you can reuse a single OpenGL view. Especially if you’re just doing full screen.  But sometimes you need more than one: flower and bouquet screens, or main game and character customization screens.  Sometimes you may even need to show them at the same time (transition or in same screen)
  • 86. Multiple OpenGL Views  Multiple ways:
  • 87. Multiple OpenGL Views  Multiple ways:  One OpenGL context per view (prevents sharing of resources)
  • 88. Multiple OpenGL Views  Multiple ways:  One OpenGL context per view (prevents sharing of resources)  One render target per view (that’s what I did)
  • 90. Multiple Render Targets  Multiple render targets is extremely useful to render images offscreen
  • 91. Multiple Render Targets  Multiple render targets is extremely useful to render images offscreen  Associate each OpenGL view with a new render target using that view as storage.
  • 92. Multiple Render Targets  Multiple render targets is extremely useful to render images offscreen  Associate each OpenGL view with a new render target using that view as storage. glBindFramebufferOES(GL_FRAMEBUFFER_OES, buffer.m_frameBufferHandle); glBindRenderbufferOES(GL_RENDERBUFFER_OES, buffer.m_colorBufferHandle); SetViewport(Rect(0, buffer.m_height, 0, buffer.m_width));
  • 94. Multiple Render Targets  Switch to each target as you render each view
  • 95. Multiple Render Targets  Switch to each target as you render each view  Or on viewWillAppear: if you’re only switching between them.
  • 98. Landscape  You could treat the OpenGL view like any other and rotate it...
  • 99. Landscape  You could treat the OpenGL view like any other and rotate it... UIWindow UIView OpenGL UIView view
  • 101. Landscape  But Apple recommends against it (for performance reasons).
  • 102. Landscape  But Apple recommends against it (for performance reasons).  Instead, create the OpenGL view in landscape mode and set rotate your projection matrix.
  • 103. Landscape  But Apple recommends against it (for performance reasons).  Instead, create the OpenGL view in landscape mode and set rotate your projection matrix. glMatrixMode(GL_PROJECTION); glLoadIdentity(); glRotatef(-90, 0, 0, 1); glOrthof(0, 480, 0, 320, 0, 1);
  • 105. Landscape and Hierarchy  Since you’ll use other views, you’ll want to leave those rotated as usual.
  • 106. Landscape and Hierarchy  Since you’ll use other views, you’ll want to leave those rotated as usual.  And put OpenGL view at the root.
  • 107. Landscape and Hierarchy  Since you’ll use other views, you’ll want to leave those rotated as usual.  And put OpenGL view at the root. UIWindow OpenGL view UIView UIView
  • 108. Case 6: Rendering From OpenGL To UIKit
  • 110. OpenGL -> UIKit  Whenever you want to use something you rendered in OpenGL
  • 111. OpenGL -> UIKit  Whenever you want to use something you rendered in OpenGL  For example, to save a screenshot to disk.
  • 112. OpenGL -> UIKit  Whenever you want to use something you rendered in OpenGL  For example, to save a screenshot to disk.  Or to update an image element on a button or UIView
  • 117. OpenGL -> UIKit  The easy part is getting the pixels back: glReadPixels
  • 118. OpenGL -> UIKit  The easy part is getting the pixels back: glReadPixels glReadPixels(0,0,RenderTargetWidth, RenderTargetHeight, GL_RGBA, GL_UNSIGNED_BYTE, imageBuffer);
  • 120. OpenGL -> UIKit  The hard part is stuffing that into a UIImage!
  • 121. OpenGL -> UIKit  The hard part is stuffing that into a UIImage! const float RowSize = RenderTargetWidth*4; CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, imageBuffer, RenderTargetSize, NULL); CGImageRef iref = CGImageCreate(RenderTargetWidth, RenderTargetHeight, 8, 32, RowSize, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaLast | kCGBitmapByteOrderDefault, ref, NULL, true, kCGRenderingIntentDefault); uint8_t* contextBuffer = (uint8_t*)m_resources->m_scratch.Allocate(RenderTargetSize); memset(contextBuffer, 0, RenderTargetSize); CGContextRef context = CGBitmapContextCreate(contextBuffer, RenderTargetWidth, RenderTargetHeight, 8, RowS CGImageGetColorSpace(iref), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Bi CGContextTranslateCTM(context, 0.0, RenderTargetHeight); CGContextScaleCTM(context, 1.0, -1.0); CGContextDrawImage(context, CGRectMake(0.0, 0.0, RenderTargetWidth, RenderTargetHeight), iref); CGImageRef outputRef = CGBitmapContextCreateImage(context); UIImage* image = [[UIImage alloc] initWithCGImage:outputRef]; CGImageRelease(outputRef); CGContextRelease(context); CGImageRelease(iref); CGDataProviderRelease(ref);
  • 123. OpenGL ->UIKit  glReadPixels is slow
  • 124. OpenGL ->UIKit  glReadPixels is slow  You need to create 2 temp buffers with the image data (in addition to the final UIImage). That adds up to quite a bit.
  • 125. OpenGL ->UIKit  glReadPixels is slow  You need to create 2 temp buffers with the image data (in addition to the final UIImage). That adds up to quite a bit.  You can use this to take higher-than- normal resolution screenshots.
  • 126. Case 7: Rendering From UIKit to OpenGL
  • 128. UIKit -> OpenGL  Need to do that whenever you want to create a texture with the contents you created in UIKit.
  • 129. UIKit -> OpenGL  Need to do that whenever you want to create a texture with the contents you created in UIKit.  Font rendering
  • 130. UIKit -> OpenGL  Need to do that whenever you want to create a texture with the contents you created in UIKit.  Font rendering  Fancy Quartz2D bitmap creation/ composition
  • 132. UIKit -> OpenGL  Once you have a UIImage, do inverse conversion and set texture data.
  • 133. UIKit -> OpenGL  Once you have a UIImage, do inverse conversion and set texture data.  You can write to non 32-bit textures too.
  • 134. UIKit -> OpenGL Code to print text directly on a texture void TextureUtils::PrintToTexture(Texture& texture, const Rect& destRect, NSString* txt, UIFont* font, Sequ scratch) { int width, height; texture.GetDimensions(width, height); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); int sizeInBytes = height*width; void* data = scratch.Allocate(sizeInBytes); memset(data, 0, sizeInBytes); CGContextRef context = CGBitmapContextCreate(data, width, height, 8, width, colorSpace, kCGImageAlphaNo CGColorSpaceRelease(colorSpace); CGContextSetGrayFillColor(context, 1.0f, 1.0f); CGContextTranslateCTM(context, 0.0, height); CGContextScaleCTM(context, 1.0, -1.0); UIGraphicsPushContext(context); [txt drawInRect:CGRectMake(destRect.left, destRect.bottom, destRect.Width(), destRect.Height()) withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignment UIGraphicsPopContext(); texture.SetData(data, sizeInBytes); CGContextRelease(context); scratch.Reset(); }
  • 135. Putting It All Together
  • 136.
  • 137.
  • 140. Conclusions  Very powerful to mix the two.
  • 141. Conclusions  Very powerful to mix the two.  Saves lots of time and you get access to great tools.
  • 142. Conclusions  Very powerful to mix the two.  Saves lots of time and you get access to great tools.  Learn and appreciate Interface Builder (I turned it into a level editor for my latest project!)
  • 143. Questions? Slides and sample code on my web site Noel Llopis Blog: http://gamesfromwithin.com Email: noel@snappytouch.com Twitter: @snappytouch

Hinweis der Redaktion

  1. Interesting perspective coming from console game development
  2. Why mix the two?
  3. Why mix the two?
  4. Why UIKit?
  5. You get all that great UI already made for you
  6. You also get view controllers, and all the behaviors, transitions, and animations
  7. And you also get Interface Builder!
  8. Each view has its graphics uploaded to video memory (not redrawn every time)
  9. Each view has its graphics uploaded to video memory (not redrawn every time)
  10. Each view has its graphics uploaded to video memory (not redrawn every time)
  11. - Don’t be scare of objective C though. It’s a great language - Those are some of the reasons more casual games use it
  12. - Don’t be scare of objective C though. It’s a great language - Those are some of the reasons more casual games use it
  13. - Don’t be scare of objective C though. It’s a great language - Those are some of the reasons more casual games use it
  14. Are games using both today?
  15. Usually two categories
  16. Usually two categories
  17. Usually two categories
  18. Usually two categories
  19. Usually two categories
  20. Usually two categories
  21. You can truly get the best of both worlds
  22. The GL gravity sample from the dev site
  23. That’s what does the magic and allows the rendering of OpenGL to be displayed in a view.
  24. That’s what does the magic and allows the rendering of OpenGL to be displayed in a view.
  25. That’s what does the magic and allows the rendering of OpenGL to be displayed in a view.
  26. But the point is that it’s just a view, so you can do most things you can do with a regular UIView. And that’s where the fun begins.
  27. As gamers we’re used to games taking up the whole screen And that’s what most games do on the iPhone as well But it doesn’t have to be that way
  28. Perfect performance
  29. Perfect performance
  30. Perfect performance
  31. I never saw any instability
  32. I never saw any instability
  33. addSubview anywhere The problem is that the UIKit is designed to be mostly static with animations in responses to events. Scene needs to be composed every time
  34. addSubview anywhere The problem is that the UIKit is designed to be mostly static with animations in responses to events. Scene needs to be composed every time
  35. Maybe because it can coordinate better the refresh of the screen with UIKit?
  36. Maybe because it can coordinate better the refresh of the screen with UIKit?
  37. Maybe because it can coordinate better the refresh of the screen with UIKit?
  38. This one’s easy!
  39. This one’s easy!
  40. This one’s easy!
  41. So you can still animate it transitioning to the game, and then you can start animating the game.
  42. So you can still animate it transitioning to the game, and then you can start animating the game.
  43. This is where it gets interesting
  44. You can lay the views out in IB for convenience
  45. You can lay the views out in IB for convenience
  46. You can lay the views out in IB for convenience
  47. For many uses: env maps, screenshots, advanced processing, etc
  48. For many uses: env maps, screenshots, advanced processing, etc
  49. For many uses: env maps, screenshots, advanced processing, etc
  50. This one can be a bit tricky
  51. Most games are in landscape!
  52. Most games are in landscape!
  53. Flower Garden does it in two places
  54. Flower Garden does it in two places
  55. The gist of it is: use correct color space and flip the image Source code on my web site
  56. The gist of it is: use correct color space and flip the image Source code on my web site
  57. You may be loading textures this way already (Apple samples do that)
  58. You may be loading textures this way already (Apple samples do that)
  59. - OpenGL view non full screen - Multiple OpenGL views (other screens) - UIKit elements on top - OpenGL -> UIKit (send bouquet) - UIKit -> OpenGL text from text field to texture