SlideShare a Scribd company logo
1 of 70
Download to read offline
coronalabs.com@walterluh
Corona
Building Native Apps
A digital canvas for everyone
®
NBC/Universal powers their campaign with Corona
coronalabs.com@walterluh
coronalabs.com@walterluh
Turning an idea into something real
+ + =
Software DevelopmentCreative
coronalabs.com@walterluh
Graphics
Yesterday Today Tomorrow
coronalabs.com@walterluh
Graphics
Circa 2000
coronalabs.com@walterluh
Graphics
Circa 2000
coronalabs.com@walterluh
Mobile Graphics
Circa 2005
coronalabs.com@walterluh
Mobile Graphics
Circa 2008
coronalabs.com@walterluh
Today
coronalabs.com@walterluh
coronalabs.com@walterluh
coronalabs.com@walterluh
What is Corona?
same code, multiple stores
develop 5-10x faster
SDK for native apps
...
coronalabs.com@walterluh
Breakthrough Productivity
36 hours
code+graphics+sound
(complete 2 level game)
14 hours
code+graphics+sound
(gameplay only)
“Angry Birds” “Fruit Ninja” “TinyWings”
12 hours
code+graphics+sound
(gameplay only)
“Developing directly in Xcode would have
been at least 5x more code than Corona”
– Unicorn Labs, Top 20 iPad eBook
Ship #1 apps 10x faster
coronalabs.com@walterluh
Not Just for Games
ESP Guitars CheeseMonger Planet Sushi Thai Cook
Visually stunning business apps
coronalabs.com@walterluh
Performance
Simplicity
Flexibility
Corona
The Sweet Spot
Staff Pick
coronalabs.com@walterluh
2-D vs 3-D
$ vs $$$
coronalabs.com@walterluh
Corona Graphics
Optimized OpenGL for 2-D
CONFIDENTIALcoronalabs.com
OpenGL in one line
Phone SDK.
// Display "myImage.png"
// ----------------------------------------------------------------------------
// OpenGLESTextureAppDelegate.m
// ----------------------------------------------------------------------------
#import "OpenGLESTextureAppDelegate.h"
#import "EAGLView.h"
#import "OpenGLESTextureViewController.h"
@implementation OpenGLESTextureAppDelegate
@synthesize window=_window;
@synthesize viewController=_viewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window.rootViewController = self.viewController;
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was
inactive. If the application was previously in the background, optionally refresh the user
interface.
*/
[self.viewController drawFrame];
}
- (void)dealloc
{
[_window release];
[_viewController release];
[super dealloc];
}
@end
// ----------------------------------------------------------------------------
// EAGLView.m
// ----------------------------------------------------------------------------
#import <QuartzCore/QuartzCore.h>
#import "EAGLView.h"
@interface EAGLView (PrivateMethods)
- (void)createFramebuffer;
- (void)deleteFramebuffer;
@end
@implementation EAGLView
@synthesize context;
// You must implement this method
+ (Class)layerClass
{
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];
if (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];
}
- (void)setContext:(EAGLContext *)newContext
{
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));
}
}
- (void)deleteFramebuffer
{
if (context) {
[EAGLContext setCurrentContext:context];
if (defaultFramebuffer) {
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);
}
}
- (BOOL)presentFramebuffer
{
BOOL success = FALSE;
if (context) {
[EAGLContext setCurrentContext:context];
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
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];
}
@end
// ----------------------------------------------------------------------------
// OpenGLESTextureViewController.m
// ----------------------------------------------------------------------------
#import <QuartzCore/QuartzCore.h>
#import "OpenGLESTextureViewController.h"
#import "EAGLView.h"
@interface OpenGLESTextureViewController ()
@property (nonatomic, retain) EAGLContext *context;
@property (nonatomic, assign) CADisplayLink *displayLink;
- (void) loadTexture;
@end
@implementation OpenGLESTextureViewController
@synthesize animating, context, displayLink;
- (void)awakeFromNib
{
EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!aContext)
NSLog(@"Failed to create ES context");
else if (![EAGLContext setCurrentContext:aContext])
NSLog(@"Failed to set ES context current");
self.context = aContext;
[aContext release];
[(EAGLView *)self.view setContext:context];
[(EAGLView *)self.view setFramebuffer];
[self loadTexture];
self.displayLink = nil;
}
- (void) loadTexture
{
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
NSString *path = [[NSBundle mainBundle] pathForResource:@"myImage" ofType:@"png"];
NSData *texData = [[NSData alloc] initWithContentsOfFile:path];
UIImage *image = [[UIImage alloc] initWithData:texData];
GLuint width = CGImageGetWidth(image.CGImage);
GLuint height = CGImageGetHeight(image.CGImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *imageData = malloc( height width 4 );
CGContextRef image_context = CGBitmapContextCreate( imageData, width, height, 8, 4
width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
CGColorSpaceRelease( colorSpace );
CGContextClearRect( image_context, CGRectMake( 0, 0, width, height ) );
CGContextTranslateCTM( image_context, 0, height - height );
CGContextDrawImage( image_context, CGRectMake( 0, 0, width, height ), image.CGImage );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
imageData);
CGContextRelease(image_context);
free(imageData);
[image release];
[texData release];
}
- (void)dealloc
{
glDeleteTextures(1, &textureID);
// Tear down context.
if ([EAGLContext currentContext] == context)
[EAGLContext setCurrentContext:nil];
[context release];
[super dealloc];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Tear down context.
if ([EAGLContext currentContext] == context)
[EAGLContext setCurrentContext:nil];
self.context = nil;
}
- (void)drawFrame
{
[(EAGLView *)self.view setFramebuffer];
// Replace the implementation of this method to do your own custom drawing.
static const GLfloat squareVertices[] = {
-0.5f, -0.33f,
0.5f, -0.33f,
-0.5f, 0.33f,
0.5f, 0.33f,
};
static const GLfloat texCoords[] = {
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0
};
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
[(EAGLView *)self.view presentFramebuffer];
}
@end
display.newImage("myImage.png")
coronalabs.com@walterluh
API for Designers
local image =
display.newImage("myImage.png")
-- Properties
image.x = 100
image.y = 100
image.rotation = 45
image.blendMode = "add"
-- Tween
transition.to( image, { alpha = 0.0 } )
coronalabs.com@walterluh
Intuitive Draw Order
Drawing Order Result
coronalabs.com@walterluh
Next-Generation Graphics
New 2.5D engine later this year!
coronalabs.com@walterluh
Corona
Rendering Engine
Virtual Machine
User
Input
Networking
Device
Device/OS
Native Mobile App
Text
StrokesFills
Bitmaps
Shapes
Objects Behaviors Dynamic Layout Events Device Capabilities Etc
Camera Mic
GPS Etc
Artwork Compiled Code Localized Strings Workflow
Developer
Assets
User Interface
Architecture
coronalabs.com@walterluh
Lua:an industry standard
coronalabs.com@walterluh
Small Code Size
1.4 MB
Footprint
coronalabs.com@walterluh
Lua types
nil
boolean
number
string
function
table
userdata
• JavaScript-like syntax
• Functions are closures
• Lexical scope (non-local vars)
• Objects are tables
coronalabs.com@walterluh
Lua vs Other Languages
if	
  (!carMoving)	
  {
	
   //	
  do	
  something
}	
  else	
  if	
  (noGas)	
  {
	
   //	
  do	
  something	
  else
}
for	
  (i=1;	
  i<=10;	
  i++)	
  {
	
   print(i)
}
for	
  (j=100;	
  j>0;	
  j-­‐-­‐)	
  {
	
   print(j)
}
if	
  (not	
  carMoving)	
  then
	
   -­‐-­‐	
  do	
  something
elseif	
  (noGas)	
  then
	
   -­‐-­‐	
  do	
  something	
  else
end
for	
  i	
  =	
  1,10	
  do
	
   print(i)
end
for	
  j	
  =	
  100,1,-­‐1	
  do
	
   print(j)
end
coronalabs.com@walterluh
array	
  =	
  {	
  "a",	
  "b",	
  100,	
  "hello"	
  }
dictionary	
  =	
  {	
  x=5,	
  y=7,	
  name="Joe"	
  }
t	
  =	
  {}	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐-­‐	
  empty	
  table
t[1]	
  =	
  "a"	
  	
  	
  	
  	
  	
  	
  	
  -­‐-­‐	
  numerical	
  index
t["x"]	
  =	
  5	
  	
  	
  	
  	
  	
  	
  	
  -­‐-­‐	
  key	
  index
t.x	
  =	
  5	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐-­‐	
  equivalent	
  property	
  access
t.hasProperties	
  =	
  true
t[array]	
  =	
  "Joe"	
  	
  -­‐-­‐	
  any	
  type	
  can	
  be	
  a	
  key!!!
t["printJoe"]	
  =	
  function()	
  print("Joe")	
  end
Lua objects areTables
coronalabs.com@walterluh
-­‐-­‐	
  create	
  empty	
  table
local	
  o	
  =	
  {}
-­‐-­‐	
  add	
  method
function	
  o:saySomething(	
  something	
  )
	
  	
  print(	
  something	
  )
end
-­‐-­‐	
  output	
  'hi'
o:saySomething(	
  "hi!"	
  )
Object methods
coronalabs.com@walterluh
-­‐-­‐	
  create	
  empty	
  table
local	
  o	
  =	
  {}
-­‐-­‐	
  add	
  method
local	
  function	
  f(	
  self,	
  something	
  )
	
  	
  print(	
  something	
  )
end
o.saySomething	
  =	
  f
-­‐-­‐	
  output	
  'hi'
o.saySomething(	
  o,	
  "hi!"	
  )
The ':' is syntactic sugar
coronalabs.com@walterluh
Arrays are 1-based
//	
  Other	
  languages:	
  index	
  begins	
  with	
  0	
  
array=['a','b','c'];
for	
  (	
  var	
  i=0;	
  i<arr.length;	
  i++)	
  {
	
  	
  log(	
  array[i]	
  )
}
-­‐-­‐	
  Lua:	
  index	
  begins	
  with	
  1
local	
  array	
  =	
  {'a','b','c'}
for	
  i=1,#array	
  do
	
  	
  print(	
  array[i]	
  )
end
coronalabs.com@walterluh
Corona Enterprise
• Integrate native libraries
• Wrap native code in your own Lua APIs
• Automate builds
Lua and Objective-C/C++ and Java
coronalabs.com@walterluh
Fast Iteration
coronalabs.com@walterluh
Demo
coronalabs.com@walterluh
Multiple Screen Sizes/Shapes
coronalabs.com@walterluh
Content Scaling in Corona
coronalabs.com@walterluh
Content Scaling
-­‐-­‐	
  config.lua
application	
  =	
  {
	
  	
  	
  	
  content	
  =	
  {
	
  	
  	
  	
  	
  	
  	
  	
  width	
  =	
  320,
	
  	
  	
  	
  	
  	
  	
  	
  height	
  =	
  480,
	
  	
  	
  	
  	
  	
  	
  	
  scale	
  =	
  "letterbox",
	
  	
  	
  	
  },
}
• Code in content units (not screen pixels)
• width/height specify content dimensions
• Scale mode determines how physical display is filled
coronalabs.com@walterluh
Retina Displays
coronalabs.com@walterluh
Retina Imaging in Corona
-­‐-­‐	
  config.lua
application	
  =	
  {
	
  	
  	
  	
  content	
  =	
  {
	
  	
  	
  	
  	
  	
  	
  	
  width	
  =	
  320,
	
  	
  	
  	
  	
  	
  	
  	
  height	
  =	
  480,
	
  	
  	
  	
  	
  	
  	
  	
  scale	
  =	
  "letterbox",
	
  	
  	
  	
  	
  	
  	
  	
  imageSuffix	
  =	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ["-­‐x15"]	
  =	
  1.5,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ["-­‐x2"]	
  =	
  2,
	
  	
  	
  	
  	
  	
  	
  	
  },
	
  	
  	
  	
  },
}
coronalabs.com@walterluh
Retina ImagingAPI
display.newImageRect(	
  imageName,	
  w,	
  h	
  )
• width/height in content units (not screen pixels)
• Best matching image file based on scale factor
• Suffixes in config.lua determine image/scale mapping
coronalabs.com@walterluh
API
Application Programming Interface Interaction
CONFIDENTIALcoronalabs.com
Hard Problems Made Easy
(e.g. how Corona taught me to love physics)
CONFIDENTIALcoronalabs.com
local sky = display.newImage( "clouds.png" )
CONFIDENTIALcoronalabs.com
CONFIDENTIALcoronalabs.com
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )
ground.x = 160
ground.y = 445
CONFIDENTIALcoronalabs.com
CONFIDENTIALcoronalabs.com
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )
ground.x = 160
ground.y = 445
local crate = display.newImage( "crate.png" )
crate.x = 180
crate.y = 80
crate.rotation = 10
CONFIDENTIALcoronalabs.com
CONFIDENTIALcoronalabs.com
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )
ground.x = 160
ground.y = 445
local crate = display.newImage( "crate.png" )
crate.x = 180
crate.y = 80
crate.rotation = 10
local physics = require( "physics" )
physics.start()
CONFIDENTIALcoronalabs.com
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )
ground.x = 160
ground.y = 445
local crate = display.newImage( "crate.png" )
crate.x = 180
crate.y = 80
crate.rotation = 10
local physics = require( "physics" )
physics.start()
physics.addBody( ground, { friction=0.5 } )
ground.bodyType = "static"
CONFIDENTIALcoronalabs.com
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )
ground.x = 160
ground.y = 445
local crate = display.newImage( "crate.png" )
crate.x = 180
crate.y = 80
crate.rotation = 10
local physics = require( "physics" )
physics.start()
physics.addBody( ground, { friction=0.5 } )
ground.bodyType = "static"
physics.addBody( crate, { density=2.0,
friction=0.5, bounce=0.3 } )
CONFIDENTIALcoronalabs.com
CONFIDENTIALcoronalabs.com
What if we want
lots of crates?
CONFIDENTIALcoronalabs.com
local crate = display.newImage( "crate.png" )
crate.x = 180
crate.y = -100
crate.rotation = 10
physics.addBody( crate, { density=2.0,
friction=0.5, bounce=0.3 } )
CONFIDENTIALcoronalabs.com
local function spawnCrate()
! local crate = display.newImage( "crate.png" )
! crate.x = math.random( 320 )
! crate.y = -100
! crate.rotation = 10
! physics.addBody( crate, { density=2.0,
friction=0.5, bounce=0.3 } )
end
timer.performWithDelay( 500, spawnCrate, 50 )
CONFIDENTIALcoronalabs.com
CONFIDENTIALcoronalabs.com
What if gravity was up
rather than down?
CONFIDENTIALcoronalabs.com
physics.setGravity( 0, 9.8 )
CONFIDENTIALcoronalabs.com
physics.setGravity( 0, -9.8 )
CONFIDENTIALcoronalabs.com
coronalabs.com@walterluh
Over 500APIs
coronalabs.com@walterluh
WebK
SQLite database
File read/write
Full Lua scripting language
Hardware-accelerated graphics
GPS, compass, accelerometer
Simple and complex physical bodies
Networking (TCP, FTP, HTTP, etc.)
Video playback (streaming or local)
Physical properties (mass, friction,
Joints, wheels, hinges, pulleys, etc.
Animated sprites with independent
Collision detection, including pre
OpenFeint game network support
Vector drawing APIs (shapes and
Native UI (keyboard, etc.)
Crypto (md4, md5, sha1, sha512,
Audio (sound effects or MP3)
Animation and transition libra
Facebook and Twitter libraries
Improved texture memory han
physics simulation
oto library
Tons of Features
<html5>
• OpenGL graphics
• Open AL audio
• Box2D Physics
• Texture atlases, sprites, ...
• Networking
• GPS, multitouch, accelerometer, ...
• Native web views, textfields, ...
• Camera, photo library, video, ...
• Services: ads, analytics, IAP, ...
• And much more!
coronalabs.com@walterluh
AmazingApps
World-class apps, developers, and community
coronalabs.com@walterluh
Thriving Ecosystem
Corona
Fireworks
Photoshop Plugin
Zwoptex
TextMate
Particle Candy
Corona Remote
Corona Project Manager
Lime
Sprite Deck
LuaGlider
Texture Packer
coronalabs.com@walterluh
No Coding Required
Build native apps using Photoshop/Kwik
coronalabs.com@walterluh
Demo
coronalabs.com@walterluh
coronalabs.com@walterluh
Developers like you
#1 #1
From Designers to Coders. From Indies to Studios.
coronalabs.com@walterluh
Anyone can be #1...with Corona
coronalabs.com@walterluh
Future Belongs toYou!
coronalabs.com@walterluh
Start today! it’s free
www.CoronaLabs.com

More Related Content

What's hot

Copy Your Favourite Nokia App with Qt
Copy Your Favourite Nokia App with QtCopy Your Favourite Nokia App with Qt
Copy Your Favourite Nokia App with Qtaccount inactive
 
CCM Escape Case Study - SkySQL Paris Meetup 17.12.2013
CCM Escape Case Study - SkySQL Paris Meetup 17.12.2013CCM Escape Case Study - SkySQL Paris Meetup 17.12.2013
CCM Escape Case Study - SkySQL Paris Meetup 17.12.2013MariaDB Corporation
 
a friend in need-a js indeed / Yonatan levin
a friend in need-a js indeed / Yonatan levina friend in need-a js indeed / Yonatan levin
a friend in need-a js indeed / Yonatan levingeektimecoil
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJSKyung Yeol Kim
 
Codestrong 2012 breakout session hacking titanium
Codestrong 2012 breakout session   hacking titaniumCodestrong 2012 breakout session   hacking titanium
Codestrong 2012 breakout session hacking titaniumAxway Appcelerator
 
Bs webgl소모임004
Bs webgl소모임004Bs webgl소모임004
Bs webgl소모임004Seonki Paik
 
The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84Mahmoud Samir Fayed
 
Android RenderScript on LLVM
Android RenderScript on LLVMAndroid RenderScript on LLVM
Android RenderScript on LLVMJohn Lee
 
The Next Generation Qt Item Views
The Next Generation Qt Item ViewsThe Next Generation Qt Item Views
The Next Generation Qt Item Viewsaccount inactive
 
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...Ontico
 
HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?Ankara JUG
 
The Ring programming language version 1.6 book - Part 86 of 189
The Ring programming language version 1.6 book - Part 86 of 189The Ring programming language version 1.6 book - Part 86 of 189
The Ring programming language version 1.6 book - Part 86 of 189Mahmoud Samir Fayed
 
Best Practices in Qt Quick/QML - Part II
Best Practices in Qt Quick/QML - Part IIBest Practices in Qt Quick/QML - Part II
Best Practices in Qt Quick/QML - Part IIICS
 
Cluj Big Data Meetup - Big Data in Practice
Cluj Big Data Meetup - Big Data in PracticeCluj Big Data Meetup - Big Data in Practice
Cluj Big Data Meetup - Big Data in PracticeSteffen Wenz
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013Laurent_VB
 

What's hot (20)

The Future of Qt Widgets
The Future of Qt WidgetsThe Future of Qt Widgets
The Future of Qt Widgets
 
Copy Your Favourite Nokia App with Qt
Copy Your Favourite Nokia App with QtCopy Your Favourite Nokia App with Qt
Copy Your Favourite Nokia App with Qt
 
Why Grails?
Why Grails?Why Grails?
Why Grails?
 
CCM Escape Case Study - SkySQL Paris Meetup 17.12.2013
CCM Escape Case Study - SkySQL Paris Meetup 17.12.2013CCM Escape Case Study - SkySQL Paris Meetup 17.12.2013
CCM Escape Case Study - SkySQL Paris Meetup 17.12.2013
 
a friend in need-a js indeed / Yonatan levin
a friend in need-a js indeed / Yonatan levina friend in need-a js indeed / Yonatan levin
a friend in need-a js indeed / Yonatan levin
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJS
 
Codestrong 2012 breakout session hacking titanium
Codestrong 2012 breakout session   hacking titaniumCodestrong 2012 breakout session   hacking titanium
Codestrong 2012 breakout session hacking titanium
 
Bs webgl소모임004
Bs webgl소모임004Bs webgl소모임004
Bs webgl소모임004
 
D3.js workshop
D3.js workshopD3.js workshop
D3.js workshop
 
The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84
 
Android RenderScript on LLVM
Android RenderScript on LLVMAndroid RenderScript on LLVM
Android RenderScript on LLVM
 
A More Flash Like Web?
A More Flash Like Web?A More Flash Like Web?
A More Flash Like Web?
 
The Next Generation Qt Item Views
The Next Generation Qt Item ViewsThe Next Generation Qt Item Views
The Next Generation Qt Item Views
 
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...
 
V8
V8V8
V8
 
HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?
 
The Ring programming language version 1.6 book - Part 86 of 189
The Ring programming language version 1.6 book - Part 86 of 189The Ring programming language version 1.6 book - Part 86 of 189
The Ring programming language version 1.6 book - Part 86 of 189
 
Best Practices in Qt Quick/QML - Part II
Best Practices in Qt Quick/QML - Part IIBest Practices in Qt Quick/QML - Part II
Best Practices in Qt Quick/QML - Part II
 
Cluj Big Data Meetup - Big Data in Practice
Cluj Big Data Meetup - Big Data in PracticeCluj Big Data Meetup - Big Data in Practice
Cluj Big Data Meetup - Big Data in Practice
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013
 

Viewers also liked

Unleashing the Power of 3D with WebJS
Unleashing the Power of 3D with WebJSUnleashing the Power of 3D with WebJS
Unleashing the Power of 3D with WebJSFITC
 
Tools of the Processing Trade with David Bouchard
 Tools of the Processing Trade with David Bouchard Tools of the Processing Trade with David Bouchard
Tools of the Processing Trade with David BouchardFITC
 
The Future of Motion/Gesture Technology
The Future of Motion/Gesture TechnologyThe Future of Motion/Gesture Technology
The Future of Motion/Gesture TechnologyFITC
 
Empowering the “Mobile Web” with Chris Mills
Empowering the “Mobile Web” with Chris MillsEmpowering the “Mobile Web” with Chris Mills
Empowering the “Mobile Web” with Chris MillsFITC
 
React For Vikings
React For VikingsReact For Vikings
React For VikingsFITC
 
21st Century Crystal Ball
21st Century Crystal Ball21st Century Crystal Ball
21st Century Crystal BallFITC
 

Viewers also liked (6)

Unleashing the Power of 3D with WebJS
Unleashing the Power of 3D with WebJSUnleashing the Power of 3D with WebJS
Unleashing the Power of 3D with WebJS
 
Tools of the Processing Trade with David Bouchard
 Tools of the Processing Trade with David Bouchard Tools of the Processing Trade with David Bouchard
Tools of the Processing Trade with David Bouchard
 
The Future of Motion/Gesture Technology
The Future of Motion/Gesture TechnologyThe Future of Motion/Gesture Technology
The Future of Motion/Gesture Technology
 
Empowering the “Mobile Web” with Chris Mills
Empowering the “Mobile Web” with Chris MillsEmpowering the “Mobile Web” with Chris Mills
Empowering the “Mobile Web” with Chris Mills
 
React For Vikings
React For VikingsReact For Vikings
React For Vikings
 
21st Century Crystal Ball
21st Century Crystal Ball21st Century Crystal Ball
21st Century Crystal Ball
 

Similar to Building Native Apps- A Digital Canvas for Coders and Designers with Walter Luh

Unconventional webapps with gwt:elemental & html5
Unconventional webapps with gwt:elemental & html5Unconventional webapps with gwt:elemental & html5
Unconventional webapps with gwt:elemental & html5firenze-gtug
 
Richard Salter: Using the Titanium OpenGL Module
Richard Salter: Using the Titanium OpenGL ModuleRichard Salter: Using the Titanium OpenGL Module
Richard Salter: Using the Titanium OpenGL ModuleAxway Appcelerator
 
1. Modify code to change cube into pyramid.2. Make the pyramid int.pdf
1. Modify code to change cube into pyramid.2. Make the pyramid int.pdf1. Modify code to change cube into pyramid.2. Make the pyramid int.pdf
1. Modify code to change cube into pyramid.2. Make the pyramid int.pdfalokopticalswatchco0
 
Webgl para JavaScripters
Webgl para JavaScriptersWebgl para JavaScripters
Webgl para JavaScriptersgerbille
 
Google's HTML5 Work: what's next?
Google's HTML5 Work: what's next?Google's HTML5 Work: what's next?
Google's HTML5 Work: what's next?Patrick Chanezon
 
Intro to computer vision in .net
Intro to computer vision in .netIntro to computer vision in .net
Intro to computer vision in .netStephen Lorello
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Chris Alfano
 
How to build a html5 websites.v1
How to build a html5 websites.v1How to build a html5 websites.v1
How to build a html5 websites.v1Bitla Software
 
V8 javascript engine for フロントエンドデベロッパー
V8 javascript engine for フロントエンドデベロッパーV8 javascript engine for フロントエンドデベロッパー
V8 javascript engine for フロントエンドデベロッパーTaketoshi 青野健利
 
Jetpack Compose - Hands-on February 2020
Jetpack Compose - Hands-on February 2020Jetpack Compose - Hands-on February 2020
Jetpack Compose - Hands-on February 2020Pedro Veloso
 
MS TechDays 2011 - HTML 5 All the Awesome Bits
MS TechDays 2011 - HTML 5 All the Awesome BitsMS TechDays 2011 - HTML 5 All the Awesome Bits
MS TechDays 2011 - HTML 5 All the Awesome BitsSpiffy
 
Installing Games Sucks, Learn WebGL
Installing Games Sucks, Learn WebGLInstalling Games Sucks, Learn WebGL
Installing Games Sucks, Learn WebGLCorey Clark, Ph.D.
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Remy Sharp
 
Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02PL dream
 
Browsers with Wings
Browsers with WingsBrowsers with Wings
Browsers with WingsRemy Sharp
 

Similar to Building Native Apps- A Digital Canvas for Coders and Designers with Walter Luh (20)

Intro to HTML5
Intro to HTML5Intro to HTML5
Intro to HTML5
 
Unconventional webapps with gwt:elemental & html5
Unconventional webapps with gwt:elemental & html5Unconventional webapps with gwt:elemental & html5
Unconventional webapps with gwt:elemental & html5
 
COLLADA & WebGL
COLLADA & WebGLCOLLADA & WebGL
COLLADA & WebGL
 
Richard Salter: Using the Titanium OpenGL Module
Richard Salter: Using the Titanium OpenGL ModuleRichard Salter: Using the Titanium OpenGL Module
Richard Salter: Using the Titanium OpenGL Module
 
1. Modify code to change cube into pyramid.2. Make the pyramid int.pdf
1. Modify code to change cube into pyramid.2. Make the pyramid int.pdf1. Modify code to change cube into pyramid.2. Make the pyramid int.pdf
1. Modify code to change cube into pyramid.2. Make the pyramid int.pdf
 
HTML5 video filters
HTML5 video filtersHTML5 video filters
HTML5 video filters
 
Webgl para JavaScripters
Webgl para JavaScriptersWebgl para JavaScripters
Webgl para JavaScripters
 
Google's HTML5 Work: what's next?
Google's HTML5 Work: what's next?Google's HTML5 Work: what's next?
Google's HTML5 Work: what's next?
 
Intro to computer vision in .net
Intro to computer vision in .netIntro to computer vision in .net
Intro to computer vision in .net
 
Core animation
Core animationCore animation
Core animation
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
 
How to build a html5 websites.v1
How to build a html5 websites.v1How to build a html5 websites.v1
How to build a html5 websites.v1
 
V8 javascript engine for フロントエンドデベロッパー
V8 javascript engine for フロントエンドデベロッパーV8 javascript engine for フロントエンドデベロッパー
V8 javascript engine for フロントエンドデベロッパー
 
Jetpack Compose - Hands-on February 2020
Jetpack Compose - Hands-on February 2020Jetpack Compose - Hands-on February 2020
Jetpack Compose - Hands-on February 2020
 
Why Grails
Why GrailsWhy Grails
Why Grails
 
MS TechDays 2011 - HTML 5 All the Awesome Bits
MS TechDays 2011 - HTML 5 All the Awesome BitsMS TechDays 2011 - HTML 5 All the Awesome Bits
MS TechDays 2011 - HTML 5 All the Awesome Bits
 
Installing Games Sucks, Learn WebGL
Installing Games Sucks, Learn WebGLInstalling Games Sucks, Learn WebGL
Installing Games Sucks, Learn WebGL
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
 
Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02
 
Browsers with Wings
Browsers with WingsBrowsers with Wings
Browsers with Wings
 

More from FITC

Cut it up
Cut it upCut it up
Cut it upFITC
 
Designing for Digital Health
Designing for Digital HealthDesigning for Digital Health
Designing for Digital HealthFITC
 
Profiling JavaScript Performance
Profiling JavaScript PerformanceProfiling JavaScript Performance
Profiling JavaScript PerformanceFITC
 
Surviving Your Tech Stack
Surviving Your Tech StackSurviving Your Tech Stack
Surviving Your Tech StackFITC
 
How to Pitch Your First AR Project
How to Pitch Your First AR ProjectHow to Pitch Your First AR Project
How to Pitch Your First AR ProjectFITC
 
Start by Understanding the Problem, Not by Delivering the Answer
Start by Understanding the Problem, Not by Delivering the AnswerStart by Understanding the Problem, Not by Delivering the Answer
Start by Understanding the Problem, Not by Delivering the AnswerFITC
 
Cocaine to Carrots: The Art of Telling Someone Else’s Story
Cocaine to Carrots: The Art of Telling Someone Else’s StoryCocaine to Carrots: The Art of Telling Someone Else’s Story
Cocaine to Carrots: The Art of Telling Someone Else’s StoryFITC
 
Everyday Innovation
Everyday InnovationEveryday Innovation
Everyday InnovationFITC
 
HyperLight Websites
HyperLight WebsitesHyperLight Websites
HyperLight WebsitesFITC
 
Everything is Terrifying
Everything is TerrifyingEverything is Terrifying
Everything is TerrifyingFITC
 
Post-Earth Visions: Designing for Space and the Future Human
Post-Earth Visions: Designing for Space and the Future HumanPost-Earth Visions: Designing for Space and the Future Human
Post-Earth Visions: Designing for Space and the Future HumanFITC
 
The Rise of the Creative Social Influencer (and How to Become One)
The Rise of the Creative Social Influencer (and How to Become One)The Rise of the Creative Social Influencer (and How to Become One)
The Rise of the Creative Social Influencer (and How to Become One)FITC
 
East of the Rockies: Developing an AR Game
East of the Rockies: Developing an AR GameEast of the Rockies: Developing an AR Game
East of the Rockies: Developing an AR GameFITC
 
Creating a Proactive Healthcare System
Creating a Proactive Healthcare SystemCreating a Proactive Healthcare System
Creating a Proactive Healthcare SystemFITC
 
World Transformation: The Secret Agenda of Product Design
World Transformation: The Secret Agenda of Product DesignWorld Transformation: The Secret Agenda of Product Design
World Transformation: The Secret Agenda of Product DesignFITC
 
The Power of Now
The Power of NowThe Power of Now
The Power of NowFITC
 
High Performance PWAs
High Performance PWAsHigh Performance PWAs
High Performance PWAsFITC
 
Rise of the JAMstack
Rise of the JAMstackRise of the JAMstack
Rise of the JAMstackFITC
 
From Closed to Open: A Journey of Self Discovery
From Closed to Open: A Journey of Self DiscoveryFrom Closed to Open: A Journey of Self Discovery
From Closed to Open: A Journey of Self DiscoveryFITC
 
Projects Ain’t Nobody Got Time For
Projects Ain’t Nobody Got Time ForProjects Ain’t Nobody Got Time For
Projects Ain’t Nobody Got Time ForFITC
 

More from FITC (20)

Cut it up
Cut it upCut it up
Cut it up
 
Designing for Digital Health
Designing for Digital HealthDesigning for Digital Health
Designing for Digital Health
 
Profiling JavaScript Performance
Profiling JavaScript PerformanceProfiling JavaScript Performance
Profiling JavaScript Performance
 
Surviving Your Tech Stack
Surviving Your Tech StackSurviving Your Tech Stack
Surviving Your Tech Stack
 
How to Pitch Your First AR Project
How to Pitch Your First AR ProjectHow to Pitch Your First AR Project
How to Pitch Your First AR Project
 
Start by Understanding the Problem, Not by Delivering the Answer
Start by Understanding the Problem, Not by Delivering the AnswerStart by Understanding the Problem, Not by Delivering the Answer
Start by Understanding the Problem, Not by Delivering the Answer
 
Cocaine to Carrots: The Art of Telling Someone Else’s Story
Cocaine to Carrots: The Art of Telling Someone Else’s StoryCocaine to Carrots: The Art of Telling Someone Else’s Story
Cocaine to Carrots: The Art of Telling Someone Else’s Story
 
Everyday Innovation
Everyday InnovationEveryday Innovation
Everyday Innovation
 
HyperLight Websites
HyperLight WebsitesHyperLight Websites
HyperLight Websites
 
Everything is Terrifying
Everything is TerrifyingEverything is Terrifying
Everything is Terrifying
 
Post-Earth Visions: Designing for Space and the Future Human
Post-Earth Visions: Designing for Space and the Future HumanPost-Earth Visions: Designing for Space and the Future Human
Post-Earth Visions: Designing for Space and the Future Human
 
The Rise of the Creative Social Influencer (and How to Become One)
The Rise of the Creative Social Influencer (and How to Become One)The Rise of the Creative Social Influencer (and How to Become One)
The Rise of the Creative Social Influencer (and How to Become One)
 
East of the Rockies: Developing an AR Game
East of the Rockies: Developing an AR GameEast of the Rockies: Developing an AR Game
East of the Rockies: Developing an AR Game
 
Creating a Proactive Healthcare System
Creating a Proactive Healthcare SystemCreating a Proactive Healthcare System
Creating a Proactive Healthcare System
 
World Transformation: The Secret Agenda of Product Design
World Transformation: The Secret Agenda of Product DesignWorld Transformation: The Secret Agenda of Product Design
World Transformation: The Secret Agenda of Product Design
 
The Power of Now
The Power of NowThe Power of Now
The Power of Now
 
High Performance PWAs
High Performance PWAsHigh Performance PWAs
High Performance PWAs
 
Rise of the JAMstack
Rise of the JAMstackRise of the JAMstack
Rise of the JAMstack
 
From Closed to Open: A Journey of Self Discovery
From Closed to Open: A Journey of Self DiscoveryFrom Closed to Open: A Journey of Self Discovery
From Closed to Open: A Journey of Self Discovery
 
Projects Ain’t Nobody Got Time For
Projects Ain’t Nobody Got Time ForProjects Ain’t Nobody Got Time For
Projects Ain’t Nobody Got Time For
 

Recently uploaded

TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
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
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
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
 
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
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
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
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
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
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 

Recently uploaded (20)

TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
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
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
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
 
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
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
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
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
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
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 

Building Native Apps- A Digital Canvas for Coders and Designers with Walter Luh

  • 1. coronalabs.com@walterluh Corona Building Native Apps A digital canvas for everyone ® NBC/Universal powers their campaign with Corona
  • 3. coronalabs.com@walterluh Turning an idea into something real + + = Software DevelopmentCreative
  • 12. coronalabs.com@walterluh What is Corona? same code, multiple stores develop 5-10x faster SDK for native apps ...
  • 13. coronalabs.com@walterluh Breakthrough Productivity 36 hours code+graphics+sound (complete 2 level game) 14 hours code+graphics+sound (gameplay only) “Angry Birds” “Fruit Ninja” “TinyWings” 12 hours code+graphics+sound (gameplay only) “Developing directly in Xcode would have been at least 5x more code than Corona” – Unicorn Labs, Top 20 iPad eBook Ship #1 apps 10x faster
  • 14. coronalabs.com@walterluh Not Just for Games ESP Guitars CheeseMonger Planet Sushi Thai Cook Visually stunning business apps
  • 18. CONFIDENTIALcoronalabs.com OpenGL in one line Phone SDK. // Display "myImage.png" // ---------------------------------------------------------------------------- // OpenGLESTextureAppDelegate.m // ---------------------------------------------------------------------------- #import "OpenGLESTextureAppDelegate.h" #import "EAGLView.h" #import "OpenGLESTextureViewController.h" @implementation OpenGLESTextureAppDelegate @synthesize window=_window; @synthesize viewController=_viewController; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions { // Override point for customization after application launch. self.window.rootViewController = self.viewController; return YES; } - (void)applicationDidBecomeActive:(UIApplication *)application { /* Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. */ [self.viewController drawFrame]; } - (void)dealloc { [_window release]; [_viewController release]; [super dealloc]; } @end // ---------------------------------------------------------------------------- // EAGLView.m // ---------------------------------------------------------------------------- #import <QuartzCore/QuartzCore.h> #import "EAGLView.h" @interface EAGLView (PrivateMethods) - (void)createFramebuffer; - (void)deleteFramebuffer; @end @implementation EAGLView @synthesize context; // You must implement this method + (Class)layerClass { 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]; if (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]; } - (void)setContext:(EAGLContext *)newContext { 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)); } } - (void)deleteFramebuffer { if (context) { [EAGLContext setCurrentContext:context]; if (defaultFramebuffer) { 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); } } - (BOOL)presentFramebuffer { BOOL success = FALSE; if (context) { [EAGLContext setCurrentContext:context]; glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); 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]; } @end // ---------------------------------------------------------------------------- // OpenGLESTextureViewController.m // ---------------------------------------------------------------------------- #import <QuartzCore/QuartzCore.h> #import "OpenGLESTextureViewController.h" #import "EAGLView.h" @interface OpenGLESTextureViewController () @property (nonatomic, retain) EAGLContext *context; @property (nonatomic, assign) CADisplayLink *displayLink; - (void) loadTexture; @end @implementation OpenGLESTextureViewController @synthesize animating, context, displayLink; - (void)awakeFromNib { EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; if (!aContext) NSLog(@"Failed to create ES context"); else if (![EAGLContext setCurrentContext:aContext]) NSLog(@"Failed to set ES context current"); self.context = aContext; [aContext release]; [(EAGLView *)self.view setContext:context]; [(EAGLView *)self.view setFramebuffer]; [self loadTexture]; self.displayLink = nil; } - (void) loadTexture { glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); NSString *path = [[NSBundle mainBundle] pathForResource:@"myImage" ofType:@"png"]; NSData *texData = [[NSData alloc] initWithContentsOfFile:path]; UIImage *image = [[UIImage alloc] initWithData:texData]; GLuint width = CGImageGetWidth(image.CGImage); GLuint height = CGImageGetHeight(image.CGImage); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); void *imageData = malloc( height width 4 ); CGContextRef image_context = CGBitmapContextCreate( imageData, width, height, 8, 4 width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big ); CGColorSpaceRelease( colorSpace ); CGContextClearRect( image_context, CGRectMake( 0, 0, width, height ) ); CGContextTranslateCTM( image_context, 0, height - height ); CGContextDrawImage( image_context, CGRectMake( 0, 0, width, height ), image.CGImage ); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData); CGContextRelease(image_context); free(imageData); [image release]; [texData release]; } - (void)dealloc { glDeleteTextures(1, &textureID); // Tear down context. if ([EAGLContext currentContext] == context) [EAGLContext setCurrentContext:nil]; [context release]; [super dealloc]; } - (void)viewDidUnload { [super viewDidUnload]; // Tear down context. if ([EAGLContext currentContext] == context) [EAGLContext setCurrentContext:nil]; self.context = nil; } - (void)drawFrame { [(EAGLView *)self.view setFramebuffer]; // Replace the implementation of this method to do your own custom drawing. static const GLfloat squareVertices[] = { -0.5f, -0.33f, 0.5f, -0.33f, -0.5f, 0.33f, 0.5f, 0.33f, }; static const GLfloat texCoords[] = { 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0 }; glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glVertexPointer(2, GL_FLOAT, 0, squareVertices); glEnableClientState(GL_VERTEX_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); [(EAGLView *)self.view presentFramebuffer]; } @end display.newImage("myImage.png")
  • 19. coronalabs.com@walterluh API for Designers local image = display.newImage("myImage.png") -- Properties image.x = 100 image.y = 100 image.rotation = 45 image.blendMode = "add" -- Tween transition.to( image, { alpha = 0.0 } )
  • 22. coronalabs.com@walterluh Corona Rendering Engine Virtual Machine User Input Networking Device Device/OS Native Mobile App Text StrokesFills Bitmaps Shapes Objects Behaviors Dynamic Layout Events Device Capabilities Etc Camera Mic GPS Etc Artwork Compiled Code Localized Strings Workflow Developer Assets User Interface Architecture
  • 25. coronalabs.com@walterluh Lua types nil boolean number string function table userdata • JavaScript-like syntax • Functions are closures • Lexical scope (non-local vars) • Objects are tables
  • 26. coronalabs.com@walterluh Lua vs Other Languages if  (!carMoving)  {   //  do  something }  else  if  (noGas)  {   //  do  something  else } for  (i=1;  i<=10;  i++)  {   print(i) } for  (j=100;  j>0;  j-­‐-­‐)  {   print(j) } if  (not  carMoving)  then   -­‐-­‐  do  something elseif  (noGas)  then   -­‐-­‐  do  something  else end for  i  =  1,10  do   print(i) end for  j  =  100,1,-­‐1  do   print(j) end
  • 27. coronalabs.com@walterluh array  =  {  "a",  "b",  100,  "hello"  } dictionary  =  {  x=5,  y=7,  name="Joe"  } t  =  {}                        -­‐-­‐  empty  table t[1]  =  "a"                -­‐-­‐  numerical  index t["x"]  =  5                -­‐-­‐  key  index t.x  =  5                      -­‐-­‐  equivalent  property  access t.hasProperties  =  true t[array]  =  "Joe"    -­‐-­‐  any  type  can  be  a  key!!! t["printJoe"]  =  function()  print("Joe")  end Lua objects areTables
  • 28. coronalabs.com@walterluh -­‐-­‐  create  empty  table local  o  =  {} -­‐-­‐  add  method function  o:saySomething(  something  )    print(  something  ) end -­‐-­‐  output  'hi' o:saySomething(  "hi!"  ) Object methods
  • 29. coronalabs.com@walterluh -­‐-­‐  create  empty  table local  o  =  {} -­‐-­‐  add  method local  function  f(  self,  something  )    print(  something  ) end o.saySomething  =  f -­‐-­‐  output  'hi' o.saySomething(  o,  "hi!"  ) The ':' is syntactic sugar
  • 30. coronalabs.com@walterluh Arrays are 1-based //  Other  languages:  index  begins  with  0   array=['a','b','c']; for  (  var  i=0;  i<arr.length;  i++)  {    log(  array[i]  ) } -­‐-­‐  Lua:  index  begins  with  1 local  array  =  {'a','b','c'} for  i=1,#array  do    print(  array[i]  ) end
  • 31. coronalabs.com@walterluh Corona Enterprise • Integrate native libraries • Wrap native code in your own Lua APIs • Automate builds Lua and Objective-C/C++ and Java
  • 36. coronalabs.com@walterluh Content Scaling -­‐-­‐  config.lua application  =  {        content  =  {                width  =  320,                height  =  480,                scale  =  "letterbox",        }, } • Code in content units (not screen pixels) • width/height specify content dimensions • Scale mode determines how physical display is filled
  • 38. coronalabs.com@walterluh Retina Imaging in Corona -­‐-­‐  config.lua application  =  {        content  =  {                width  =  320,                height  =  480,                scale  =  "letterbox",                imageSuffix  =  {                        ["-­‐x15"]  =  1.5,                        ["-­‐x2"]  =  2,                },        }, }
  • 39. coronalabs.com@walterluh Retina ImagingAPI display.newImageRect(  imageName,  w,  h  ) • width/height in content units (not screen pixels) • Best matching image file based on scale factor • Suffixes in config.lua determine image/scale mapping
  • 41. CONFIDENTIALcoronalabs.com Hard Problems Made Easy (e.g. how Corona taught me to love physics)
  • 42. CONFIDENTIALcoronalabs.com local sky = display.newImage( "clouds.png" )
  • 44. CONFIDENTIALcoronalabs.com local sky = display.newImage( "clouds.png" ) local ground = display.newImage( "ground.png" ) ground.x = 160 ground.y = 445
  • 46. CONFIDENTIALcoronalabs.com local sky = display.newImage( "clouds.png" ) local ground = display.newImage( "ground.png" ) ground.x = 160 ground.y = 445 local crate = display.newImage( "crate.png" ) crate.x = 180 crate.y = 80 crate.rotation = 10
  • 48. CONFIDENTIALcoronalabs.com local sky = display.newImage( "clouds.png" ) local ground = display.newImage( "ground.png" ) ground.x = 160 ground.y = 445 local crate = display.newImage( "crate.png" ) crate.x = 180 crate.y = 80 crate.rotation = 10 local physics = require( "physics" ) physics.start()
  • 49. CONFIDENTIALcoronalabs.com local sky = display.newImage( "clouds.png" ) local ground = display.newImage( "ground.png" ) ground.x = 160 ground.y = 445 local crate = display.newImage( "crate.png" ) crate.x = 180 crate.y = 80 crate.rotation = 10 local physics = require( "physics" ) physics.start() physics.addBody( ground, { friction=0.5 } ) ground.bodyType = "static"
  • 50. CONFIDENTIALcoronalabs.com local sky = display.newImage( "clouds.png" ) local ground = display.newImage( "ground.png" ) ground.x = 160 ground.y = 445 local crate = display.newImage( "crate.png" ) crate.x = 180 crate.y = 80 crate.rotation = 10 local physics = require( "physics" ) physics.start() physics.addBody( ground, { friction=0.5 } ) ground.bodyType = "static" physics.addBody( crate, { density=2.0, friction=0.5, bounce=0.3 } )
  • 53. CONFIDENTIALcoronalabs.com local crate = display.newImage( "crate.png" ) crate.x = 180 crate.y = -100 crate.rotation = 10 physics.addBody( crate, { density=2.0, friction=0.5, bounce=0.3 } )
  • 54. CONFIDENTIALcoronalabs.com local function spawnCrate() ! local crate = display.newImage( "crate.png" ) ! crate.x = math.random( 320 ) ! crate.y = -100 ! crate.rotation = 10 ! physics.addBody( crate, { density=2.0, friction=0.5, bounce=0.3 } ) end timer.performWithDelay( 500, spawnCrate, 50 )
  • 56. CONFIDENTIALcoronalabs.com What if gravity was up rather than down?
  • 61. coronalabs.com@walterluh WebK SQLite database File read/write Full Lua scripting language Hardware-accelerated graphics GPS, compass, accelerometer Simple and complex physical bodies Networking (TCP, FTP, HTTP, etc.) Video playback (streaming or local) Physical properties (mass, friction, Joints, wheels, hinges, pulleys, etc. Animated sprites with independent Collision detection, including pre OpenFeint game network support Vector drawing APIs (shapes and Native UI (keyboard, etc.) Crypto (md4, md5, sha1, sha512, Audio (sound effects or MP3) Animation and transition libra Facebook and Twitter libraries Improved texture memory han physics simulation oto library Tons of Features <html5> • OpenGL graphics • Open AL audio • Box2D Physics • Texture atlases, sprites, ... • Networking • GPS, multitouch, accelerometer, ... • Native web views, textfields, ... • Camera, photo library, video, ... • Services: ads, analytics, IAP, ... • And much more!
  • 63. coronalabs.com@walterluh Thriving Ecosystem Corona Fireworks Photoshop Plugin Zwoptex TextMate Particle Candy Corona Remote Corona Project Manager Lime Sprite Deck LuaGlider Texture Packer
  • 64. coronalabs.com@walterluh No Coding Required Build native apps using Photoshop/Kwik
  • 67. coronalabs.com@walterluh Developers like you #1 #1 From Designers to Coders. From Indies to Studios.