Showing posts with label tutorial. Show all posts
Showing posts with label tutorial. Show all posts

Thursday, April 25, 2013

Tutorial 30 - Codea v1.5.2: Objective C Add On, Game Center

Figure 0. iOS Dev Center


30.1 Overview


CodeaAddon is an experimental protocol for adding native extensions to exported Codea projects. You must deal with Lua directly to register your functions and globals. This protocol should be considered alpha and is subject to change in future Codea releases.As with the previous tutorial on iAds, we have provided a lot of background on Game Center in these tutorials:
Have a look at the above to refresh your knowledge on what is required from an iTunes Connect perspective as we will only cover that area briefly in this tutorial.


Figure 1. Find out the Bundle Identifier for your App.


30.2 Registering your Application in iTunes Connect


In order to test your app's Game Center functionality you need to register an app ID associated with this app which enables Game Center. The association is done via the bundle identifier of your app (Figure 1). Click on the app title in the top left of the project navigator screen in Xcode to bring up this screen. Make sure that you have selected the "Summary" tab. Write down the bundle identifier shown, we will need this shortly.

Figure 2. Set up a new App ID for your app.

Log into your apple developer account, go to the iOS Dev Center (Figure 0) and select the Certificates, Identifiers & Profiles link on the right hand side of the page. Select a name for your app ID (pick something you can remember e.g. we used AudioDemoAppID) and fill in the App ID Suffix bundle identifier. This is the critical step which will link your app to the configuration in iTunes Connect. Use the bundle identifier that you wrote down earlier. Click "confirm" and then "submit".

Figure 3. Associate your bundle identifier with the App ID.

Head back to the iOS Dev Center (Figure 0) and this time click on iTunes Connect link in the top right of the page. You will be asked to sign in again, do so and then click on the Manage your Apps link (Figure 4).

Figure 4. iTunes Connect

On the Manage your Apps page (Figure 5), click on the "Add New App" button at the top left of the screen. Click on iOS App on the next screen.

Figure 5. Manage your Apps

Fill in the app name, SKU number (this can be any unique identifier, we normally use the date), and then select the App ID that you just created for the bundle identifier (Figure 6). Click "Continue" when you are done.

Figure 6. iTunes Connect App Information.

Fill in all the meta data (have a look at the earlier tutorials if you get stuck) and save the configuration. When you are done (Figure 7), we can enable Game Center for your app. Click on the "Manage Game Center" button on the right hand side of the page (Figure 7).

Figure 7. Metadata addition complete.

Click on the button that says "Enable for Single Game" and then either configure some achievements and leader boards or just click "Done". We can now test our exported app once we have included the Game Center add on.

Figure 8. Adding the GameKit Framework.


30.3 Add the GameKit Framework to Your App


Fire up Xcode and load the exported version of your Codea application (See Tutorial 27). Click on the imported project file at the top of the project navigator then in the Build Phases tab, scroll down to the link binary with libraries area and select the drop down arrow. Click on the "+" button below your existing frameworks to add a new framework. Find GameKit and click on "Add"


30.4 Changes to your Exported AppDelegate Files


All of the source code files are provided at the end of this tutorial. You need to update AppDelegate.h as follows:

//
// AppDelegate.h
// AudioDemo
//
// Used to demonstrate the audio, game center and iAds add on libraries
//
// Created by Reefwing Software on Sunday, 14 April 2013
// Copyright (c) Reefwing Software. All rights reserved.
//

    #import <UIKit/UIKit.h>
    #import "AudioAddOn.h"
    #import "IAdsAddOn.h"
    #import "GameCenterAddOn.h"

    @class CodeaViewController;

    @interface AppDelegate : UIResponder <UIApplicationDelegate>

    @property (strong, nonatomic) IAdsAddOn *iAdsAddOn;
    @property (strong, nonatomic) AudioAddOn *audioAddOn;
    @property (strong, nonatomic) GameCenterAddOn *gameCenterAddOn;
    @property (strong, nonatomic) UIWindow *window;
    @property (strong, nonatomic) CodeaViewController *viewController;

@end


And AppDelegate.mm, should now look like:

//
// AppDelegate.mm
// AudioDemo
//
// Created by Reefwing Software on Sunday, 14 April 2013
// Copyright (c) Reefwing Software. All rights reserved.
//

#import "AppDelegate.h"
#import "CodeaViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[CodeaViewController alloc] init];

    // Create and add our AudioAddOn to Codea

    self.audioAddOn = [[AudioAddOn alloc] init];
    [self.viewController registerAddon: self.audioAddOn];

    // Create and add our iAdsAddOn to Codea

    self.iAdsAddOn = [[IAdsAddOn alloc] init];
    [self.viewController registerAddon: self.iAdsAddOn];

    // Create and add our GameCenterAddOn to Codea

    self.gameCenterAddOn = [[GameCenterAddOn alloc] init];
    [self.viewController registerAddon: self.gameCenterAddOn];

    NSString* projectPath = [[[NSBundle mainBundle] bundlePath]    stringByAppendingPathComponent:@"AudioDemo.codea"];

    [self.viewController loadProjectAtPath:projectPath];

    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];

    return YES;

}

- (void)applicationWillResignActive:(UIApplication *)application
{

}

- (void)applicationDidEnterBackground:(UIApplication *)application
{

}

- (void)applicationWillEnterForeground:(UIApplication *)application
{

}

- (void)applicationDidBecomeActive:(UIApplication *)application

}

- (void)applicationWillTerminate:(UIApplication *)application
{

}

@end


Obviously there is no need to register the iAds and Audio add ons if you are just using Game Center. We have just left these in to demonstrate how you can stack add ons.



Figure 9. If you try to show Achievements or Leaderboards with none set up in iTunes Connect, you will see this screen.

30.5 The Game Center Add On


You need to add the GameCenterAddOn.h and GameCenterAddOn.m files to your project (plus the other iAds and Audio add on classes if you are using them). These are available below.

To do this, right click on the Addons folder in the project navigator and select Add files to "YourProjectName"... Navigate to where ever you saved these files and select them.

This Game Center Add On will make four new functions available in your Lua code:

  • gameCenterStart(); 
  • showLeaderBoardWithIdentifier(int ident); 
  • showAchievementsView(); and
  • playerIsAuthenticated;

You need to call gameCenterStart() first as your game must authenticate a local player before you can use any Game Center classes. 


Figure 10. You may need to sign in the first time you try to authenticate a player.

If you want to add more Game Center functionality the just follow the pattern in the add on. For example, if you want to add a save score function then, in GameCenterAddOn.h add:

static int saveScore(struct lua_State *state);

Then in GameCenterAddOn.m add/modify:

// Add to method

- (void)codea:(CodeaViewController*)controller didCreateLuaState:(struct lua_State*)L
{
    ...
    lua_register(L, "saveScore", saveScore);
    ...
}

// New Objective C method

- (void) saveNewScore: (int) score
{
    // INSERT YOUR LEADERBOARD IDENTIFIER IN THE LINE BELOW
    // Replace "Easy Difficulty" with your identifier from iTunes Connect

    GKScore *scoreReporter = [[GKScore alloc] initWithCategory: @"Easy Difficulty"];

    if (scoreReporter)
    {
        scoreReporter.value = score;

        [scoreReporter reportScoreWithCompletionHandler: ^(NSError *error)
        {
            if (error != nil)
            {
                // handle the reporting error

                NSLog(@"Game Center: Error Saving Score - %@", [error localizedDescription]);
            }
        }];   
    }
}

// New C function

static int saveScore(struct lua_State *state)
{
    [gameCenterAddOnInstance saveNewScore: lua_tonumber(state, 1)];

    return 0;
}

Then in your Lua code you can use saveScore(yourNewScore).

Figure 11. Player Authenticated.


30.6 Download the Code



Sunday, January 27, 2013

Tutorial 25 - A Lua Primer for Codea (Part 1)

25.1 Introduction


Every year around Christmas there is a surge of activity on the Codea Forums and on this tutorial site. A common theme in the comments and emails that we receive, is that this site assumes quite a bit of knowledge and as Codea appears to be attractive to first time programmers there are some gaps which need to be filled.

This tutorial is an attempt to fill in some of those gaps. In particular, we will try and provide a quick primer on the Lua language which Codea uses. To ensure that Codea does not incur the wrath of Apple, there are some features of the Lua language which have been disabled in Codea. We will discuss these briefly but the list is diminishing with every new release of Codea and there isn't anything which will likely cause you any problems.


25.2 Lua


Lua is a light weight scripting language written in C. By light weight we don't mean that it isn't capable of writing complicated code but that the syntax is stream lined and straight forward. This makes it a great first language to learn. 

Lua means "moon" in Portugese, it is the evolution of another language called SOL (Portugese for "sun"). It was created in 1993 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes, members of the Computer Graphics Technology Group (Tecgraf) at the Pontifical Catholic University of Rio de Janeiro, in Brazil (hence the Portugese naming).


25.3 Variables and Data Types


Variables are memory locations that hold data. There are three kinds of variables in Lua: global variables, local variables, and table fields. All variables are global unless defined otherwise. Defining an identifier as local is done using the local keyword. Local identifiers are not visible outside the block in which they were declared, but are visible inside sub-blocks. This is called lexical scoping. For Codea a tab is considered a chunk,  which translates as follows:
  1. If you define a variable within any of the tabs it will, by default be treated as global.
  2. If you define a local variable within a tab (but outside a function), you will only be able to access it within that tab.
  3. If you define a local variable within a function, you can only access it from within that function. However, if a function is enclosed in another function, then it has access to all the local variables of that function. In these circumstances, the external local variable is called an "upvalue". We cover this in Interlude 7.
Assigning to a variable that has not been declared locally within the current chunk will recursively search for that name in the parent chunk, up to the top-level. If the name is found, the assignment is made to that variable. If the name is not found, the assignment becomes a global (either creating a new variable, or replacing an existing global). The consequence of this behaviour is that using local variables is much faster than globals.

Global identifiers are stored in the implicit global environment table, which can explicitly be accessed through the name _G (see section 25.5).  

Variable names must start with a letter or underscore and can contain letters, digits or underscores. Defined keywords in Lua can not be used as a variable name (e.g. and, break, do, else and end). As a convention, variables in capitals starting with an underscore (e.g. _G or  _VERSION) are reserved for internal Lua global variables.

Lua supports only a small number of data types. The ones you will use the most are boolean (true or false), numbers, strings and tables. 

By default, Lua's number type is represented by double-precision floating-point numbers. However, Codea's Lua interpreter uses another internal representation for numbers: single-precision float. This gives a precision of 6 to 9 significant decimal digits and a range for positive values of between about 1.4e−45 to about 3.4e+38 (reference from Codea Wiki).

Lua strings can hold any 8-bit character, including embedded zeros. Strings can be enclosed in single or double quotes, pick one style and stick with it, we tend to go with double quotes. Strings in Lua are immutable values, and thus you cannot change a character inside a string. You can also delimit literal strings using matching double square brackets. For example:

aLongString = [[
                   line 1
                   line 2
                   line 3
                   line 4
              ]]

Boolean variables are a relatively recent introduction to Lua. The boolean type has two values, true and false. Conditional tests consider false and nil as false and anything else as true (including 0 and "").

Lua is a dynamically typed language, which means that variables do not have a defined type, they get their type based on the data assigned to them. This means that the following is a valid chunk of code in Lua (albeit probably not best practise as it would make your program hard to follow):

x = 1
print("x as an integer: " .. x)
x = 3.141592654
print("x as a float or real number: " .. x)
x = 0xFE
print("x as a hexadecimal converted to decimal: " .. x)
x = "now a string"
print("x as a string: " .. x)
x = true
print(x)
x = {value = 999}
print("x as a table: " .. x.value)
x = function(n) return n*2 end
print("x as a function: " .. x(2))

A few comments about the preceding code and some general observations on variables: 
  • Lua is case sensitive, so x and X are different variables. 
  • In the example above, when we store a hexadecimal value in x it is automatically converted and printed as a decimal.
  • You can concatenate (i.e. join) two strings or a string and a number using the".." operator. Numbers are automatically converted to strings in this situation. You can't concatenate a boolean.
  • This automatic conversion (or to use the technical term - coercion,  works the other way around as well, a string will be treated as a number if used in that context. Any arithmetic operation applied to a string tries to convert this string to a number. Note that comparison operators (== ~= < > <= >=) do not coerce their arguments. Thus a number is not equal to its string representation.
  • Each line of code is terminated by a new line. You can optionally use a semi-colon (as used in C, but it isn't recommended). 
  • You can do multiple assignments on the one line (e.g. x, y = 1, 2), and you can use this to swap two variables (e.g. x, y = y, x).
  • A variable that hasn't been assigned a value will be nil by definition. 
  • Unlike C, the value 0 is not a false test condition in Lua, only nil or false is. You can use the fact that nil equates to false to assign default values to a variable (e.g. x = x or 2 will assign the variable x a value of 2 if it hasn't been previously assigned a value).
  • Note that you can assign a function to a variable. As an example, we make use of this in Codea to pass call back functions to our Button class to indicate what function to call when a button is tapped. The technical term for this feature is first-class functions. As such, they can be created during runtime, stored in variables, and passed to and returned from other functions.
There are two other data types called userdata and thread. Userdata and tables will be covered in subsequent sections. Thread is way outside the scope of this tutorial so we are just going to ignore them.


25.4 Tables


Tables in Lua are amazingly versatile. Which is just as well since they are the only built in composite data type available. The technical term for tables in Lua is a hashed heterogeneous associative array and they are worthy of a separate tutorial, which is exactly what we have done. You can access our tutorials on tables here:
  1.  Understanding Tables;
  2.  Converting a string to table and table to string
  3.  Saving and Loading complicated tables; and
  4.  Classes in Lua and Codea.

25.5 The Global Variable Table _G


This section goes beyond the scope of this tutorial, so feel free to skip ahead. It is included here out of interest. We mentioned above that Lua has a number of internal variables. One of these is _G, a global variable which points to the global environment. It includes all of the global variables and functions and even includes a reference to itself! It is sometimes useful to understand what has been defined globally and you can use the following to display the contents of _G: 

for k, v in pairs(_G) do print(k, v) end


25.6 Userdata


Userdata are variables that encapsulate arbitrary C/C++ data within a Lua interface. Many Lua modules extend the capabilities of Lua by binding external libraries, including the creation of new types as userdata. Userdata variables can only be created using the C API (i.e. in our context this means the Codea runtime), this can't be done in Lua.

Userdata is largely outside the scope of this tutorial but you need to know that Codea extends Lua with 12 user-defined types such as codeaimage, mesh, matrix, vec2, vec3, touch and color. You can read all about these on the Codea User Defined Types page.

Userdata is also useful when we want to expose C/Objective C functions in Lua via the runtime. Have a look at our tutorials on integrating Game Centerbuilding a Universal App or implementing iAds if you are interested.


25.7 Operators


Lua supports the following arithmetic operators:  + (addition), - (subtraction), * (multiplication), / (division), % (modulo),  ^ (exponentiation) and  - (negation).

The relational operators in Lua are: == (equal), ~= (not equal), < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to). These operators will return a boolean (true or false).

The logical operators in Lua are and, or, and not. As for control structures, all logical operators consider both false and nil as false and anything else as true.

As mentioned in section 25.3, the string concatenation operator in Lua is denoted by two dots ('..'). If either operand is a number, then it is converted to a string before joining.

The length operator is denoted by #. The length of a string is its number of bytes (i.e. characters). The length of a table is more complicated. For a table used as a simple array the length operator will work as expected and return the number of elements in the array. For more complicated tables, the returned length can be any of the indices that directly precedes a nil value. You can read more about this in our tutorial on tables.

25.8 Classes


In Interlude 11 we spoke about the use of classes in Codea. Codea comes with a built-in global function called class() that is used to emulate the functionality of a class data structure using a table (and metatable). We use classes extensively in our tutorials but we haven't explained the difference between the "." and ":" operators when applied to a class. As this has been the subject of a number of questions, we will cover the proper usage in this section.

In order to demonstrate, we will first construct a simple ship class. By convention the base class name starts with a capital, while instances of the class have names which start in a lower case letter. 

The Codea class() constructor is a function which, when called, sets up a new table and attaches the class metatable to it. The metatable redirects unrecognized events to the class method table (as well as possibly handling events itself). This is covered in some depth on the Codea wiki.

Ship = class()

function Ship:init( hitPoints )
    self.points = hitPoints or 100
end

function Ship:hit( damage )
    self.points = self.points - damage
    print( self.points )
end

In our Main tab, setup() function we may then instantiate our class as follows:

myShip = Ship()

This will create a new object called myShip of class Ship. Note that we called ship without any parameters. This means that hitPoints will be nil and self.points will be assigned 100 (our default value) since nil is interpreted as false by Lua. 

One of the potentially confusing parts of the class definition is where does "self" come from and why do we use it? The self variable is created automatically by calling class() and provides a reference to the object created when we instantiate a class. This means that when we change the points variable using self.points we only change it for that object, not for every object of class Ship. So in our example above self = myShip. 

Try converting the Ship class so that it uses points instead of self.points. If you do this and have created another ship (e.g. myOtherShip = Ship()), then every time you call myShip:hit(20) this will also reduce the hit points of myOtherShip, which is usually not what you want.

If our ship gets hit then we want to record the damage and print out the current hit points using the hit(damage) function of our class. There are two ways you could do this (the right way and the wrong way!). In the Main tab of your program, you could use:

myShip:hit(20)

or you could try to use:

myShip.hit(20)

Which is correct? To work this out we have to understand the difference between the two statements. Using ":" we are actually passing two parameters to hit(), the damage and a hidden reference to the object being hit (i.e. self). So myShip:hit(20) is equivalent to myShip.hit(self, 20). 

The second option - myShip.hit(20) will throw an error in Codea. If you want to access the class instance variables directly from the Main tab, you can do something like:

myShip.points = myShip.points - 20

This will operate as expected, but only if you have defined it as self.points in your class.


25.9 Other Resources


If what is provided here isn't sufficient then have a look at the official Lua Tutorial site, which has a MUCH more detailed treatment on Lua. The Codea reference documentation is also very useful, as is the active forum and wiki (in particular have a look at the Hints and Tips page which contains references to items not covered elsewhere). 

Codea (v1.4) uses version 5.1 of Lua (you can determine the current version of Lua using the statement print(_VERSION)). The definitive treatment of the Lua language can be found at the official on-line Lua 5.1 Reference Manual

Saturday, November 24, 2012

Tutorial 24 - Basic 3D Graphics

Figure 1. Ripple Shader.

24.1 Setting the Scene


Version 1.5 of Codea is a huge update. In addition to camera access, image blend modes and a tween library for simple animation, it includes full access to shaders and a shader editor. This feature gives you full access to GLSL (OpenGL Shading Language) vertex and fragment shaders (which can be used to apply the ripple shader effect shown in Figure 1). To understand how to implement and use shaders we need to take a few steps back and provide some graphical foundations.

24.2 OpenGL


OpenGL is a multipurpose open-standard graphics library. Although it is actually a specification, it is usually thought of as an Application Programming Interface (API), which is the manifestation of this specification. The OpenGL API uses C and GLSL is very similar in structure to C but has its own peculiarities. As a C API, OpenGL integrates seamlessly with Objective-C based Cocoa Touch applications. The OpenGL API is defined as a state machine (see Tutorial 5), and almost all of the OpenGL functions set or retrieve some state in OpenGL. The only functions that do not change state are functions that use the currently set state to cause rendering to happen.

OpenGL for Embedded Systems (OpenGL ES) is a simplified version of OpenGL that provides a library which is easier to learn and implement on mobile graphics hardware. Apple provides implementations of OpenGL ES v1.1 and OpenGL ES v2.0. Codea uses v2.0.

OpenGL ES 2.0 is very similar to OpenGL ES 1.1, but removes functions that target the fixed-function vertex and fragment pipeline stages. Instead, it introduces new functions that provide access to a general-purpose shader-based pipeline. Shaders allow you to write custom vertex and fragment functions that execute directly on the graphics hardware (which is very fast). 

24.3 Rendering Graphics


Everything displayed on your iPad screen is a 2 dimensional array of pixels. Each pixel has a particular colour defined by a red, green, blue and alpha (transparency) value in the range 0 to 1. It is the purpose of the graphics pipeline to determine what colour to put in each pixel to provide a representation of your image. Displaying a 2D image is fairly straight forward but what about 3D? The process of converting a 3D world into a 2D image is called rendering.

There are many different rendering systems. The one that we will concern ourselves with is called rasterization, and a rendering system that uses rasterization is called a rasterizer. In rasterizers, all objects that you see are represented by empty shells made up of many triangles. These series of triangles are called "geometry", "model" or "mesh". We will use the term mesh as that is what is used in Codea.


Figure 2. Rasterizing a Triangle.

The process of rasterization has several phases. These phases are ordered into a graphics pipeline (figure 3), where the mathematical model of your image, consisting of a mesh of triangles, enter from the top and a 2D pixel image comes out the bottom. This is a gross simplification but may help in the understanding of the process. The order which triangles from your mesh are submitted to the pipeline can effect the final image. Pixels are square, so they only approximate the triangles (Figure 2), just as the triangles approximate the 3D image. The process of converting your triangles to pixels is called scan conversion, but before we can do this we need to perform some mathematics to check whether the triangle is visible and convert it from 3D to a 2D representation.




24.4 Graphics Pipeline Overview


Triangles are described by 3 vertices, each of which define a point in three dimensional space (x, y, z). To represent these in two dimensions we have to project the vertex co-ordinates onto a plane. We maintain the illusion of depth by using tricks like perspective (i.e. things the same size appear smaller the further away they are). We get to influence the graphics pipeline at two points, the vertex shader and the fragment shader, shown in orange in Figure 3.

If you are interested in a much more detailed explanation then we suggest that you read Andrew Stacey's tutorial on Using Matrices in Codea.

Step 1 - Vertex Shader (Clip Space Transformation)

The first phase of rasterization is to transform the vertices of each triangle into "clip space". Everything within the clip space region will be rendered to the output image, and everything that falls outside of this will be discarded. In clip space, the positive x direction is to the right, the positive y direction is up, and the positive z direction is away from the viewer. Clip space can be different for different vertices within a triangle. It is defined as a region of 3D space with the range [-w, w] in each of the x, y, and z directions. 

This is difficult to visualise and use so the vertices are normalised by dividing each co-ordinate (x, y, z) by w. After being normalised, the (x, y, z) co-ordinates will be in the range of -1 to +1. Dividing by w also applies a perspective effect to each of our triangles.

The entire process can be thought of as a mapping from the projection volume to a 2 unit cube with the origin at (0, 0, 0).


Figure 4. Clip Space Transformation & Normalisation.

In terms of the graphical pipeline (figure 3), this transformation is coded in the Vertex Shader. Open up the Shader Lab in Codea and tap on the vertex shader tab. In the main() function, the line:

gl_Position = modelViewProject * position;

performs the clip space transformation for you. 

The inputs to the vertex shader consist of:
  • Attributes - per vertex data supplied via vertex arrays (e.g. position, color and texCoord). They are signified by the attribute tag in GLSL;
  • Uniforms - constant data used by the vertex shader (e.g. modelViewProjection). Labelled as uniform in GLSL; and
  • Samplers - a specific type of uniforms that represent textures used by the vertex shader. These are optional.
The outputs of the vertex shader are called (somewhat redundantly) varying variables.

Step 2 - Primitive Assembly

A primitive is a geometric object which can be drawn by OpenGL ES (e.g. a point, line or triangle). In this stage, the shaded vertices are assembled into individual primitives.

Normalisation and Clipping will happen automatically in the Primitive Assembly stage between the vertex shader and fragment shader. Primitive Assembly will also convert from normalized device coordinates to window coordinates. As the name suggests, window coordinates are relative to the window that OpenGL is running within. Window coordinates have the bottom-left position as the x, y (0, 0) origin. The bounds for z are [0, 1], with 0 being the closest and 1 being the farthest away. Vertex positions outside of this range are not visible. The region of 3D space that is visible on the screen is referred to as the view frustum.

Step 3 - Rasterization

Rasterization converts the graphic primitives from the previous stage to two dimensional fragments. These 2D fragments represent pixels that can be drawn to the screen (Figure 2).

In this stage, the varying values are calculated for each fragment and passed as inputs to the fragment shader. In addition, the colour, depth, stencil and screen co-ordinates are generated and will be passed to the per-fragment operations (e.g. stencil, blend and dither).

Step 4 - Fragment Shader

The fragment shader is executed for each fragment produced by the rasterization stage and takes the following inputs:
  • Varying variables - outputs from the vertex shader that are generated for each fragment in the rasteriser using interpolation (e.g. vColor in the Ripple Shader Lab example).;
  • Uniforms - constant data used by the fragment shader (e.g. time and freq in the Ripple Shader Lab example).; and
  • Samplers - a specific type of uniforms that represent textures used by the fragment shader (e.g. texture in the Ripple Shader Lab example).
The output of the fragment shader will either be a colour value called gl_FragColor or it may be discarded (see Step 5).

Step 5 - Per Fragment Operations

The final step before writing to the frame buffer is to perform (where enabled) the following per fragment operations.
  1. Pixel ownership test - checks if the pixel is currently owned by the OpenGL context. If it isn't (e.g. the pixel is obscured by another view) then it isn't displayed.
  2. Scissor Test - if enabled, is used to restrict drawing to a certain part of the screen. If the fragment is outside the scissor region it is discarded.
  3. Stencil & Depth test - if enabled, OpenGL's stencil buffer can be used to mask an area.The stencil test conditionally discards a fragment based on the value in the stencil buffer. Similarly, if enabled the depth buffer test discards the incoming fragment if a depth comparison fails.
  4. Blending - combines the newly generated fragment colour value with the corresponding colour values in the frame buffer at that screen location.
  5. Dithering - simulates greater color depth to minimise artifacts that can occur from using limited precision. It is hardware-dependent and all OpenGL allows you to do is to turn it on or off.

24.5 A Simple Shader Example


Version 1.5 of Codea comes with a sample ripple shader (see Figure 1). The following fragment shader code will tint a texture with the tint colour by the tint amount.

// A basic fragment shader with tint.


// This represents the current texture on the mesh
// uniform lowp sampler2D texture;

// The interpolated vertex color for this fragment
// varying lowp vec4 vColor;

// The interpolated texture coordinate for this fragment
// varying highp vec2 vTexCoord;

void main()
{
    // Sample the texture at the interpolated coordinate
    
    lowp vec4 texColor = texture2D( texture, vTexCoord );
    
    // Tint colour - red is currently hard coded.
    // Tint amount - select a number between 0.0 and 1.0
    // Alternatively you could pass the tint color and amount
    // into your shader by defining above:
    //
    // uniform lowp vec4 tintColor;
    // uniform lowp float tintAmount;
    
    lowp vec4 tintColor = vec4(1.0,0.0,0.0,1.0);
    lowp float tintAmount = 0.3;
    tintColor.a = texColor.a;

    // Set the output color to the texture color
    // modified by the tint amount and colour.
    
    gl_FragColor = tintColor * tintAmount + texColor * (1.0 - tintAmount);
}

24.6 Appendix - GLSL Precision Qualifiers


You will notice the lowp, mediump and highp precision specifiers in the shader lab example. It is much faster to use lowp in calculations than highp.The required minimum ranges and precisions for the various precision qualifiers are:


Apple provides the following guidelines for using precision in iOS applications:
  • When in doubt, default to high precision.
  • Colours in the 0.0 to 1.0 range can usually be represented using low precision variables.
  • Position data should usually be stored as high precision.
  • Normals and vectors used in lighting calculations can usually be stored as medium precision.
  • After reducing precision, retest your application to ensure that the results are what you expect.

Saturday, November 17, 2012

Tutorial 23 - Implementing iAds with Codea


23.1 Introduction


A common business model in the App store is to give away your app for free and generate revenue by serving ads to your application. This model has benefits but can annoy your users if done in excess. Everyone likes stuff that is free, so setting a zero cost removes most of the barriers to downloading your app and should maximise download numbers.

Since iOS 4.0 the iAds framework has been available for developers. Using this you can add banner or full screen advertisements to your application. If you are planning to include ads on a screen then you need to ensure that you have left space within your interface to display them. Full screen ads (referred to as interstitial ads by Apple) are only available on the iPad and are only suitable in certain situations, so we wont cover those in this tutorial.

You receive revenue when users view (called impressions) or click advertisements on your app. Some apps use a bit of social engineering to maximise their click through rate. For example the Foxtel (cable TV) app in Australia has ads which appear at the top of the channel selection screen. As per the Apple guidelines these ads are only displayed once the banner has been loaded from the ad server. When this occurs, the ad slides in from the top and moves the content down by the height of the banner. However what happens 50% of the time (for us at least) is that you accidentally tap the ad when you are trying to select a channel.

It is difficult to estimate exactly what revenue you might receive from including iAds in your app. A graph of the impressions that we got for the last year is shown below. There was about 98k in total with 90% coming from one app (Personality). According to Apple the effective revenue per thousand ads (eCPM) served over this period was $0.82. In practice, we get on average $0.25 per day. So while this may not be a get rich quick scheme, it is not bad passive income, particularly given the app I'm deriving revenue on is not optimised for ads. 

We suspect you could do much better with a free game app with high reusability (people tend to use Personality only 2-3 times at best). Apple says that "hundreds of developers are making more than $15,000 per quarter". Given that there are 275,000 iOS developers in the US alone, this is perhaps not that impressive - albeit not all of those developers have iAd enabled apps.




23.2 Banner Views


From a Codea perspective, implementing iAds is easy. If you are happy to display ads on every screen then you just need to leave the appropriate amount of space on your screen to display the ad. In most cases there will be screens that you don't want to display ads on (e.g. the main game screen), so we have extended Codea Lua with a function, showBannerAd(true) to turn ads on and off. For our example, we will only display ads on the Menu and High Score screens.

For the iPad, banner sizes are set at:
  • Portrait: 66 (height) x 768 (width) points - see Interlude 13 if you dont understand the difference between pixels and points.
  • Landscape: 66 (height) x 1024 (width) points.
For completeness, the iPhone banner sizes are 320 x 50 points for a portrait advertisement and 480 x 32 points for a landscape advertisement.

The banner ads are intended to typically appear either at the top or bottom of the display and are provided in two formats so that ads may be displayed when the device is either in portrait or landscape orientation.


23.3 Setup iAds in iTunes Connect


As with Achievements and in-App purchasing, there are some things that you need to enable in iTunes Connect before your app will be able to receive ads from Apple's servers. Log in to your developer account, select iTunes Connect and then click on Manage your Apps. Click on the appropriate App icon and then click on the Setup iAds link (right hand side towards the top).

Answer the question regarding whether the primary target audience for your app is users under 17 years of age and then click Enable iAds and Save.

That's it! You can disable iAds just as simply but changes to your iAd settings will not take effect until your next app version is approved.


23.4 Creating Your Banner Views in the Codea runtime


You should only create a banner view when you intend to display it to the user. Otherwise, it may cycle through ads and deplete the list of available advertising for your application. As a corollary to this, avoid keeping a banner view around when it is invisible to the user. To demonstrate the implementation of iAds in the runtime we will use our old faithful MineSweeper application.

Based on our careful UI planning (or perhaps just through good luck) we happen to have enough space at the top of the MineSweeper Menu screen to fit in a banner ad, so that is where we will put it. As MineSweeper is now a universal application we will need to handle the iPhone sized banners as well. We have more room at the bottom of the iPhone Menu screen when it is in the portrait orientation, so when we detect that device and orientation we will place the banner at the bottom of the view. There is no room for a banner on an iPhone in landscape orientation, so we will disable ads when we detect this combination.

Banner views use a delegate to communicate with your application. Your application will thus need to implement a banner view delegate to handle common events. In particular we need to handle:
  1. when the user taps the banner.
  2. when the banner view loads an advertisement.
  3. when the banner view encounters an error.
Usually you would place this code in the relevant view controller but for simplicity we will handle this in the CodifyAppDelegate (the alternative is to extend the BasicRendererViewController class in the runtime).

If your application supports orientation changes, your view controller must also change the banner view’s size when the orientation of the device changes.

Step 1 - Add the iAd Framework to your App.

Fire up Xcode and load the runtime version of your Codea application. Click on the CodeaTemplate file at the top of the project navigator then in the summary tab, scroll down to the linked libraries area. Click on the "+" button below your existing frameworks to add a new framework. Find iAds and click on "Add".

Step 2 - Update the CodifyAppDelegate Files.

In CodifyAppDelegate.h you need to import the framework you just added using:

#import <iAd/iAd.h>

then modify the class interface definition so that it looks like this:

@interface CodifyAppDelegate : UIResponder<UIApplicationDelegate, ADBannerViewDelegate>

This indicates that the ADBannerViewDelegate protocol will be implemented. We will provide a link to download the updated CodifyAppDelegate files below. We have added two other things to the CodifyAppDelegate files:
  1. A boolean instance variable called displayingAds which is controlled from your Lua code via the modified aGameCenter_Codea class; and
  2. A call back method called iAdDisplayStatusChanged which is used to update the banner view if the MineSweeper game state or orientation changes. This also comes via the modified aGameCenter_Codea class.
Step 3 - Update the other Codea runtime Files.

As we saw in Tutorial 19 when integrating Game Center, there are changes required in LuaState.m, OSCommands.h and OSCommands.m, to allow Lua to communicate with our Objective C code. This mostly comprises registering our new showBannerAd(true or false) function.

In LuaState.m add the following to the  - (void) create method:

    //iAds Function
    LuaRegFunc(showBannerAd);

In OSCommands.h add the following below the similar Game Center definitions:

    //iAds
    int showBannerAd(struct lua_State *L);

Finally, in OSCommands.m add the following method below the Game Center definitions:

int showBannerAd(struct lua_State *L){
    [CodeaGameCenter showBannerAd:lua_toboolean(L,1)];
    return 0;
}

23.5 Codea Lua Code Changes


As mentioned in section 23.2, if you are happy to display adds on every screen then there is no changes required to your Lua code (assuming you left space for the ads). If like us you want to select when ads are displayed, then you need to use the new showBannerAd() function. If you pass true in this function then ads will be displayed and if you pass false, they wont.

As an example, the following shows our updated orientationChanged() function. 

function orientationChanged(newOrientation)

    print("Orientation Change Detected.")
    
    if setupHasRun and gameState == stateRun or gameState == stateWon or 
        gameState == stateLost then
            updateGridLocation()
    end 
    
    if setupHasRun and (gameState == stateMenu or gameState == stateScore) then
        showBannerAd(true)
    else
        showBannerAd(false)
    end
    
end

We also use showBannerAd()  when the gameState changes due to button taps.

The other class we need to modify is the SpashScreen. In the fadeAnimation call back, we turn on ads once the splash screen has faded away.

function fadeAnimationDone()
    
    -- Call back function for Fader complete
    
    gameState = stateMenu
    showBannerAd(true)
    
end

23.6 Download the Updated Runtime & Codea Files


The aGameCenter_Codea and CodifyAppDelegate files are available on GitHub. In addition, the following links allow downloading individual files from DropBox: