Skip to content

Instantly share code, notes, and snippets.

Created February 20, 2017 16:54
Show Gist options
  • Save anonymous/6ed3f8231e76db35921ef260bfa6bf43 to your computer and use it in GitHub Desktop.
Save anonymous/6ed3f8231e76db35921ef260bfa6bf43 to your computer and use it in GitHub Desktop.
/*
Copyright (C) 2015 Apple Inc. All Rights Reserved.
See LICENSE.txt for this sample’s licensing information
Abstract:
The main rendering code.
*/
#import "ES2Renderer.h"
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>
#import "../vshader.glsl"
#import "../fshader.glsl"
@interface ES2Renderer ()
{
EAGLContext* _context;
// The OpenGL names for the framebuffer and renderbuffer used to render to this view
GLuint _colorRenderBuffer;
GLuint _frameRenderBuffer;
GLuint _program;
GLuint _v_shader;
GLuint _f_shader;
GLint _position_slot;
GLuint _vertex_buffer;
BOOL _stopDrawing;
float _triangleMatrix[6];
}
@end
@implementation ES2Renderer
// Create an ES 2.0 context
- (instancetype)initWithContext:(EAGLContext*)context AndDrawable:(id<EAGLDrawable>)drawable
{
// Determine if GLSL version 140 is supported by this context.
// We'll use this info to generate a GLSL shader source string
// with the proper version preprocessor string prepended
float glLanguageVersion;
#if TARGET_IOS
sscanf((char *)glGetString(GL_SHADING_LANGUAGE_VERSION), "OpenGL ES GLSL ES %f", &glLanguageVersion);
#else
sscanf((char *)glGetString(GL_SHADING_LANGUAGE_VERSION), "%f", &glLanguageVersion);
#endif
// GL_SHADING_LANGUAGE_VERSION returns the version standard version form
// with decimals, but the GLSL version preprocessor directive simply
// uses integers (thus 1.10 should 110 and 1.40 should be 140, etc.)
// We multiply the floating point number by 100 to get a proper
// number for the GLSL preprocessor directive
GLuint version = 100 * glLanguageVersion;
NSLog(@"version %i", (int)version);
// Create default framebuffer object. The backing will be allocated for the
// current layer in -resizeFromLayer
_stopDrawing = false;
_context = context;
glGenRenderbuffers(1, &_colorRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:drawable];
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, _colorRenderBuffer);
_triangleMatrix[0] = -1.0; _triangleMatrix[1] = 0.0;
_triangleMatrix[2] = 0.0; _triangleMatrix[3] = 1.0;
_triangleMatrix[4] = 1.0; _triangleMatrix[5] = 0.0;
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
return nil;
}
[self createVertexShader];
[self createFragmentShader];
[self linkProgram];
glGenBuffers(1, &_vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(_triangleMatrix), _triangleMatrix, GL_STATIC_DRAW);
glClearColor(1, 0.0, 0, 1.0);
return self;
}
- (BOOL)createVertexShader
{
_v_shader = glCreateShader(GL_VERTEX_SHADER);
NSString* shader_text = vshader;
const GLchar* v_shader_text_cstr = [shader_text UTF8String];
glShaderSource(_v_shader, 1, &v_shader_text_cstr, nil);
glCompileShader(_v_shader);
GLint v_shader_compile_status = GL_FALSE;
glGetShaderiv(_v_shader, GL_COMPILE_STATUS, &v_shader_compile_status);
if (v_shader_compile_status == GL_FALSE)
{
GLint v_shader_log_length;
glGetShaderiv(_v_shader, GL_INFO_LOG_LENGTH, &v_shader_log_length);
char* v_shader_log = (char*)malloc(sizeof(char) * v_shader_log_length);
glGetShaderInfoLog(_v_shader, v_shader_log_length, nil, v_shader_log);
NSString* errorMsg = [NSString stringWithUTF8String:v_shader_log];
NSLog(@"Error compiling vertex shader! error: /n");
NSLog(errorMsg);
_stopDrawing = true;
free(v_shader_log);
}
return v_shader_compile_status;
}
- (BOOL)createFragmentShader
{
_f_shader = glCreateShader(GL_FRAGMENT_SHADER);
NSString* f_shader_text = fshader;
const GLchar* f_shader_text_cstr = [f_shader_text UTF8String];
glShaderSource(_f_shader, 1, &f_shader_text_cstr, nil);
glCompileShader(_f_shader);
GLint f_shader_compile_status = GL_FALSE;
glGetShaderiv(_f_shader, GL_COMPILE_STATUS, &f_shader_compile_status);
if (f_shader_compile_status == GL_FALSE)
{
GLint f_shader_log_length;
glGetShaderiv(_f_shader, GL_INFO_LOG_LENGTH, &f_shader_log_length);
char* f_shader_log = (char*)malloc(sizeof(char) * f_shader_log_length);
glGetShaderInfoLog(_f_shader, f_shader_log_length, nil, f_shader_log);
NSString* errorMsg = [NSString stringWithUTF8String:f_shader_log];
NSLog(@"Error compiling fragment shader! error: /n");
NSLog(errorMsg);
_stopDrawing = true;
free(f_shader_log);
}
return f_shader_compile_status;
}
- (BOOL)linkProgram
{
_program = glCreateProgram();
glAttachShader(_program, _v_shader);
glAttachShader(_program, _f_shader);
glLinkProgram(_program);
GLint link_status = GL_FALSE;
glGetProgramiv(_program, GL_LINK_STATUS, &link_status);
if (link_status == GL_FALSE)
{
GLint link_log_length;
glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &link_log_length);
char* link_log = (char*)malloc(sizeof(char) * link_log_length);
glGetProgramInfoLog(_program, link_log_length, nil, link_log);
NSString* errorMsg = [NSString stringWithUTF8String: link_log];
NSLog(@"Error linking program! error: /n");
NSLog(errorMsg);
_stopDrawing = true;
free(link_log);
}
GLint status;
glValidateProgram(_program);
glGetProgramiv(_program, GL_VALIDATE_STATUS, &status);
if (status == 0)
{
NSLog(@"Program cannot run with current OpenGL State");
}
glUseProgram(_program);
_position_slot = glGetAttribLocation(_program, "position");
glEnableVertexAttribArray(_position_slot);
//glEnableVertexAttribArray(0);
return link_status;
}
- (void)checkError
{
GLenum error;
error = glGetError();
NSLog(@"error code %i",error);
switch (error) {
case GL_NO_ERROR:
NSLog(@"[graphHandler]:\t\tError: No error!\n");
break;
case GL_INVALID_ENUM:
NSLog(@"[graphHandler]:\t\tError: GL_INVALID_ENUM\n");
break;
case GL_INVALID_VALUE:
NSLog(@"[graphHandler]:\t\tError: GL_INVALID_VALUE\n");
break;
case GL_INVALID_OPERATION:
NSLog(@"[graphHandler]:\t\tError: GL_INVALID_OPERATION\n");
break;
case GL_OUT_OF_MEMORY:
NSLog(@"[graphHandler]:\t\tError: GL_OUT_OF_MEMORY\n");
break;
}
}
- (void)render
{
// Replace the implementation of this method to do your own custom drawing
[self checkError];
if (!_stopDrawing)
{
glClear(GL_COLOR_BUFFER_BIT);
// 1rst attribute buffer : vertices
//glEnableVertexAttribArray(_position_slot);
glVertexAttribPointer(
_position_slot,
2, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
[_context presentRenderbuffer:GL_RENDERBUFFER];
}
}
- (BOOL)resizeFromLayer:(CAEAGLLayer*)layer
{
// The pixel dimensions of the CAEAGLLayer
GLint backingWidth;
GLint backingHeight;
// Allocate color buffer backing based on the current layer size
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer];
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
//[super resizeWithWidth:backingWidth AndHeight:backingHeight];
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
return NO;
}
return YES;
}
- (void)dealloc
{
// tear down GL
if (_colorRenderBuffer)
{
glDeleteRenderbuffers(1, &_colorRenderBuffer);
_colorRenderBuffer = 0;
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment