CS185c
Chris Pollett
Nov. 17, 2010
- (void) locationManager: (CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation: (CLLocation *)oldLocation ; - (void) locationManager:(CLLocationManager *)manager didUpdateHeading: (CLHeading *)newHeading ; - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error ;to handle location and heading info, we implement the interface CLLocationManagerDelegate; to promise that our controller has methods
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration;to handle accelerometer info, we implement the interface UIAccelerometerDelegate.
#import <UIKit/UIKit.h> #import <CoreLocation/CoreLocation.h> @interface SensorTestsViewController : UIViewController <CLLocationManagerDelegate, UIAccelerometerDelegate> { IBOutlet UILabel *locationLabel; IBOutlet UILabel *headingLabel; IBOutlet UILabel *accelerometerLabel; CLLocationManager *locationManager; } @property (retain, nonatomic) UILabel *locationLabel; @property (retain, nonatomic) UILabel *headingLabel; @property (retain, nonatomic) UILabel *accelerometerLabel; @end
#import "SensorTestsViewController.h" @implementation SensorTestsViewController @synthesize locationLabel; @synthesize headingLabel; @synthesize accelerometerLabel; - (void) viewDidLoad { locationManager = [[CLLocationManager alloc] init]; locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyBest; [locationManager startUpdatingLocation]; [locationManager startUpdatingHeading]; UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer]; accelerometer.delegate = self; accelerometer.updateInterval = 1.0f/60.0f; /* how many times a second to send acclerometer updates. Shouldn't do too fast or battery dies. */ } - (void) locationManager: (CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation: (CLLocation *)oldLocation { NSString *loc = [[NSString alloc] initWithFormat:@"My Coordinates: %@", newLocation.description]; locationLabel.text = loc; [loc release]; } - (void) locationManager:(CLLocationManager *)manager didUpdateHeading: (CLHeading *)newHeading { NSString *head = [[NSString alloc] initWithFormat:@"My Heading: %@", newHeading.description]; headingLabel.text = head; [head release]; } - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { if ([error code] == kCLErrorDenied) { [locationManager stopUpdatingLocation]; } } - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { NSString *head = [[NSString alloc] initWithFormat:@"Acceleration: X:%f Y:%f Z:%f", acceleration.x, acceleration.y, acceleration.z]; accelerometerLabel.text = head; [head release]; } - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; } - (void)viewDidUnload { } - (void)dealloc { [locationLabel release]; [locationManager release]; [super dealloc]; } @end
string.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="xyz">Acceleration: X: Y: Z:</string> <string name="app_name">AccelerometerDemo</string> </resources>
main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/xyz" android:id="@+id/acceleration" /> </LinearLayout>
public void onSensorChanged(SensorEvent event); public void onAccuracyChanged(Sensor arg0, int arg1);We really only care about code in the former method.
package org.pollett; import java.util.List; import android.app.Activity; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.widget.TextView; public class AccelerometerDemo extends Activity implements SensorEventListener { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); accelerationLabel = (TextView )this.findViewById(R.id.acceleration); manager = (SensorManager)getSystemService(SENSOR_SERVICE); List<Sensor> list = manager.getSensorList(Sensor.TYPE_ACCELEROMETER); if(list != null && list.size() > 0) { accelerometer = list.get(0); } } @Override public void onResume() { super.onResume(); if(accelerometer != null) { manager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL); } } @Override public void onPause() { super.onPause(); if(accelerometer != null) { manager.unregisterListener(this); } } public void onAccuracyChanged(Sensor arg0, int arg1) { } public void onSensorChanged(SensorEvent event) { accelerationLabel.setText("Acceleration X:" + event.values[0] + " Y:" + event.values[1] + " Z:" + event.values[2]); } protected TextView accelerationLabel; protected SensorManager manager; protected Sensor accelerometer; }
[glView startAnimation];in appDidFinishLaunching
renderer = [[ES2Renderer alloc] init];
- (void) startAnimation { if (!animating) { if (displayLinkSupported) { // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will // not be called in system versions earlier than 3.1. displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)]; [displayLink setFrameInterval:animationFrameInterval]; [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; } else animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0 / 60.0) * animationFrameInterval) target:self selector:@selector(drawView:) userInfo:nil repeats:TRUE]; animating = TRUE; } }
- (void) drawView:(id)sender { [renderer render]; }
// Create an ES 2.0 context - (id) init { if (self = [super init]) { context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; if (!context || ![EAGLContext setCurrentContext:context] || ![self loadShaders]) { [self release]; return nil; } // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer glGenFramebuffers(1, &defaultFramebuffer); glGenRenderbuffers(1, &colorRenderbuffer); glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); } return self; }
The code to render things should look reasonably familiar if you followed the Android examples...
- (void) render { // 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 GLubyte squareColors[] = { 255, 255, 0, 255, 0, 255, 255, 255, 0, 0, 0, 0, 255, 0, 255, 255, }; static float transY = 0.0f; // This application only creates a single context which is already set current at this point. // This call is redundant, but needed if dealing with multiple contexts. [EAGLContext setCurrentContext:context]; // This application only creates a single default framebuffer which is already bound at this point. // This call is redundant, but needed if dealing with multiple framebuffers. glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); glViewport(0, 0, backingWidth, backingHeight); glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // Use shader program glUseProgram(program); // Update uniform value glUniform1f(uniforms[UNIFORM_TRANSLATE], (GLfloat)transY); transY += 0.075f; // Update attribute values glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); glEnableVertexAttribArray(ATTRIB_VERTEX); glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, 1, 0, squareColors); glEnableVertexAttribArray(ATTRIB_COLOR); // Validate program before drawing. This is a good check, but only really necessary in a debug build. // DEBUG macro must be defined in your debug configurations if that's not already the case. #if defined(DEBUG) if (![self validateProgram:program]) { NSLog(@"Failed to validate program: %d", program); return; } #endif // Draw glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // This application only creates a single color renderbuffer which is already bound at this point. // This call is redundant, but needed if dealing with multiple renderbuffers. glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); [context presentRenderbuffer:GL_RENDERBUFFER]; }
glViewport(0, 0, backingWidth, backingHeight);corresponds to the code we had in our Android application
gl.glViewport(0, 0, view.getWidth(), view.getHeight());