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