cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_uikitopenglview.m (8269B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
      4
      5  This software is provided 'as-is', without any express or implied
      6  warranty.  In no event will the authors be held liable for any damages
      7  arising from the use of this software.
      8
      9  Permission is granted to anyone to use this software for any purpose,
     10  including commercial applications, and to alter it and redistribute it
     11  freely, subject to the following restrictions:
     12
     13  1. The origin of this software must not be misrepresented; you must not
     14     claim that you wrote the original software. If you use this software
     15     in a product, an acknowledgment in the product documentation would be
     16     appreciated but is not required.
     17  2. Altered source versions must be plainly marked as such, and must not be
     18     misrepresented as being the original software.
     19  3. This notice may not be removed or altered from any source distribution.
     20*/
     21#include "../../SDL_internal.h"
     22
     23#if SDL_VIDEO_DRIVER_UIKIT
     24
     25#include <QuartzCore/QuartzCore.h>
     26#include <OpenGLES/EAGLDrawable.h>
     27#include "SDL_uikitopenglview.h"
     28#include "SDL_uikitmessagebox.h"
     29
     30
     31@implementation SDL_uikitopenglview
     32
     33@synthesize context;
     34
     35+ (Class)layerClass
     36{
     37    return [CAEAGLLayer class];
     38}
     39
     40- (id)initWithFrame:(CGRect)frame
     41      scale:(CGFloat)scale
     42      retainBacking:(BOOL)retained
     43      rBits:(int)rBits
     44      gBits:(int)gBits
     45      bBits:(int)bBits
     46      aBits:(int)aBits
     47      depthBits:(int)depthBits
     48      stencilBits:(int)stencilBits
     49      majorVersion:(int)majorVersion
     50      shareGroup:(EAGLSharegroup*)shareGroup
     51{
     52    depthBufferFormat = 0;
     53
     54    if ((self = [super initWithFrame:frame])) {
     55        const BOOL useStencilBuffer = (stencilBits != 0);
     56        const BOOL useDepthBuffer = (depthBits != 0);
     57        NSString *colorFormat = nil;
     58
     59        /* The EAGLRenderingAPI enum values currently map 1:1 to major GLES
     60           versions, and this allows us to handle future OpenGL ES versions.
     61         */
     62        EAGLRenderingAPI api = majorVersion;
     63
     64        if (rBits == 8 && gBits == 8 && bBits == 8) {
     65            /* if user specifically requests rbg888 or some color format higher than 16bpp */
     66            colorFormat = kEAGLColorFormatRGBA8;
     67        } else {
     68            /* default case (faster) */
     69            colorFormat = kEAGLColorFormatRGB565;
     70        }
     71
     72        /* Get the layer */
     73        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
     74
     75        eaglLayer.opaque = YES;
     76        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
     77                                        [NSNumber numberWithBool: retained], kEAGLDrawablePropertyRetainedBacking, colorFormat, kEAGLDrawablePropertyColorFormat, nil];
     78
     79        context = [[EAGLContext alloc] initWithAPI:api sharegroup:shareGroup];
     80        if (!context || ![EAGLContext setCurrentContext:context]) {
     81            [self release];
     82            SDL_SetError("OpenGL ES %d not supported", majorVersion);
     83            return nil;
     84        }
     85
     86        /* Set the appropriate scale (for retina display support) */
     87        self.contentScaleFactor = scale;
     88
     89        /* create the buffers */
     90        glGenFramebuffersOES(1, &viewFramebuffer);
     91        glGenRenderbuffersOES(1, &viewRenderbuffer);
     92
     93        glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
     94        glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
     95        [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
     96        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
     97
     98        glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
     99        glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
    100
    101        if ((useDepthBuffer) || (useStencilBuffer)) {
    102            if (useStencilBuffer) {
    103                /* Apparently you need to pack stencil and depth into one buffer. */
    104                depthBufferFormat = GL_DEPTH24_STENCIL8_OES;
    105            } else if (useDepthBuffer) {
    106                /* iOS only has 24-bit depth buffers, even with GL_DEPTH_COMPONENT16_OES */
    107                depthBufferFormat = GL_DEPTH_COMPONENT24_OES;
    108            }
    109
    110            glGenRenderbuffersOES(1, &depthRenderbuffer);
    111            glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
    112            glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depthBufferFormat, backingWidth, backingHeight);
    113            if (useDepthBuffer) {
    114                glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
    115            }
    116            if (useStencilBuffer) {
    117                glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
    118            }
    119        }
    120
    121        if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
    122            return NO;
    123        }
    124
    125        glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    126        /* end create buffers */
    127
    128        self.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
    129        self.autoresizesSubviews = YES;
    130    }
    131    return self;
    132}
    133
    134- (void)updateFrame
    135{
    136    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    137    glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0);
    138    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, 0);
    139    glDeleteRenderbuffersOES(1, &viewRenderbuffer);
    140
    141    glGenRenderbuffersOES(1, &viewRenderbuffer);
    142    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    143    [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
    144    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
    145
    146    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
    147    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
    148
    149    if (depthRenderbuffer != 0) {
    150        glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
    151        glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depthBufferFormat, backingWidth, backingHeight);
    152    }
    153
    154    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    155}
    156
    157- (void)setAnimationCallback:(int)interval
    158    callback:(void (*)(void*))callback
    159    callbackParam:(void*)callbackParam
    160{
    161    [self stopAnimation];
    162
    163    animationInterval = interval;
    164    animationCallback = callback;
    165    animationCallbackParam = callbackParam;
    166
    167    if (animationCallback)
    168        [self startAnimation];
    169}
    170
    171- (void)startAnimation
    172{
    173    displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(doLoop:)];
    174    [displayLink setFrameInterval:animationInterval];
    175    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    176}
    177
    178- (void)stopAnimation
    179{
    180    [displayLink invalidate];
    181    displayLink = nil;
    182}
    183
    184- (void)doLoop:(CADisplayLink*)sender
    185{
    186    /* Don't run the game loop while a messagebox is up */
    187    if (!UIKit_ShowingMessageBox()) {
    188        animationCallback(animationCallbackParam);
    189    }
    190}
    191
    192- (void)setCurrentContext
    193{
    194    [EAGLContext setCurrentContext:context];
    195}
    196
    197
    198- (void)swapBuffers
    199{
    200    /* viewRenderbuffer should always be bound here. Code that binds something
    201        else is responsible for rebinding viewRenderbuffer, to reduce
    202        duplicate state changes. */
    203    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
    204}
    205
    206
    207- (void)layoutSubviews
    208{
    209    [EAGLContext setCurrentContext:context];
    210    [self updateFrame];
    211}
    212
    213- (void)destroyFramebuffer
    214{
    215    glDeleteFramebuffersOES(1, &viewFramebuffer);
    216    viewFramebuffer = 0;
    217    glDeleteRenderbuffersOES(1, &viewRenderbuffer);
    218    viewRenderbuffer = 0;
    219
    220    if (depthRenderbuffer) {
    221        glDeleteRenderbuffersOES(1, &depthRenderbuffer);
    222        depthRenderbuffer = 0;
    223    }
    224}
    225
    226
    227- (void)dealloc
    228{
    229    [self destroyFramebuffer];
    230    if ([EAGLContext currentContext] == context) {
    231        [EAGLContext setCurrentContext:nil];
    232    }
    233    [context release];
    234    [super dealloc];
    235}
    236
    237@end
    238
    239#endif /* SDL_VIDEO_DRIVER_UIKIT */
    240
    241/* vi: set ts=4 sw=4 expandtab: */