Thursday, September 24, 2009

Annotation overlay on iPhone 3GS

Recently I made a new demo showing how we can use iPhone's compass and accelerometer for information overlay. (iPhone 3GS, iPhone SDK 3.1)

Enjoy this !!


Thursday, September 17, 2009

Overlaying views on UIImagePickerController's view

Recently, iPhone SDK 3.1 was out. In the update, Apple now allows developers to overlay their own views on the preview view of the UIImagePickerController. Before the SDK 3.1, PLCameraController, a private API, is required or we have to do some hack in the view hierarchy of the UIImagePickerController.

On iPhone SDK 3.1, UIImagePickerController has a property, named as cameraOverlayView defined as :

The custom view to display on top of the default image picker interface.
@property(nonatomic,retain) UIView *cameraOverlayView

When I first met this property, I misunderstood what the property means. That is, I thought that the property is the camera preview view itself. But I was wrong. cameraOveralyView doesn't give us camera preview view. What we can do with cameraOverlayView is just adding my own view to the UIImagePickerController's view and nothing more.

This is very limited functionality for augmented reality because still, it is not possible to get the raw video data from the camera. However, if you just need the background video, this is quite an easy solution for you.

The cameraOverlayView works as follows (I implemented this in an IBAction of a view controller):

//Let's add and image view on the video
UIImage *image = [UIImage imageNamed:@"mylogo.png"] ;
UIImageView *imgView = [[UIImageView alloc] initWithImage:image] ;
imgView.bounds = CGRectMake(100,100, 128, 128) ;
UIImagePickerController *camera = [[UIImagePickerController alloc] init];

// Hide Apple's UI
camera.sourceType = UIImagePickerControllerSourceTypeCamera;
camera.showsCameraControls = NO;
camera.navigationBarHidden = YES;
camera.toolbarHidden = YES;
camera.wantsFullScreenLayout = YES;

// Add the view to be overlaid
camera.cameraOverlayView = imgView ;
[imgView release] ;

// Show the camera's view as a modal dialog.
[controller presentModalViewController:self animated:YES];


Somehow, it is a little bit weird that modal dialog is required. But it is the way we use UIImagePickerController as Apple allows only this way. If all procedures are OK, you will see something like this. A logo is overlaid on the camera's preview view.



If you want to make the video fill the entire screen, change the transformation property of the UIImagePickerController through the property 'cameraViewTransform', which is also a new feature in 3.1.

camera.cameraViewTransform=
CGAffineTransformScale(self.cameraViewTransform, 1.0, 1.13);


Thus, now it is very easy to make some augmented reality applications using 'cameraOverlayView' feature. I made a simple application that displays annotations in the scene by using the iPhone 3GS's compass.




Wednesday, September 2, 2009

A simple and nice way to video background without OpenGL ES texturing on the iPhone : Another tip

When I upgraded the Oolong Engine to the version supporting OpenGL ES 2.0, my trick for video background did not work. The GL view's background is cleared (0,0,0), but the video preview view was occluded by the GL view. Clearly, glClear(0,0,0,0) didn't work at that stage.


I tried to find why this happens and I found a solution after all. The reason why glClear do not work was that the color format of the GL view was set to RGB565, which seems not to provide alpha in the scene So I changed the color format from RGB565 to RGBA8 like this and I can see the background video and rendered scene now.


original code in delegate.m was :


_glView = [[EAGLView2 alloc] initWithFrame:rect pixelFormat:GL_RGB565 depthFormat:GL_DEPTH_COMPONENT16 preserveBackbuffer:NO];


What I chanaged for solving the problem is :


_glView = [[EAGLView2 alloc] initWithFrame:rect pixelFormat:GL_RGBA8_OES depthFormat:GL_DEPTH_COMPONENT16 preserveBackbuffer:NO];



Actually, you can see the initWithFrame method initializes the color format either RGB565 or RGBA8. Please look the implementation of initWithFrame method in the file EAGLView2.m. You may see this code.


eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithBool:YES],

kEAGLDrawablePropertyRetainedBacking,

(format == GL_RGB565) ? kEAGLColorFormatRGB565 : kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];


When clearing OpenGL View with alpha does not work on Oolong engine


The reason why glClear do not work was that the color format of the GL view was set to RGB565,
which seems not to provide alpha in the scene

So I changed the color format from RGB565 to RGBA8 like this and
I can see the background video and rendered scene now.

original code in delegate.m:

_glView = [[EAGLView2 alloc] initWithFrame:rect pixelFormat:GL_RGB565 depthFormat:GL_DEPTH_COMPONENT16 preserveBackbuffer:NO];

What I chanaged for solving the problem :

_glView = [[EAGLView2 alloc] initWithFrame:rect pixelFormat:GL_RGBA8_OES depthFormat:GL_DEPTH_COMPONENT16 preserveBackbuffer:NO];

Actually, you can see that the initWithFrame method initializes the color format either RGB565 or RGBA8. Please look the implementation file EAGLView2.m :

eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],
kEAGLDrawablePropertyRetainedBacking,
(format == GL_RGB565) ? kEAGLColorFormatRGB565 : kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];