Skip to content

Instantly share code, notes, and snippets.

@5sw
Last active February 16, 2018 03:35
Show Gist options
  • Save 5sw/0ee9d4f869dc99d0ad84 to your computer and use it in GitHub Desktop.
Save 5sw/0ee9d4f869dc99d0ad84 to your computer and use it in GitHub Desktop.
UIView subclass that renders a SceneKit scene using SCNRenderer
#import <UIKit/UIKit.h>
#import <SceneKit/SceneKit.h>
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>
@interface View : UIView
@property (strong, nonatomic) SCNScene *scene;
- (void)renderFrame;
@end
@implementation View {
EAGLContext *context;
GLuint framebuffer;
GLuint colorRenderbuffer;
GLint width;
GLint height;
SCNRenderer *renderer;
}
+ (Class)layerClass
{
return [CAEAGLLayer class];
}
- (BOOL)initializeOpenGL
{
context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext: context];
CAEAGLLayer *layer = (id)self.layer;
layer.contentsScale = [UIScreen mainScreen].scale;
layer.opaque = YES;
glGenFramebuffers( 1, &framebuffer );
glBindFramebuffer( GL_FRAMEBUFFER, framebuffer );
glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
if (![context renderbufferStorage:GL_RENDERBUFFER fromDrawable: layer]) return NO;
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);
GLuint depthRenderbuffer;
glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
}
- (void)prepareToRender
{
[self initializeOpenGL];
renderer = [SCNRenderer rendererWithContext: (__bridge void *)context options: nil];
renderer.scene = self.scene;
}
- (void)renderFrame
{
if (!context) {
[self prepareToRender];
}
[EAGLContext setCurrentContext: context];
glBindFramebuffer( GL_FRAMEBUFFER, framebuffer );
glBindRenderbuffer( GL_RENDERBUFFER, colorRenderbuffer );
glViewport(0, 0, width, height );
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
[renderer render];
const GLenum discards[] = {GL_DEPTH_ATTACHMENT};
glDiscardFramebufferEXT(GL_FRAMEBUFFER,1,discards);
[context presentRenderbuffer:GL_RENDERBUFFER];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment