SlideShare una empresa de Scribd logo
1 de 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

Más contenido relacionado

Último

Último (20)

Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 

Destacado

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
ThinkNow
 
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
Kurio // The Social Media Age(ncy)
 

Destacado (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

Notas del editor

  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