src/video/uikit/SDL_uikitopenglview.m
author Sam Lantinga <slouken@libsdl.org>
Tue, 01 Feb 2011 09:00:47 -0800
changeset 5132 5f09cb749d75
parent 5130 ec13e48ee0d9
child 5209 115fff0641ee
permissions -rw-r--r--
Added vim spacing hints
     1 /*
     2  SDL - Simple DirectMedia Layer
     3  Copyright (C) 1997-2009 Sam Lantinga
     4  
     5  This library is free software; you can redistribute it and/or
     6  modify it under the terms of the GNU Lesser General Public
     7  License as published by the Free Software Foundation; either
     8  version 2.1 of the License, or (at your option) any later version.
     9  
    10  This library is distributed in the hope that it will be useful,
    11  but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13  Lesser General Public License for more details.
    14  
    15  You should have received a copy of the GNU Lesser General Public
    16  License along with this library; if not, write to the Free Software
    17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18  
    19  Sam Lantinga
    20  slouken@libsdl.org
    21  */
    22 
    23 #import <QuartzCore/QuartzCore.h>
    24 #import <OpenGLES/EAGLDrawable.h>
    25 #import "SDL_uikitopenglview.h"
    26 
    27 @interface SDL_uikitopenglview (privateMethods)
    28 
    29 - (BOOL) createFramebuffer;
    30 - (void) destroyFramebuffer;
    31 
    32 @end
    33 
    34 
    35 @implementation SDL_uikitopenglview
    36 
    37 @synthesize context;
    38 
    39 + (Class)layerClass {
    40     return [CAEAGLLayer class];
    41 }
    42 
    43 - (id)initWithFrame:(CGRect)frame \
    44       retainBacking:(BOOL)retained \
    45       rBits:(int)rBits \
    46       gBits:(int)gBits \
    47       bBits:(int)bBits \
    48       aBits:(int)aBits \
    49       depthBits:(int)depthBits \
    50 {
    51     NSString *colorFormat=nil;
    52     GLuint depthBufferFormat;
    53     BOOL useDepthBuffer;
    54     
    55     if (rBits == 8 && gBits == 8 && bBits == 8) {
    56         /* if user specifically requests rbg888 or some color format higher than 16bpp */
    57         colorFormat = kEAGLColorFormatRGBA8;
    58     }
    59     else {
    60         /* default case (faster) */
    61         colorFormat = kEAGLColorFormatRGB565;
    62     }
    63     
    64     if (depthBits == 24) {
    65         useDepthBuffer = YES;
    66         depthBufferFormat = GL_DEPTH_COMPONENT24_OES;
    67     }
    68     else if (depthBits == 0) {
    69         useDepthBuffer = NO;
    70     }
    71     else {
    72         /* default case when depth buffer is not disabled */
    73         /* 
    74            strange, even when we use this, we seem to get a 24 bit depth buffer on iPhone.
    75            perhaps that's the only depth format iPhone actually supports
    76         */
    77         useDepthBuffer = YES;
    78         depthBufferFormat = GL_DEPTH_COMPONENT16_OES;
    79     }
    80     
    81     if ((self = [super initWithFrame:frame])) {
    82         // Get the layer
    83         CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
    84         
    85         eaglLayer.opaque = YES;
    86         eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
    87                                         [NSNumber numberWithBool: retained], kEAGLDrawablePropertyRetainedBacking, colorFormat, kEAGLDrawablePropertyColorFormat, nil];
    88         
    89         context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES1];
    90         
    91         if (!context || ![EAGLContext setCurrentContext:context]) {
    92             [self release];
    93             return nil;
    94         }
    95         
    96         /* create the buffers */
    97         glGenFramebuffersOES(1, &viewFramebuffer);
    98         glGenRenderbuffersOES(1, &viewRenderbuffer);
    99         
   100         glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
   101         glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
   102         [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
   103         glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
   104         
   105         glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
   106         glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
   107         
   108         if (useDepthBuffer) {
   109             glGenRenderbuffersOES(1, &depthRenderbuffer);
   110             glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
   111             glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depthBufferFormat, backingWidth, backingHeight);
   112             glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
   113         }
   114             
   115         if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
   116             return NO;
   117         }
   118         /* end create buffers */
   119 
   120         /* Use the main screen scale (for retina display support) */
   121         if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
   122             self.contentScaleFactor = [UIScreen mainScreen].scale;
   123     }
   124     return self;
   125 }
   126 
   127 - (void)setCurrentContext {
   128     [EAGLContext setCurrentContext:context];
   129 }
   130 
   131 
   132 - (void)swapBuffers {
   133     glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
   134     [context presentRenderbuffer:GL_RENDERBUFFER_OES];
   135 }
   136 
   137 
   138 - (void)layoutSubviews {
   139     [EAGLContext setCurrentContext:context];
   140 }
   141 
   142 - (void)destroyFramebuffer {
   143     glDeleteFramebuffersOES(1, &viewFramebuffer);
   144     viewFramebuffer = 0;
   145     glDeleteRenderbuffersOES(1, &viewRenderbuffer);
   146     viewRenderbuffer = 0;
   147     
   148     if (depthRenderbuffer) {
   149         glDeleteRenderbuffersOES(1, &depthRenderbuffer);
   150         depthRenderbuffer = 0;
   151     }
   152 }
   153 
   154 
   155 - (void)dealloc {
   156     [self destroyFramebuffer];
   157     if ([EAGLContext currentContext] == context) {
   158         [EAGLContext setCurrentContext:nil];
   159     }
   160     [context release];    
   161     [super dealloc];
   162 }
   163 
   164 @end
   165 
   166 /* vi: set ts=4 sw=4 expandtab: */