Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #import <QuartzCore/QuartzCore.h>
- #import <OpenGLES/ES1/glext.h>
- #import "GLView2D.h"
- #import "GLAppDelegate.h"
- #import "Util.h"
- #include <sys/sysctl.h>
- @interface GLView2D ()
- - (BOOL) _createContext;
- - (BOOL) _createSurface;
- - (void) _destroySurface;
- @end
- @implementation GLView2D
- @synthesize size = _size;
- @synthesize orientation = _orientation;
- @synthesize autoRotation = _autoRotation;
- @synthesize isSlowDevice = _isSlowDevice;
- + (Class) layerClass {
- return [CAEAGLLayer class];
- }
- - (id) init {
- if (!(self = [super initWithFrame:CGRectMake(0, 0, 320, 480)])) return nil;
- size_t size;
- sysctlbyname("hw.machine", NULL, &size, NULL, 0);
- char *machine = malloc(size);
- sysctlbyname("hw.machine", machine, &size, NULL, 0);
- NSString *platform = [NSString stringWithCString:machine encoding: NSUTF8StringEncoding];
- free(machine);
- _isSlowDevice =
- [platform isEqualToString:@"iPhone1,1"] || // iPhone 1G
- [platform isEqualToString:@"iPhone1,2"] || // iPhone 3G
- [platform isEqualToString:@"iPpod1,1"] || // iPod Touch 1G
- [platform isEqualToString:@"iPod2,1"]; // iPod Touch 2G
- _orientation = UIDeviceOrientationPortrait;
- if (![self _createContext]) {
- NSLog(@"Error creating OpenGL context.");
- [self release];
- return nil;
- }
- if ([[[UIDevice currentDevice] systemVersion] compare:@"3.1" options:NSNumericSearch] != NSOrderedAscending) {
- _displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(tick)];
- [_displayLink setFrameInterval:_isSlowDevice ? 2 : 1];
- [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
- [_displayLink setPaused:YES];
- } else {
- NSLog(@"WARNING: Running on pre-3.1 OS.");
- _timer = [[Timer alloc] initWithTicksPerSecond:_isSlowDevice ? 30 : 60 listener:self];
- }
- return self;
- }
- - (BOOL) _createContext {
- CAEAGLLayer *eaglLayer = (CAEAGLLayer*)[self layer];
- [eaglLayer setDrawableProperties:
- [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking,
- kEAGLColorFormatRGB565, kEAGLDrawablePropertyColorFormat, // kEAGLColorFormatRGBA8?
- nil
- ]
- ];
- _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
- if (!_context) return NO;
- if (![self _createSurface]) return NO;
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnable(GL_SCISSOR_TEST);
- glEnable(GL_TEXTURE_2D);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisable(GL_FOG);
- glDisable(GL_DEPTH_TEST);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glClearColor(0, 0, 0, 1);
- glClear(GL_COLOR_BUFFER_BIT);
- return YES;
- }
- - (BOOL) _createSurface {
- if (![EAGLContext setCurrentContext:_context]) return NO;
- GLuint oldRenderbuffer, oldFramebuffer;
- glGetIntegerv(GL_RENDERBUFFER_BINDING_OES, (GLint *)&oldRenderbuffer);
- glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint *)&oldFramebuffer);
- glGenRenderbuffersOES(1, &_renderBuffer);
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, _renderBuffer);
- CAEAGLLayer *eaglLayer = (CAEAGLLayer*)[self layer];
- if (![_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer]) {
- glDeleteRenderbuffersOES(1, &_renderBuffer);
- glBindRenderbufferOES(GL_RENDERBUFFER_BINDING_OES, oldRenderbuffer);
- return NO;
- }
- glGenFramebuffersOES(1, &_frameBuffer);
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, _frameBuffer);
- glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, _renderBuffer);
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, oldRenderbuffer);
- [self setupSurface];
- return YES;
- }
- - (void) setupSurface {
- _size = [self bounds].size;
- _size.width = roundf(_size.width);
- _size.height = roundf(_size.height);
- glDisable(GL_DITHER);
- glDisable(GL_DEPTH_TEST);
- glShadeModel(GL_FLAT);
- glViewport(0, 0, _size.width, _size.height);
- glScissor(0, 0, _size.width, _size.height);
- [self orthographic];
- }
- - (void) _destroySurface {
- [EAGLContext setCurrentContext:_context];
- glDeleteRenderbuffersOES(1, &_renderBuffer);
- _renderBuffer = 0;
- glDeleteFramebuffersOES(1, &_frameBuffer);
- _frameBuffer = 0;
- }
- // Called when the view is resized.
- - (void) layoutSubviews {
- CGRect bounds = [self bounds];
- if (roundf(bounds.size.width) == _size.width) return;
- if (roundf(bounds.size.height) == _size.height) return;
- [self _destroySurface];
- [self _createSurface];
- [self setupSurface];
- }
- - (void) dealloc {
- [_timer release];
- [fpsFont release];
- [self _destroySurface];
- [EAGLContext setCurrentContext:nil];
- [_context release]; _context = nil;
- [super dealloc];
- }
- - (GLAppDelegate *) app {
- return [[UIApplication sharedApplication] delegate];
- }
- - (void) setShowFPS:(BOOL)showFPS font:(Font*)font {
- if (showFPS == _showFPS) return;
- _showFPS = showFPS;
- [fpsFont release];
- fpsFont = nil;
- if (_showFPS) {
- fpsFont = [font retain];
- if (!fpsFont) _showFPS = NO;
- }
- }
- @end
- @implementation GLView2D (Update)
- - (void) _setOrientationToDevice {
- UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
- if (deviceOrientation == _orientation) return;
- if (
- deviceOrientation != UIDeviceOrientationPortrait &&
- deviceOrientation != UIDeviceOrientationPortraitUpsideDown &&
- deviceOrientation != UIDeviceOrientationLandscapeLeft &&
- deviceOrientation != UIDeviceOrientationLandscapeRight
- ) return;
- _orientation = deviceOrientation;
- [self setupSurface];
- }
- - (void) setOrientation:(UIDeviceOrientation)orientation {
- _orientation = orientation;
- [self setupSurface];
- }
- - (void) tick {
- double timestamp = [_displayLink timestamp];
- [self tick:timestamp - _lastTimestamp];
- _lastTimestamp = timestamp;
- }
- - (void) tick:(double)delta {
- //if (_autoRotation) [self _setOrientationToDevice];
- glPushMatrix();
- [self update:delta];
- glPopMatrix();
- if (_showFPS) {
- fpsTime -= delta;
- if (fpsTime <= 0) {
- fpsTime = 1;
- fps = frameCount;
- frameCount = 0;
- NSLog(@"fps %d", fps);
- } else
- frameCount++;
- glColor4ub(255, 255, 255, 255);
- if (fps && NO)
- [fpsFont drawTextAtPoint:CGPointMake(10, 10) text:[NSString stringWithFormat:@"%d", fps]];
- }
- [self swapBuffers];
- }
- - (void) update:(double)delta {
- }
- - (void) start {
- [_displayLink setPaused:NO];
- [_timer start];
- }
- - (void) stop {
- [_displayLink setPaused:YES];
- [_timer stop];
- }
- - (void) shutdown {
- [_displayLink invalidate];
- _displayLink = nil;
- [_timer stop];
- }
- - (void) setAutoRotation:(BOOL)autoRotation {
- if (autoRotation == _autoRotation) return;
- _autoRotation = autoRotation;
- if (_autoRotation) {
- [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
- [self _setOrientationToDevice];
- } else
- [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
- }
- - (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
- return (interfaceOrientation==UIInterfaceOrientationLandscapeLeft ||
- interfaceOrientation==UIInterfaceOrientationLandscapeRight) ? YES : NO;
- }
- @end
- @implementation GLView2D (Drawing)
- - (void) swapBuffers {
- [EAGLContext setCurrentContext:_context];
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, _renderBuffer);
- if (![_context presentRenderbuffer:GL_RENDERBUFFER_OES])
- ERROR("Failed to swap render buffer.");
- }
- - (void) clear {
- glClear(GL_COLOR_BUFFER_BIT);
- }
- - (void) orthographic {
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- if (_orientation == UIDeviceOrientationPortraitUpsideDown) {
- glRotatef(180, 0, 0, 1);
- } else if (_orientation == UIDeviceOrientationLandscapeLeft) {
- CGFloat temp = _size.width;
- _size.width = _size.height;
- _size.height = temp;
- glRotatef(90, 0, 0, 1);
- } else if (_orientation == UIDeviceOrientationLandscapeRight) {
- CGFloat temp = _size.width;
- _size.width = _size.height;
- _size.height = temp;
- glRotatef(-90, 0, 0, 1);
- }
- glOrthof(0, _size.width, _size.height, 0, -1, 1);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- }
- - (void) perspectiveWithFOV:(double)fovy aspect:(double)aspect zNear:(double)zNear zFar:(double)zFar {
- if (_orientation == UIDeviceOrientationPortraitUpsideDown) {
- glRotatef(180, 0, 0, 1);
- } else if (_orientation == UIDeviceOrientationLandscapeLeft) {
- glRotatef(90, 0, 0, 1);
- } else if (_orientation == UIDeviceOrientationLandscapeRight) {
- glRotatef(-90, 0, 0, 1);
- }
- double ymax = zNear * tan(fovy * M_PI / 360.0);
- double ymin = -ymax;
- double xmin = ymin * aspect;
- double xmax = ymax * aspect;
- glFrustumf(xmin, xmax, ymin, ymax, zNear, zFar);
- }
- - (void) lookAtEyex:(GLfloat)eyex eyey:(GLfloat)eyey eyez:(GLfloat)eyez
- centerx:(GLfloat)centerx centery:(GLfloat)centery centerz:(GLfloat)centerz
- upx:(GLfloat)upx upy:(GLfloat)upy upz:(GLfloat)upz
- {
- GLfloat m[16];
- GLfloat x[3], y[3], z[3];
- GLfloat mag;
- // Make rotation matrix.
- // Z vector
- z[0] = eyex - centerx;
- z[1] = eyey - centery;
- z[2] = eyez - centerz;
- mag = sqrtf(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
- if (mag) { // mpichler, 19950515
- z[0] /= mag;
- z[1] /= mag;
- z[2] /= mag;
- }
- // Y vector
- y[0] = upx;
- y[1] = upy;
- y[2] = upz;
- // X vector = Y cross Z
- x[0] = y[1] * z[2] - y[2] * z[1];
- x[1] = -y[0] * z[2] + y[2] * z[0];
- x[2] = y[0] * z[1] - y[1] * z[0];
- // Recompute Y = Z cross X
- y[0] = z[1] * x[2] - z[2] * x[1];
- y[1] = -z[0] * x[2] + z[2] * x[0];
- y[2] = z[0] * x[1] - z[1] * x[0];
- // mpichler, 19950515
- // cross product gives area of parallelogram, which is < 1.0 for
- // non-perpendicular unit-length vectors; so normalize x, y here
- mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
- if (mag) {
- x[0] /= mag;
- x[1] /= mag;
- x[2] /= mag;
- }
- mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
- if (mag) {
- y[0] /= mag;
- y[1] /= mag;
- y[2] /= mag;
- }
- #define M(row,col) m[col*4+row]
- M(0, 0) = x[0];
- M(0, 1) = x[1];
- M(0, 2) = x[2];
- M(0, 3) = 0.0;
- M(1, 0) = y[0];
- M(1, 1) = y[1];
- M(1, 2) = y[2];
- M(1, 3) = 0.0;
- M(2, 0) = z[0];
- M(2, 1) = z[1];
- M(2, 2) = z[2];
- M(2, 3) = 0.0;
- M(3, 0) = 0.0;
- M(3, 1) = 0.0;
- M(3, 2) = 0.0;
- M(3, 3) = 1.0;
- #undef M
- glMultMatrixf(m);
- // Translate eye to origin.
- glTranslatef(-eyex, -eyey, -eyez);
- }
- @end
Add Comment
Please, Sign In to add comment