Skip to content

Commit 89a99c8

Browse files
committed
Make framebuffer objects abstract.
1 parent 4cb674d commit 89a99c8

File tree

7 files changed

+153
-128
lines changed

7 files changed

+153
-128
lines changed

CCRendererGLSupport.m

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
#import "CCRenderer_Private.h"
26+
#import "CCTexture_Private.h"
2627

2728
#import "CCRenderDispatch.h"
2829

@@ -243,3 +244,142 @@ -(void)bind:(BOOL)bind
243244
}
244245

245246
@end
247+
248+
249+
@interface CCFrameBufferObjectGL : CCFrameBufferObject @end
250+
@implementation CCFrameBufferObjectGL {
251+
GLuint _fbo;
252+
GLuint _depthRenderBuffer;
253+
GLuint _stencilRenderBuffer;
254+
}
255+
256+
-(instancetype)initWithTexture:(CCTexture *)texture depthStencilFormat:(GLuint)depthStencilFormat
257+
{
258+
if((self = [super initWithTexture:texture depthStencilFormat:depthStencilFormat])){
259+
CCRenderDispatch(NO, ^{
260+
CCGL_DEBUG_PUSH_GROUP_MARKER("CCRenderTexture: Create");
261+
262+
// generate FBO
263+
glGenFramebuffers(1, &_fbo);
264+
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
265+
266+
// associate texture with FBO
267+
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.name, 0);
268+
269+
CGSize sizeInPixels = texture.contentSizeInPixels;
270+
GLuint width = ceil(sizeInPixels.width);
271+
GLuint height = ceil(sizeInPixels.height);
272+
273+
#if __CC_PLATFORM_ANDROID
274+
275+
// Some android devices *only* support combined depth buffers (like all iOS devices), some android devices do not
276+
// support combined depth buffers, thus we have to create a seperate stencil buffer
277+
if(_depthStencilFormat)
278+
{
279+
//create and attach depth buffer
280+
281+
if(![[CCConfiguration sharedConfiguration] supportsPackedDepthStencil])
282+
{
283+
glGenRenderbuffers(1, &depthRenderBuffer);
284+
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer);
285+
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); //GL_DEPTH_COMPONENT24_OES
286+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer);
287+
288+
// if depth format is the one with stencil part, bind same render buffer as stencil attachment
289+
if(_depthStencilFormat == GL_DEPTH24_STENCIL8)
290+
{
291+
glGenRenderbuffers(1, &stencilRenderBuffer);
292+
glBindRenderbuffer(GL_RENDERBUFFER, stencilRenderBuffer);
293+
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, powH);
294+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencilRenderBuffer);
295+
}
296+
}
297+
else
298+
{
299+
glGenRenderbuffers(1, &depthRenderBuffer);
300+
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer);
301+
glRenderbufferStorage(GL_RENDERBUFFER, _depthStencilFormat, width, height);
302+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer);
303+
304+
// if depth format is the one with stencil part, bind same render buffer as stencil attachment
305+
if(_depthStencilFormat == GL_DEPTH24_STENCIL8){
306+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer);
307+
}
308+
}
309+
}
310+
311+
#else
312+
313+
if(depthStencilFormat){
314+
//create and attach depth buffer
315+
glGenRenderbuffers(1, &_depthRenderBuffer);
316+
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
317+
glRenderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, width, height);
318+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
319+
320+
// associate texture with FBO
321+
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.name, 0);
322+
323+
if(depthStencilFormat){
324+
//create and attach depth buffer
325+
glGenRenderbuffers(1, &_depthRenderBuffer);
326+
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
327+
glRenderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, width, height);
328+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
329+
330+
// if depth format is the one with stencil part, bind same render buffer as stencil attachment
331+
if(depthStencilFormat == GL_DEPTH24_STENCIL8){
332+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
333+
}
334+
}
335+
}
336+
337+
#endif
338+
339+
// check if it worked (probably worth doing :) )
340+
NSAssert( glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, @"Could not attach texture to framebuffer");
341+
342+
CCGL_DEBUG_POP_GROUP_MARKER();
343+
CC_CHECK_GL_ERROR_DEBUG();
344+
});
345+
}
346+
return self;
347+
}
348+
349+
-(void)dealloc
350+
{
351+
GLuint fbo = _fbo;
352+
GLuint depthRenderBuffer = _depthRenderBuffer;
353+
GLuint stencilRenderBuffer = _stencilRenderBuffer;
354+
355+
CCRenderDispatch(YES, ^{
356+
glDeleteFramebuffers(1, &fbo);
357+
358+
if(depthRenderBuffer){
359+
glDeleteRenderbuffers(1, &depthRenderBuffer);
360+
}
361+
362+
if(depthRenderBuffer){
363+
glDeleteRenderbuffers(1, &stencilRenderBuffer);
364+
}
365+
});
366+
}
367+
368+
-(void)bind
369+
{
370+
CGSize size = self.sizeInPixels;
371+
glViewport(0, 0, size.width, size.height);
372+
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
373+
}
374+
375+
-(void)syncWithView:(CC_VIEW<CCDirectorView> *)view;
376+
{
377+
CCGLView *glView = (CCGLView *)view;
378+
self.sizeInPixels = CC_SIZE_SCALE(view.bounds.size, view.contentScaleFactor);
379+
self.contentScale = view.contentScaleFactor;
380+
381+
#warning TODO does this need to handle MSAA specially?
382+
_fbo = glView->_renderer.defaultFrameBuffer;
383+
}
384+
385+
@end

