Created
February 20, 2017 16:54
-
-
Save anonymous/6ed3f8231e76db35921ef260bfa6bf43 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
/* | |
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