123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- /*
- Simple DirectMedia Layer
- Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- */
- #include "../../SDL_internal.h"
- #if SDL_VIDEO_DRIVER_UIKIT
- #include <QuartzCore/QuartzCore.h>
- #include <OpenGLES/EAGLDrawable.h>
- #include "SDL_uikitopenglview.h"
- #include "SDL_uikitmessagebox.h"
- @implementation SDL_uikitopenglview
- @synthesize context;
- + (Class)layerClass
- {
- return [CAEAGLLayer class];
- }
- - (id)initWithFrame:(CGRect)frame
- scale:(CGFloat)scale
- retainBacking:(BOOL)retained
- rBits:(int)rBits
- gBits:(int)gBits
- bBits:(int)bBits
- aBits:(int)aBits
- depthBits:(int)depthBits
- stencilBits:(int)stencilBits
- majorVersion:(int)majorVersion
- shareGroup:(EAGLSharegroup*)shareGroup
- {
- depthBufferFormat = 0;
- if ((self = [super initWithFrame:frame])) {
- const BOOL useStencilBuffer = (stencilBits != 0);
- const BOOL useDepthBuffer = (depthBits != 0);
- NSString *colorFormat = nil;
- /* The EAGLRenderingAPI enum values currently map 1:1 to major GLES
- versions, and this allows us to handle future OpenGL ES versions.
- */
- EAGLRenderingAPI api = majorVersion;
- if (rBits == 8 && gBits == 8 && bBits == 8) {
- /* if user specifically requests rbg888 or some color format higher than 16bpp */
- colorFormat = kEAGLColorFormatRGBA8;
- } else {
- /* default case (faster) */
- colorFormat = kEAGLColorFormatRGB565;
- }
- /* Get the layer */
- CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
- eaglLayer.opaque = YES;
- eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool: retained], kEAGLDrawablePropertyRetainedBacking, colorFormat, kEAGLDrawablePropertyColorFormat, nil];
- context = [[EAGLContext alloc] initWithAPI:api sharegroup:shareGroup];
- if (!context || ![EAGLContext setCurrentContext:context]) {
- [self release];
- SDL_SetError("OpenGL ES %d not supported", majorVersion);
- return nil;
- }
- /* Set the appropriate scale (for retina display support) */
- if ([self respondsToSelector:@selector(contentScaleFactor)])
- self.contentScaleFactor = scale;
- /* create the buffers */
- glGenFramebuffersOES(1, &viewFramebuffer);
- glGenRenderbuffersOES(1, &viewRenderbuffer);
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
- [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
- glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
- if ((useDepthBuffer) || (useStencilBuffer)) {
- if (useStencilBuffer) {
- /* Apparently you need to pack stencil and depth into one buffer. */
- depthBufferFormat = GL_DEPTH24_STENCIL8_OES;
- } else if (useDepthBuffer) {
- /* iOS only has 24-bit depth buffers, even with GL_DEPTH_COMPONENT16_OES */
- depthBufferFormat = GL_DEPTH_COMPONENT24_OES;
- }
- glGenRenderbuffersOES(1, &depthRenderbuffer);
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
- glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depthBufferFormat, backingWidth, backingHeight);
- if (useDepthBuffer) {
- glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
- }
- if (useStencilBuffer) {
- glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
- }
- }
- if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
- return NO;
- }
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
- /* end create buffers */
- self.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
- self.autoresizesSubviews = YES;
- }
- return self;
- }
- - (void)updateFrame
- {
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0);
- glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, 0);
- glDeleteRenderbuffersOES(1, &viewRenderbuffer);
- glGenRenderbuffersOES(1, &viewRenderbuffer);
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
- [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
- glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
- if (depthRenderbuffer != 0) {
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
- glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depthBufferFormat, backingWidth, backingHeight);
- }
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
- }
- - (void)setAnimationCallback:(int)interval
- callback:(void (*)(void*))callback
- callbackParam:(void*)callbackParam
- {
- [self stopAnimation];
- animationInterval = interval;
- animationCallback = callback;
- animationCallbackParam = callbackParam;
- if (animationCallback)
- [self startAnimation];
- }
- - (void)startAnimation
- {
- /* 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:.
- */
- displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doLoop:)];
- [displayLink setFrameInterval:animationInterval];
- [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
- }
- - (void)stopAnimation
- {
- [displayLink invalidate];
- displayLink = nil;
- }
- - (void)doLoop:(id)sender
- {
- /* Don't run the game loop while a messagebox is up */
- if (!UIKit_ShowingMessageBox()) {
- animationCallback(animationCallbackParam);
- }
- }
- - (void)setCurrentContext
- {
- [EAGLContext setCurrentContext:context];
- }
- - (void)swapBuffers
- {
- /* viewRenderbuffer should always be bound here. Code that binds something
- else is responsible for rebinding viewRenderbuffer, to reduce
- duplicate state changes. */
- [context presentRenderbuffer:GL_RENDERBUFFER_OES];
- }
- - (void)layoutSubviews
- {
- [EAGLContext setCurrentContext:context];
- [self updateFrame];
- }
- - (void)destroyFramebuffer
- {
- glDeleteFramebuffersOES(1, &viewFramebuffer);
- viewFramebuffer = 0;
- glDeleteRenderbuffersOES(1, &viewRenderbuffer);
- viewRenderbuffer = 0;
- if (depthRenderbuffer) {
- glDeleteRenderbuffersOES(1, &depthRenderbuffer);
- depthRenderbuffer = 0;
- }
- }
- - (void)dealloc
- {
- [self destroyFramebuffer];
- if ([EAGLContext currentContext] == context) {
- [EAGLContext setCurrentContext:nil];
- }
- [context release];
- [super dealloc];
- }
- @end
- #endif /* SDL_VIDEO_DRIVER_UIKIT */
- /* vi: set ts=4 sw=4 expandtab: */
|