cocos2d/CCConfiguration.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ extern Class CCGraphicsBufferClass;
3131
extern Class CCGraphicsBufferBindingsClass;
3232
extern Class CCRenderStateClass;
3333
extern Class CCRenderCommandDrawClass;
34+
extern Class CCFrameBufferObjectClass;
3435

3536
extern NSString* const CCSetupPixelFormat;
3637
extern NSString* const CCSetupScreenMode;

cocos2d/CCConfiguration.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
Class CCGraphicsBufferBindingsClass;
4444
Class CCRenderStateClass;
4545
Class CCRenderCommandDrawClass;
46+
Class CCFrameBufferObjectClass;
4647

4748
NSString* const CCSetupPixelFormat = @"CCSetupPixelFormat";
4849
NSString* const CCSetupScreenMode = @"CCSetupScreenMode";
@@ -143,6 +144,7 @@ -(CCGraphicsAPI)graphicsAPI
143144
CCGraphicsBufferBindingsClass = NSClassFromString(@"CCGraphicsBufferBindingsMetal");
144145
CCRenderStateClass = NSClassFromString(@"CCRenderStateMetal");
145146
CCRenderCommandDrawClass = NSClassFromString(@"CCRenderCommandDrawMetal");
147+
CCFrameBufferObjectClass = NSClassFromString(@"CCFrameBufferObjectMetal");
146148

147149
_graphicsAPI = CCGraphicsAPIMetal;
148150
} else
@@ -152,6 +154,7 @@ -(CCGraphicsAPI)graphicsAPI
152154
CCGraphicsBufferBindingsClass = NSClassFromString(@"CCGraphicsBufferBindingsGL");
153155
CCRenderStateClass = NSClassFromString(@"CCRenderStateGL");
154156
CCRenderCommandDrawClass = NSClassFromString(@"CCRenderCommandDrawGL");
157+
CCFrameBufferObjectClass = NSClassFromString(@"CCFrameBufferObjectGL");
155158

156159
_graphicsAPI = CCGraphicsAPIGL;
157160
}
@@ -160,6 +163,7 @@ -(CCGraphicsAPI)graphicsAPI
160163
NSAssert(CCGraphicsBufferBindingsClass, @"CCGraphicsBufferBindingsClass not configured.");
161164
NSAssert(CCRenderStateClass, @"CCRenderStateClass not configured.");
162165
NSAssert(CCRenderCommandDrawClass, @"CCRenderCommandDrawClass not configured.");
166+
NSAssert(CCFrameBufferObjectClass, @"CCFrameBufferObjectClass not configured.");
163167
}
164168

165169
return _graphicsAPI;

cocos2d/CCDirector.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ - (id) init
203203
_rendererPool = [NSMutableArray array];
204204
_globalShaderUniforms = [NSMutableDictionary dictionary];
205205

206-
_framebuffer = [[CCFrameBufferObject alloc] init];
206+
_framebuffer = [[CCFrameBufferObjectClass alloc] init];
207207
}
208208

209209
return self;

cocos2d/CCRenderTexture.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ -(void)createTextureAndFboWithPixelSize:(CGSize)pixelSize
177177
// Render textures are nearest filtered for legacy reasons.
178178
self.texture.antialiased = NO;
179179

180-
_framebuffer = [[CCFrameBufferObject alloc] initWithTexture:texture depthStencilFormat:_depthStencilFormat];
180+
_framebuffer = [[CCFrameBufferObjectClass alloc] initWithTexture:texture depthStencilFormat:_depthStencilFormat];
181181

182182
// XXX Thayer says: I think this is incorrect for any situations where the content
183183
// size type isn't (points, points). The call to setTextureRect below eventually arrives

cocos2d/CCRendererBasicTypes.m

Lines changed: 3 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -428,128 +428,15 @@ -(instancetype)initWithTexture:(CCTexture *)texture depthStencilFormat:(GLuint)d
428428

429429
_sizeInPixels = texture.contentSizeInPixels;
430430
_contentScale = texture.contentScale;
431-
432-
CCRenderDispatch(NO, ^{
433-
CCGL_DEBUG_PUSH_GROUP_MARKER("CCRenderTexture: Create");
434-
435-
// generate FBO
436-
glGenFramebuffers(1, &_fbo);
437-
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
438-
439-
// associate texture with FBO
440-
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.name, 0);
441-
442-
CGSize sizeInPixels = texture.contentSizeInPixels;
443-
GLuint width = ceil(sizeInPixels.width);
444-
GLuint height = ceil(sizeInPixels.height);
445-
446-
#if __CC_PLATFORM_ANDROID
447-
448-
// Some android devices *only* support combined depth buffers (like all iOS devices), some android devices do not
449-
// support combined depth buffers, thus we have to create a seperate stencil buffer
450-
if(_depthStencilFormat)
451-
{
452-
//create and attach depth buffer
453-
454-
if(![[CCConfiguration sharedConfiguration] supportsPackedDepthStencil])
455-
{
456-
glGenRenderbuffers(1, &depthRenderBuffer);
457-
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer);
458-
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); //GL_DEPTH_COMPONENT24_OES
459-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer);
460-
461-
// if depth format is the one with stencil part, bind same render buffer as stencil attachment
462-
if(_depthStencilFormat == GL_DEPTH24_STENCIL8)
463-
{
464-
glGenRenderbuffers(1, &stencilRenderBuffer);
465-
glBindRenderbuffer(GL_RENDERBUFFER, stencilRenderBuffer);
466-
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, powH);
467-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencilRenderBuffer);
468-
}
469-
}
470-
else
471-
{
472-
glGenRenderbuffers(1, &depthRenderBuffer);
473-
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer);
474-
glRenderbufferStorage(GL_RENDERBUFFER, _depthStencilFormat, width, height);
475-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer);
476-
477-
// if depth format is the one with stencil part, bind same render buffer as stencil attachment
478-
if(_depthStencilFormat == GL_DEPTH24_STENCIL8){
479-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer);
480-
}
481-
}
482-
}
483-
484-
#else
485-
486-
if(depthStencilFormat){
487-
//create and attach depth buffer
488-
glGenRenderbuffers(1, &_depthRenderBuffer);
489-
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
490-
glRenderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, width, height);
491-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
492-
493-
// associate texture with FBO
494-
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.name, 0);
495-
496-
if(depthStencilFormat){
497-
//create and attach depth buffer
498-
glGenRenderbuffers(1, &_depthRenderBuffer);
499-
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
500-
glRenderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, width, height);
501-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
502-
503-
// if depth format is the one with stencil part, bind same render buffer as stencil attachment
504-
if(depthStencilFormat == GL_DEPTH24_STENCIL8){
505-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
506-
}
507-
}
508-
}
509-
510-
#endif
511-
512-
// check if it worked (probably worth doing :) )
513-
NSAssert( glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, @"Could not attach texture to framebuffer");
514-
515-
CCGL_DEBUG_POP_GROUP_MARKER();
516-
CC_CHECK_GL_ERROR_DEBUG();
517-
});
518431
}
519-
return self;
520-
}
521-
522-
-(void)dealloc
523-
{
524-
GLuint fbo = _fbo;
525-
GLuint depthRenderBuffer = _depthRenderBuffer;
526-
GLuint stencilRenderBuffer = _stencilRenderBuffer;
527432

528-
CCRenderDispatch(YES, ^{
529-
glDeleteFramebuffers(1, &fbo);
530-
531-
if(depthRenderBuffer){
532-
glDeleteRenderbuffers(1, &depthRenderBuffer);
533-
}
534-
535-
if(depthRenderBuffer){
536-
glDeleteRenderbuffers(1, &stencilRenderBuffer);
537-
}
538-
});
433+
return self;
539434
}
540435

541436
-(void)bind
542-
{
543-
glViewport(0, 0, _sizeInPixels.width, _sizeInPixels.height);
544-
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
545-
}
437+
{NSAssert(NO, @"Must be overridden.");}
546438

547439
-(void)syncWithView:(CC_VIEW<CCDirectorView> *)view;
548-
{
549-
CCGLView *glView = (CCGLView *)view;
550-
_contentScale = view.contentScaleFactor;
551-
_sizeInPixels = CC_SIZE_SCALE(view.bounds.size, _contentScale);
552-
_fbo = glView->_renderer.defaultFrameBuffer;
553-
}
440+
{NSAssert(NO, @"Must be overridden.");}
554441

555442
@end

cocos2d/CCRendererBasicTypes_Private.h

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,20 +116,13 @@ CCGraphicsBufferPushElements(CCGraphicsBuffer *buffer, size_t requestedCount)
116116
@end
117117

118118

119-
#warning TODO make me abstract!
120119
@interface CCFrameBufferObject : NSObject {
121120
CCTexture *_texture;
122-
123-
CGSize _sizeInPixels;
124-
CGFloat _contentScale;
125-
126-
GLuint _fbo;
127-
GLuint _depthRenderBuffer;
128-
GLuint _stencilRenderBuffer;
129121
}
130122

131-
@property(nonatomic, readonly) CGSize sizeInPixels;
132-
@property(nonatomic, readonly) CGFloat contentScale;
123+
// Setters should be treated as protected.
124+
@property(nonatomic, assign) CGSize sizeInPixels;
125+
@property(nonatomic, assign) CGFloat contentScale;
133126

134127
-(instancetype)initWithTexture:(CCTexture *)texture depthStencilFormat:(GLuint)depthStencilFormat;
135128

0 commit comments

Comments
 (0)