zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_uikitopenglview.m
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 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_config.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  if (rBits == 8 && gBits == 8 && bBits == 8) {
60  /* if user specifically requests rbg888 or some color format higher than 16bpp */
61  colorFormat = kEAGLColorFormatRGBA8;
62  } else {
63  /* default case (faster) */
64  colorFormat = kEAGLColorFormatRGB565;
65  }
66 
67  /* Get the layer */
68  CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
69 
70  eaglLayer.opaque = YES;
71  eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
72  [NSNumber numberWithBool: retained], kEAGLDrawablePropertyRetainedBacking, colorFormat, kEAGLDrawablePropertyColorFormat, nil];
73 
74  if (majorVersion > 1) {
75  context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:shareGroup];
76  } else {
77  context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1 sharegroup:shareGroup];
78  }
79  if (!context || ![EAGLContext setCurrentContext:context]) {
80  [self release];
81  SDL_SetError("OpenGL ES %d not supported", majorVersion);
82  return nil;
83  }
84 
85  /* Set the appropriate scale (for retina display support) */
86  if ([self respondsToSelector:@selector(contentScaleFactor)])
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  /* end create buffers */
125 
126  self.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
127  self.autoresizesSubviews = YES;
128  }
129  return self;
130 }
131 
132 - (void)updateFrame
133 {
134  glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
135  glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0);
136  glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, 0);
137  glDeleteRenderbuffersOES(1, &viewRenderbuffer);
138 
139  glGenRenderbuffersOES(1, &viewRenderbuffer);
140  glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
141  [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
142  glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
143 
144  glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
145  glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
146 
147  if (depthRenderbuffer != 0) {
148  glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
149  glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depthBufferFormat, backingWidth, backingHeight);
150  }
151 }
152 
153 - (void)setAnimationCallback:(int)interval
154  callback:(void (*)(void*))callback
155  callbackParam:(void*)callbackParam
156 {
157  [self stopAnimation];
158 
159  animationInterval = interval;
160  animationCallback = callback;
161  animationCallbackParam = callbackParam;
162 
163  if (animationCallback)
164  [self startAnimation];
165 }
166 
168 {
169  /* CADisplayLink is API new to iPhone SDK 3.1.
170  * Compiling against earlier versions will result in a warning, but can be dismissed
171  * if the system version runtime check for CADisplayLink exists in -initWithCoder:.
172  */
173  displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doLoop:)];
174  [displayLink setFrameInterval:animationInterval];
175  [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
176 }
177 
179 {
180  [displayLink invalidate];
181  displayLink = nil;
182 }
183 
184 - (void)doLoop:(id)sender
185 {
186  /* Don't run the game loop while a messagebox is up */
187  if (!UIKit_ShowingMessageBox()) {
188  animationCallback(animationCallbackParam);
189  }
190 }
191 
193 {
194  [EAGLContext setCurrentContext:context];
195 }
196 
197 
198 - (void)swapBuffers
199 {
200  glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
201  [context presentRenderbuffer:GL_RENDERBUFFER_OES];
202 }
203 
204 
205 - (void)layoutSubviews
206 {
207  [EAGLContext setCurrentContext:context];
208  [self updateFrame];
209 }
210 
211 - (void)destroyFramebuffer
212 {
213  glDeleteFramebuffersOES(1, &viewFramebuffer);
214  viewFramebuffer = 0;
215  glDeleteRenderbuffersOES(1, &viewRenderbuffer);
216  viewRenderbuffer = 0;
217 
218  if (depthRenderbuffer) {
219  glDeleteRenderbuffersOES(1, &depthRenderbuffer);
220  depthRenderbuffer = 0;
221  }
222 }
223 
224 
225 - (void)dealloc
226 {
227  [self destroyFramebuffer];
228  if ([EAGLContext currentContext] == context) {
229  [EAGLContext setCurrentContext:nil];
230  }
231  [context release];
232  [super dealloc];
233 }
234 
235 @end
236 
237 #endif /* SDL_VIDEO_DRIVER_UIKIT */
238 
239 /* vi: set ts=4 sw=4 expandtab: */
#define GL_DEPTH_COMPONENT24_OES
Definition: gl2ext.h:44
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
GLint GLboolean GLint layer
Definition: glew.h:3462
GLuint id
Definition: gl2ext.h:1142
GLenum GLenum colorFormat
Definition: glew.h:12405
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:12632
TParseContext * context
#define GL_DEPTH24_STENCIL8_OES
Definition: gl2ext.h:93
typedef BOOL(WINAPI *PFNWGLSETSTEREOEMITTERSTATE3DLPROC)(HDC hDC