Skip to content

Instantly share code, notes, and snippets.

@narumij
Created April 16, 2011 13:00
Show Gist options
  • Save narumij/923096 to your computer and use it in GitHub Desktop.
Save narumij/923096 to your computer and use it in GitHub Desktop.
//
// 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
//
// 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