Created
April 16, 2011 13:00
-
-
Save narumij/923096 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// EAGLView.h | |
// OpenGLES_iPhone | |
// | |
// Created by mmalc Crawford on 11/18/10. | |
// Copyright 2010 Apple Inc. All rights reserved. | |
// | |
#import <UIKit/UIKit.h> | |
#import <OpenGLES/ES1/gl.h> | |
#import <OpenGLES/ES1/glext.h> | |
#import <OpenGLES/ES2/gl.h> | |
#import <OpenGLES/ES2/glext.h> | |
#define HAS_EAGLVIEW_DEPTH_BUFFER 1 | |
@class EAGLContext; | |
// This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. | |
// The view content is basically an EAGL surface you render your OpenGL scene into. | |
// Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. | |
@interface EAGLView : UIView { | |
@private | |
// The pixel dimensions of the CAEAGLLayer. | |
GLint framebufferWidth; | |
GLint framebufferHeight; | |
// The OpenGL ES names for the framebuffer and renderbuffer used to render to this view. | |
GLuint defaultFramebuffer, colorRenderbuffer; | |
#if HAS_EAGLVIEW_DEPTH_BUFFER | |
GLuint depthRenderbuffer; | |
#endif | |
} | |
@property (nonatomic, retain) EAGLContext *context; | |
- (void)setFramebuffer; | |
- (BOOL)presentFramebuffer; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// EAGLView.m | |
// OpenGLES_iPhone | |
// | |
// Created by mmalc Crawford on 11/18/10. | |
// Copyright 2010 Apple Inc. All rights reserved. | |
// | |
#import <QuartzCore/QuartzCore.h> | |
#import "EAGLView.h" | |
@interface EAGLView (PrivateMethods) | |
- (void)createFramebuffer; | |
- (void)deleteFramebuffer; | |
@end | |
@implementation EAGLView | |
@synthesize context; | |
// You must implement this method | |
+ (Class)layerClass | |
{ | |
return [CAEAGLLayer class]; | |
} | |
//The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:. | |
- (id)initWithCoder:(NSCoder*)coder | |
{ | |
self = [super initWithCoder:coder]; | |
if (self) { | |
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; | |
eaglLayer.opaque = TRUE; | |
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: | |
[NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, | |
kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, | |
nil]; | |
} | |
return self; | |
} | |
- (void)dealloc | |
{ | |
[self deleteFramebuffer]; | |
[context release]; | |
[super dealloc]; | |
} | |
- (void)setContext:(EAGLContext *)newContext | |
{ | |
if (context != newContext) { | |
[self deleteFramebuffer]; | |
[context release]; | |
context = [newContext retain]; | |
[EAGLContext setCurrentContext:nil]; | |
} | |
} | |
- (void)createFramebuffer | |
{ | |
if (context && !defaultFramebuffer) { | |
[EAGLContext setCurrentContext:context]; | |
// Create default framebuffer object. | |
glGenFramebuffers(1, &defaultFramebuffer); | |
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); | |
// Create color render buffer and allocate backing store. | |
glGenRenderbuffers(1, &colorRenderbuffer); | |
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); | |
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; | |
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth); | |
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight); | |
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); | |
#if HAS_EAGLVIEW_DEPTH_BUFFER | |
glGenRenderbuffers(1, &depthRenderbuffer); | |
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); | |
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); | |
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, framebufferWidth, framebufferHeight); | |
#endif | |
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) | |
NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); | |
} | |
} | |
- (void)deleteFramebuffer | |
{ | |
if (context) { | |
[EAGLContext setCurrentContext:context]; | |
if (defaultFramebuffer) { | |
glDeleteFramebuffers(1, &defaultFramebuffer); | |
defaultFramebuffer = 0; | |
} | |
if (colorRenderbuffer) { | |
glDeleteRenderbuffers(1, &colorRenderbuffer); | |
colorRenderbuffer = 0; | |
} | |
#if HAS_EAGLVIEW_DEPTH_BUFFER | |
if (depthRenderbuffer) | |
{ | |
glDeleteRenderbuffers(1, &depthRenderbuffer); | |
depthRenderbuffer = 0; | |
} | |
#endif | |
} | |
} | |
- (void)setFramebuffer | |
{ | |
if (context) { | |
[EAGLContext setCurrentContext:context]; | |
if (!defaultFramebuffer) | |
[self createFramebuffer]; | |
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); | |
glViewport(0, 0, framebufferWidth, framebufferHeight); | |
} | |
} | |
- (BOOL)presentFramebuffer | |
{ | |
BOOL success = FALSE; | |
if (context) { | |
[EAGLContext setCurrentContext:context]; | |
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); | |
success = [context presentRenderbuffer:GL_RENDERBUFFER]; | |
} | |
return success; | |
} | |
- (void)layoutSubviews | |
{ | |
// The framebuffer will be re-created at the beginning of the next setFramebuffer method call. | |
[self deleteFramebuffer]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment