Skip to content

Latest commit

 

History

History
277 lines (222 loc) · 8.94 KB

SDL_uikitopenglview.m

File metadata and controls

277 lines (222 loc) · 8.94 KB
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
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 <OpenGLES/EAGLDrawable.h>
Oct 28, 2014
Oct 28, 2014
26
#include <OpenGLES/ES2/glext.h>
Jan 15, 2015
Jan 15, 2015
27
28
#import "SDL_uikitopenglview.h"
#include "SDL_uikitwindow.h"
Jan 15, 2015
Jan 15, 2015
30
@implementation SDLEAGLContext
Jan 15, 2015
Jan 15, 2015
32
@end
Jul 23, 2014
Jul 23, 2014
33
Jan 15, 2015
Jan 15, 2015
34
35
@implementation SDL_uikitopenglview {
/* The renderbuffer and framebuffer used to render to this layer. */
Jul 23, 2014
Jul 23, 2014
36
37
GLuint viewRenderbuffer, viewFramebuffer;
Jan 15, 2015
Jan 15, 2015
38
/* The depth buffer that is attached to viewFramebuffer, if it exists. */
Jul 23, 2014
Jul 23, 2014
39
40
41
42
43
GLuint depthRenderbuffer;
/* format of depthRenderbuffer */
GLenum depthBufferFormat;
}
44
45
@synthesize context;
Jul 23, 2014
Jul 23, 2014
46
47
@synthesize backingWidth;
@synthesize backingHeight;
Jul 15, 2014
Jul 15, 2014
48
49
50
51
52
53
+ (Class)layerClass
{
return [CAEAGLLayer class];
}
Jan 15, 2015
Jan 15, 2015
54
55
56
57
58
59
60
61
62
63
64
65
- (instancetype)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
sRGB:(BOOL)sRGB
majorVersion:(int)majorVersion
shareGroup:(EAGLSharegroup*)shareGroup
66
67
68
69
70
71
72
{
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
Jan 15, 2015
Jan 15, 2015
73
* versions, and this allows us to handle future OpenGL ES versions. */
74
75
EAGLRenderingAPI api = majorVersion;
Jan 15, 2015
Jan 15, 2015
76
context = [[SDLEAGLContext alloc] initWithAPI:api sharegroup:shareGroup];
Jul 22, 2014
Jul 22, 2014
77
78
79
80
81
if (!context || ![EAGLContext setCurrentContext:context]) {
SDL_SetError("OpenGL ES %d not supported", majorVersion);
return nil;
}
Jan 15, 2015
Jan 15, 2015
82
83
context.sdlView = self;
Oct 28, 2014
Oct 28, 2014
84
85
if (sRGB) {
/* sRGB EAGL drawable support was added in iOS 7. */
Nov 21, 2014
Nov 21, 2014
86
if (UIKit_IsSystemVersionAtLeast(7.0)) {
Oct 28, 2014
Oct 28, 2014
87
88
89
90
91
92
colorFormat = kEAGLColorFormatSRGBA8;
} else {
SDL_SetError("sRGB drawables are not supported.");
return nil;
}
} else if (rBits >= 8 || gBits >= 8 || bBits >= 8) {
93
94
95
/* if user specifically requests rbg888 or some color format higher than 16bpp */
colorFormat = kEAGLColorFormatRGBA8;
} else {
Jan 15, 2015
Jan 15, 2015
96
/* default case (potentially faster) */
97
98
99
100
101
102
colorFormat = kEAGLColorFormatRGB565;
}
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
eaglLayer.opaque = YES;
Jul 23, 2014
Jul 23, 2014
103
eaglLayer.drawableProperties = @{
Nov 20, 2014
Nov 20, 2014
104
105
kEAGLDrawablePropertyRetainedBacking:@(retained),
kEAGLDrawablePropertyColorFormat:colorFormat
Jul 23, 2014
Jul 23, 2014
106
};
107
108
/* Set the appropriate scale (for retina display support) */
Jun 21, 2014
Jun 21, 2014
109
self.contentScaleFactor = scale;
Jul 22, 2014
Jul 22, 2014
111
/* Create the color Renderbuffer Object */
Oct 28, 2014
Oct 28, 2014
112
113
glGenRenderbuffers(1, &viewRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
Oct 28, 2014
Oct 28, 2014
115
116
if (![context renderbufferStorage:GL_RENDERBUFFER fromDrawable:eaglLayer]) {
SDL_SetError("Failed to create OpenGL ES drawable");
Jul 22, 2014
Jul 22, 2014
117
118
119
120
return nil;
}
/* Create the Framebuffer Object */
Oct 28, 2014
Oct 28, 2014
121
122
glGenFramebuffers(1, &viewFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
Jul 22, 2014
Jul 22, 2014
123
124
/* attach the color renderbuffer to the FBO */
Oct 28, 2014
Oct 28, 2014
125
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer);
Oct 28, 2014
Oct 28, 2014
127
128
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
129
130
131
132
133
134
if ((useDepthBuffer) || (useStencilBuffer)) {
if (useStencilBuffer) {
/* Apparently you need to pack stencil and depth into one buffer. */
depthBufferFormat = GL_DEPTH24_STENCIL8_OES;
} else if (useDepthBuffer) {
Jan 15, 2015
Jan 15, 2015
135
136
/* iOS only uses 32-bit float (exposed as fixed point 24-bit)
* depth buffers. */
137
138
139
depthBufferFormat = GL_DEPTH_COMPONENT24_OES;
}
Oct 28, 2014
Oct 28, 2014
140
141
142
glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, depthBufferFormat, backingWidth, backingHeight);
143
if (useDepthBuffer) {
Oct 28, 2014
Oct 28, 2014
144
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
145
146
}
if (useStencilBuffer) {
Oct 28, 2014
Oct 28, 2014
147
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
148
149
150
}
}
Oct 28, 2014
Oct 28, 2014
151
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
Jul 22, 2014
Jul 22, 2014
152
153
SDL_SetError("Failed creating OpenGL ES framebuffer");
return nil;
154
155
}
Oct 28, 2014
Oct 28, 2014
156
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
Nov 21, 2014
Nov 21, 2014
157
158
[self setDebugLabels];
159
}
Jul 22, 2014
Jul 22, 2014
160
161
162
163
return self;
}
Aug 8, 2014
Aug 8, 2014
164
165
166
167
168
169
170
171
172
173
- (GLuint)drawableRenderbuffer
{
return viewRenderbuffer;
}
- (GLuint)drawableFramebuffer
{
return viewFramebuffer;
}
174
175
- (void)updateFrame
{
Nov 21, 2014
Nov 21, 2014
176
177
GLint prevRenderbuffer = 0;
glGetIntegerv(GL_RENDERBUFFER_BINDING, &prevRenderbuffer);
Oct 28, 2014
Oct 28, 2014
179
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
Jan 15, 2015
Jan 15, 2015
180
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
Oct 28, 2014
Oct 28, 2014
182
183
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
184
185
if (depthRenderbuffer != 0) {
Oct 28, 2014
Oct 28, 2014
186
187
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, depthBufferFormat, backingWidth, backingHeight);
188
189
}
Nov 21, 2014
Nov 21, 2014
190
glBindRenderbuffer(GL_RENDERBUFFER, prevRenderbuffer);
Nov 21, 2014
Nov 21, 2014
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
}
- (void)setDebugLabels
{
if (viewFramebuffer != 0) {
glLabelObjectEXT(GL_FRAMEBUFFER, viewFramebuffer, 0, "context FBO");
}
if (viewRenderbuffer != 0) {
glLabelObjectEXT(GL_RENDERBUFFER, viewRenderbuffer, 0, "context color buffer");
}
if (depthRenderbuffer != 0) {
if (depthBufferFormat == GL_DEPTH24_STENCIL8_OES) {
glLabelObjectEXT(GL_RENDERBUFFER, depthRenderbuffer, 0, "context depth-stencil buffer");
} else {
glLabelObjectEXT(GL_RENDERBUFFER, depthRenderbuffer, 0, "context depth buffer");
}
}
210
211
212
213
214
215
216
217
218
219
}
- (void)setCurrentContext
{
[EAGLContext setCurrentContext:context];
}
- (void)swapBuffers
{
/* viewRenderbuffer should always be bound here. Code that binds something
Jan 15, 2015
Jan 15, 2015
220
221
* else is responsible for rebinding viewRenderbuffer, to reduce duplicate
* state changes. */
Oct 28, 2014
Oct 28, 2014
222
[context presentRenderbuffer:GL_RENDERBUFFER];
223
224
225
226
}
- (void)layoutSubviews
{
Jul 21, 2014
Jul 21, 2014
227
228
[super layoutSubviews];
Jan 15, 2015
Jan 15, 2015
229
230
int width = (int) (self.bounds.size.width * self.contentScaleFactor);
int height = (int) (self.bounds.size.height * self.contentScaleFactor);
Nov 21, 2014
Nov 21, 2014
231
232
233
/* Update the color and depth buffer storage if the layer size has changed. */
if (width != backingWidth || height != backingHeight) {
Jan 15, 2015
Jan 15, 2015
234
235
236
237
238
EAGLContext *prevContext = [EAGLContext currentContext];
if (prevContext != context) {
[EAGLContext setCurrentContext:context];
}
Nov 21, 2014
Nov 21, 2014
239
[self updateFrame];
Jan 15, 2015
Jan 15, 2015
240
241
242
243
if (prevContext != context) {
[EAGLContext setCurrentContext:prevContext];
}
Nov 21, 2014
Nov 21, 2014
244
}
245
246
247
248
}
- (void)destroyFramebuffer
{
Jul 22, 2014
Jul 22, 2014
249
if (viewFramebuffer != 0) {
Oct 28, 2014
Oct 28, 2014
250
glDeleteFramebuffers(1, &viewFramebuffer);
Jul 22, 2014
Jul 22, 2014
251
252
253
254
viewFramebuffer = 0;
}
if (viewRenderbuffer != 0) {
Oct 28, 2014
Oct 28, 2014
255
glDeleteRenderbuffers(1, &viewRenderbuffer);
Jul 22, 2014
Jul 22, 2014
256
257
viewRenderbuffer = 0;
}
Jul 22, 2014
Jul 22, 2014
259
if (depthRenderbuffer != 0) {
Oct 28, 2014
Oct 28, 2014
260
glDeleteRenderbuffers(1, &depthRenderbuffer);
261
262
263
264
265
266
267
depthRenderbuffer = 0;
}
}
- (void)dealloc
{
if ([EAGLContext currentContext] == context) {
Aug 6, 2014
Aug 6, 2014
268
[self destroyFramebuffer];
269
270
271
272
273
274
275
276
277
[EAGLContext setCurrentContext:nil];
}
}
@end
#endif /* SDL_VIDEO_DRIVER_UIKIT */
/* vi: set ts=4 sw=4 expandtab: */