Created
May 5, 2012 21:31
-
-
Save marknorgren/2605701 to your computer and use it in GitHub Desktop.
SEIS 750 Final Project - OutForADrive - iOS
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
// | |
// OpenGLView.m | |
// HelloOpenGL | |
// | |
// Created by Ray Wenderlich on 5/24/11. | |
// Copyright 2011 __MyCompanyName__. All rights reserved. | |
// | |
#import "OpenGLView.h" | |
#import "CC3GLMatrix.h" | |
#import "glUtil.h" | |
#define glBindVertexArray glBindVertexArrayOES | |
#define glGenVertexArrays glGenVertexArraysOES | |
#define glDeleteVertexArrays glDeleteVertexArraysOES | |
#define GetGLError() \ | |
{ \ | |
GLenum err = glGetError(); \ | |
while (err != GL_NO_ERROR) { \ | |
NSLog(@"GLError %s set in File:%s Line:%d\n", \ | |
GetGLErrorString(err), \ | |
__FILE__, \ | |
__LINE__); \ | |
err = glGetError(); \ | |
} \ | |
} | |
@implementation OpenGLView | |
enum VAO_OBJECTS | |
{ | |
CUBE, | |
CUBE2, | |
CAR, | |
HEADLIGHT, | |
POLICE_LIGHT, | |
POLICE_LIGHT2, | |
WHEEL, | |
TIRETREAD, | |
HUBCAP, | |
HEAD, | |
EYE, | |
STAGE, | |
NUMBER_OF_VAO_OBJECTS | |
}; | |
enum VBO_OBJECTS | |
{ | |
CUBE_VERTS, | |
CUBE_COLORS, //NOTE: THIS ORDER HAS TO STAY THE SAME FOR NOW VERTS - COLORS | |
CUBE_NORMALS, | |
CUBE_MATERIAL_AMBIENT, | |
CUBE_MATERIAL_DIFFUSE, | |
CUBE_SPECULAR, | |
CUBE_SHININESS, | |
CAR_VERTS, | |
CAR_COLORS, | |
CAR_NORMALS, | |
CAR_MATERIAL_AMBIENT, | |
CAR_MATERIAL_DIFFUSE, | |
CAR_SPECULAR, | |
CAR_SHININESS, | |
HEADLIGHT_VERTS, | |
HEADLIGHT_COLORS, | |
HEADLIGHT_NORMALS, | |
POLICE_LIGHT_VERTS, | |
POLICE_LIGHT_COLORS, | |
POLICE_LIGHT_NORMALS, | |
POLICE_LIGHT_VERTS2, | |
POLICE_LIGHT_COLORS2, | |
POLICE_LIGHT_NORMALS2, | |
WHEEL_VERTS, | |
WHEEL_COLORS, | |
WHEEL_NORMALS, | |
TIRETREAD_VERTS, | |
TIRETREAD_COLORS, | |
TIRETREAD_NORMALS, | |
HUBCAP_VERTS, | |
HUBCAP_COLORS, | |
HUBCAP_NORMALS, | |
HEAD_VERTS, | |
HEAD_COLORS, | |
HEAD_NORMALS, | |
EYE_VERTS, | |
EYE_COLORS, | |
EYE_NORMALS, | |
STAGE_VERTS, | |
STAGE_COLORS, | |
STAGE_NORMALS, | |
STAGE_MATERIAL_AMBIENT, | |
STAGE_MATERIAL_DIFFUSE, | |
STAGE_SPECULAR, | |
STAGE_SHININESS, | |
NUMBER_OF_VBO_OBJECTS | |
}; | |
// LIGHTING | |
#define SHADER_ATTRIBS_PER_OBJECT 3 | |
//shader program | |
GLuint programHandle; | |
GLuint model_view; | |
GLuint projection; | |
GLuint NormalMatrix; | |
GLuint vPosition; | |
GLuint vColor; | |
GLuint vAmbientDiffuseColor; | |
GLuint vSpecularColor; | |
GLuint vSpecularExponent; | |
GLuint vNormal; | |
GLuint vAmbient; | |
GLuint vDiffuse; | |
GLuint vSpecular; | |
GLuint ambient_light; | |
GLuint scene_light_color; | |
//need some arrays to store cube attributes | |
GLuint vao[NUMBER_OF_VAO_OBJECTS]; | |
GLuint vbo[NUMBER_OF_VBO_OBJECTS]; | |
/** CUBE OBJECT **/ | |
CC3Vector4 cubeVerts[36]; | |
CC3Vector4 cubeColors[36]; | |
CC3Vector cubeNormals[36]; | |
- (void) generateCube { | |
GetGLError(); | |
for(int i=0; i<6; i++){ | |
cubeColors[i] = CC3Vector4Make(0.0, 1.0, 1.0, 1.0); //front | |
cubeNormals[i] = CC3VectorMake(0.0,0.0,1.0); | |
} | |
GetGLError(); | |
cubeVerts[0] = CC3Vector4Make(1.0f, -1.0f, 1.0f, 1.0); | |
cubeVerts[1] = CC3Vector4Make(1.0f, 1.0f, 1.0f, 1.0); | |
cubeVerts[2] = CC3Vector4Make(-1.0f, 1.0f, 1.0f, 1.0); | |
cubeVerts[3] = CC3Vector4Make(-1.0f, 1.0f, 1.0f, 1.0); | |
cubeVerts[4] = CC3Vector4Make(-1.0f, -1.0f, 1.0f, 1.0); | |
cubeVerts[5] = CC3Vector4Make(1.0f, -1.0f, 1.0f, 1.0); | |
GetGLError(); | |
for(int i=6; i<12; i++){ | |
cubeColors[i] = CC3Vector4Make(1.0, 0.0, 1.0, 1.0); //back | |
cubeNormals[i] = CC3VectorMake(0.0,0.0,-1.0); | |
} | |
GetGLError(); | |
cubeVerts[6] = CC3Vector4Make(-1.0f, -1.0f, -1.0f, 1.0); | |
cubeVerts[7] = CC3Vector4Make(-1.0f, 1.0f, -1.0f, 1.0); | |
cubeVerts[8] = CC3Vector4Make(1.0f, 1.0f, -1.0f, 1.0); | |
cubeVerts[9] = CC3Vector4Make(1.0f, 1.0f, -1.0f, 1.0); | |
cubeVerts[10] = CC3Vector4Make(1.0f, -1.0f, -1.0f, 1.0); | |
cubeVerts[11] = CC3Vector4Make(-1.0f, -1.0f, -1.0f, 1.0); | |
for(int i=12; i<18; i++){ | |
cubeColors[i] = CC3Vector4Make(1.0, 1.0, 0.0, 1.0); //left | |
cubeNormals[i] = CC3VectorMake(1.0,0.0,0.0); | |
} | |
cubeVerts[12] = CC3Vector4Make(1.0f, 1.0f, 1.0f, 1.0); | |
cubeVerts[13] = CC3Vector4Make(1.0f, -1.0f, 1.0f, 1.0); | |
cubeVerts[14] = CC3Vector4Make(1.0f, -1.0f, -1.0f, 1.0); | |
cubeVerts[15] = CC3Vector4Make(1.0f, -1.0f, -1.0f, 1.0); | |
cubeVerts[16] = CC3Vector4Make(1.0f, 1.0f, -1.0f, 1.0); | |
cubeVerts[17] = CC3Vector4Make(1.0f, 1.0f, 1.0f, 1.0); | |
for(int i=18; i<24; i++){ | |
cubeColors[i] = CC3Vector4Make(1.0, 0.0, 0.0, 1.0); //right | |
cubeNormals[i] = CC3VectorMake(-1.0,0.0,0.0); | |
} | |
cubeVerts[18] = CC3Vector4Make(-1.0f, 1.0f, -1.0f, 1.0); | |
cubeVerts[19] = CC3Vector4Make(-1.0f, -1.0f, -1.0f, 1.0); | |
cubeVerts[20] = CC3Vector4Make(-1.0f, -1.0f, 1.0f, 1.0); | |
cubeVerts[21] = CC3Vector4Make(-1.0f, -1.0f, 1.0f, 1.0); | |
cubeVerts[22] = CC3Vector4Make(-1.0f, 1.0f, 1.0f, 1.0); | |
cubeVerts[23] = CC3Vector4Make(-1.0f, 1.0f, -1.0f, 1.0); | |
for(int i=24; i<30; i++){ | |
cubeColors[i] = CC3Vector4Make(0.0, 0.0, 1.0, 1.0); //top | |
cubeNormals[i] = CC3VectorMake(0.0,1.0,0.0); | |
} | |
cubeVerts[24] = CC3Vector4Make(1.0f, 1.0f, 1.0f, 1.0); | |
cubeVerts[25] = CC3Vector4Make(1.0f, 1.0f, -1.0f, 1.0); | |
cubeVerts[26] = CC3Vector4Make(-1.0f, 1.0f, -1.0f, 1.0); | |
cubeVerts[27] = CC3Vector4Make(-1.0f, 1.0f, -1.0f, 1.0); | |
cubeVerts[28] = CC3Vector4Make(-1.0f, 1.0f, 1.0f, 1.0); | |
cubeVerts[29] = CC3Vector4Make(1.0f, 1.0f, 1.0f, 1.0); | |
for(int i=30; i<36; i++){ | |
cubeColors[i] = CC3Vector4Make(0.0, 1.0, 0.0, 1.0); //bottom | |
cubeNormals[i] =CC3VectorMake(0.0,-1.0,0.0); | |
} | |
cubeVerts[30] = CC3Vector4Make(1.0f, -1.0f, -1.0f, 1.0); | |
cubeVerts[31] = CC3Vector4Make(1.0f, -1.0f, 1.0f, 1.0); | |
cubeVerts[32] = CC3Vector4Make(-1.0f, -1.0f, 1.0f, 1.0); | |
cubeVerts[33] = CC3Vector4Make(-1.0f, -1.0f, 1.0f, 1.0); | |
cubeVerts[34] = CC3Vector4Make(-1.0f, -1.0f, -1.0f, 1.0); | |
cubeVerts[35] = CC3Vector4Make(1.0f, -1.0f, -1.0f, 1.0); | |
} | |
+ (Class)layerClass { | |
return [CAEAGLLayer class]; | |
} | |
- (void)setupLayer { | |
_eaglLayer = (CAEAGLLayer*) self.layer; | |
_eaglLayer.opaque = YES; | |
} | |
- (void)setupContext { | |
EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES2; | |
_context = [[EAGLContext alloc] initWithAPI:api]; | |
if (!_context) { | |
NSLog(@"Failed to initialize OpenGLES 2.0 context"); | |
exit(1); | |
} | |
if (![EAGLContext setCurrentContext:_context]) { | |
NSLog(@"Failed to set current OpenGL context"); | |
exit(1); | |
} | |
} | |
- (void)setupRenderBuffer { | |
glGenRenderbuffers(1, &_colorRenderBuffer); | |
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer); | |
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer]; | |
} | |
- (void)setupDepthBuffer { | |
glGenRenderbuffers(1, &_depthRenderBuffer); | |
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer); | |
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, self.frame.size.width, self.frame.size.height); | |
} | |
- (void)setupFrameBuffer { | |
GLuint framebuffer; | |
glGenFramebuffers(1, &framebuffer); | |
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); | |
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer); | |
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer); | |
} | |
- (GLuint)compileShader:(NSString*)shaderName withType:(GLenum)shaderType { | |
// 1 | |
NSString* shaderPath = [[NSBundle mainBundle] pathForResource:shaderName ofType:@"glsl"]; | |
NSError* error; | |
NSString* shaderString = [NSString stringWithContentsOfFile:shaderPath encoding:NSUTF8StringEncoding error:&error]; | |
if (!shaderString) { | |
NSLog(@"Error loading shader: %@", error.localizedDescription); | |
exit(1); | |
} | |
// 2 | |
GLuint shaderHandle = glCreateShader(shaderType); | |
// 3 | |
const char * shaderStringUTF8 = [shaderString UTF8String]; | |
int shaderStringLength = [shaderString length]; | |
glShaderSource(shaderHandle, 1, &shaderStringUTF8, &shaderStringLength); | |
// 4 | |
glCompileShader(shaderHandle); | |
// 5 | |
GLint compileSuccess; | |
glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess); | |
if (compileSuccess == GL_FALSE) { | |
GLchar messages[256]; | |
glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]); | |
NSString *messageString = [NSString stringWithUTF8String:messages]; | |
NSLog(@"%@", messageString); | |
exit(1); | |
} | |
return shaderHandle; | |
} | |
- (void)compileShaders { | |
NSLog(@"comileShaders"); | |
GetGLError(); | |
// 1 | |
GLuint vertexShader = [self compileShader:@"SimpleVertex" withType:GL_VERTEX_SHADER]; | |
GLuint fragmentShader = [self compileShader:@"SimpleFragment" withType:GL_FRAGMENT_SHADER]; | |
GetGLError(); | |
// 2 | |
programHandle = glCreateProgram(); | |
glAttachShader(programHandle, vertexShader); | |
glAttachShader(programHandle, fragmentShader); | |
glLinkProgram(programHandle); | |
GetGLError(); | |
// 3 | |
GLint linkSuccess; | |
glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess); | |
if (linkSuccess == GL_FALSE) { | |
GLchar messages[256]; | |
glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]); | |
NSString *messageString = [NSString stringWithUTF8String:messages]; | |
NSLog(@"%@", messageString); | |
exit(1); | |
} | |
glUseProgram(programHandle); | |
} | |
- (void)setupVBOs { | |
NSLog(@"sizeOf cubeVerts: %lu", sizeof(cubeVerts)); | |
// Create a vertex array object | |
glGenVertexArrays( 1, &vao[0] ); | |
glBindVertexArray( vao[CUBE] ); | |
// CUBE | |
// Create and initialize any buffer objects | |
GetGLError(); | |
glGenBuffers( 3, &vbo[CUBE_VERTS] ); | |
glBindBuffer( GL_ARRAY_BUFFER, vbo[CUBE_VERTS] ); | |
glBufferData( GL_ARRAY_BUFFER, sizeof(cubeVerts), cubeVerts, GL_STATIC_DRAW); | |
_positionSlot = glGetAttribLocation(programHandle, "Position"); | |
glEnableVertexAttribArray(_positionSlot); | |
glVertexAttribPointer(_positionSlot, 4, GL_FLOAT, GL_FALSE, 0, 0); | |
GetGLError(); | |
//and now our colors for each vertex | |
glBindBuffer( GL_ARRAY_BUFFER, vbo[CUBE_COLORS] ); | |
glBufferData( GL_ARRAY_BUFFER, sizeof(cubeColors), cubeColors, GL_STATIC_DRAW ); | |
_colorSlot = glGetAttribLocation(programHandle, "SourceColor"); | |
GetGLError(); | |
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, 0, 0); | |
GetGLError(); | |
glEnableVertexAttribArray(_colorSlot); | |
GetGLError(); | |
//vertex normals | |
glBindBuffer( GL_ARRAY_BUFFER, vbo[CUBE_NORMALS] ); | |
glBufferData( GL_ARRAY_BUFFER, sizeof(cubeNormals), cubeNormals, GL_STATIC_DRAW ); | |
GetGLError(); | |
} | |
- (void)render:(CADisplayLink*)displayLink { | |
glClearColor(1, 1, 1, 1.0); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glEnable(GL_DEPTH_TEST); | |
GetGLError(); | |
CC3GLMatrix *projection = [CC3GLMatrix matrix]; | |
[projection populateFromFrustumLeft:-5 andRight:5 andBottom:-5 andTop:5 andNear:1 andFar:50]; | |
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix); | |
GetGLError(); | |
CC3GLMatrix *modelView = [CC3GLMatrix matrix]; | |
[modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)]; | |
_currentRotation += displayLink.duration * 90; | |
[modelView rotateBy:CC3VectorMake(_currentRotation, _currentRotation, 0)]; | |
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix); | |
GetGLError(); | |
GetGLError(); | |
glBindVertexArray( vao[CUBE] ); | |
glDrawArrays( GL_TRIANGLES, 0, 36 ); // draw the cube | |
GetGLError(); | |
[_context presentRenderbuffer:GL_RENDERBUFFER]; | |
GetGLError(); | |
} | |
- (void)setupDisplayLink { | |
CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render:)]; | |
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; | |
} | |
- (void) setupShader | |
{ | |
glUseProgram(programHandle); | |
_projectionUniform = glGetUniformLocation(programHandle, "Projection"); | |
_modelViewUniform = glGetUniformLocation(programHandle, "Modelview"); | |
glBindVertexArray( vao[CUBE] ); | |
GetGLError(); | |
glBindBuffer( GL_ARRAY_BUFFER, vbo[CUBE_VERTS] ); | |
_positionSlot = glGetAttribLocation(programHandle, "Position"); | |
glEnableVertexAttribArray(_positionSlot); | |
glVertexAttribPointer(_positionSlot, 4, GL_FLOAT, GL_FALSE, 0, 0); | |
NSLog(@"max: %d", GL_MAX_VERTEX_ATTRIBS); | |
GetGLError(); | |
glBindBuffer( GL_ARRAY_BUFFER, vbo[CUBE_COLORS] ); | |
_colorSlot = glGetAttribLocation(programHandle, "SourceColor"); | |
GetGLError(); | |
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, 0, 0); | |
GetGLError(); | |
glEnableVertexAttribArray(_colorSlot); | |
GetGLError(); | |
NSLog(@"\nLocations of the shader variables:\n Position:%i\n Color:%i\n", _positionSlot, _colorSlot); //Prints out the values of 1, 0, 0 | |
} | |
- (void) initOpenGL | |
{ | |
[self generateCube]; | |
NSLog(@"generateCube complete"); | |
// init shader | |
[self compileShaders]; | |
NSLog(@"compileShaders complete"); | |
GetGLError(); | |
/* | |
// create and initialize several buffer objects | |
glGenVertexArrays( NUMBER_OF_VAO_OBJECTS, &vao[0] ); | |
glBindVertexArray( vao[CUBE] ); | |
GetGLError(); | |
glGenBuffers( 3, &vbo[CUBE_VERTS] ); | |
glBindBuffer( GL_ARRAY_BUFFER, vbo[CUBE_VERTS] ); | |
glBufferData( GL_ARRAY_BUFFER, sizeof(cubeVerts), cubeVerts, GL_STATIC_DRAW); | |
GetGLError(); | |
//and now our colors for each vertex | |
glBindBuffer( GL_ARRAY_BUFFER, vbo[CUBE_COLORS] ); | |
glBufferData( GL_ARRAY_BUFFER, sizeof(cubeColors), cubeColors, GL_STATIC_DRAW ); | |
GetGLError(); | |
//vertex normals | |
glBindBuffer( GL_ARRAY_BUFFER, vbo[CUBE_NORMALS] ); | |
glBufferData( GL_ARRAY_BUFFER, sizeof(cubeNormals), cubeNormals, GL_STATIC_DRAW ); | |
*/ | |
GetGLError(); | |
} | |
/* main starting point */ | |
- (id)initWithFrame:(CGRect)frame | |
{ | |
self = [super initWithFrame:frame]; | |
if (self) { | |
[self setupLayer]; | |
[self setupContext]; | |
[self setupDepthBuffer]; | |
[self setupRenderBuffer]; | |
[self setupFrameBuffer]; | |
//comiles shaders | |
[self initOpenGL]; | |
GetGLError(); | |
[self setupVBOs]; | |
NSLog(@"setupVBOs complete"); | |
//setup shader | |
[self setupShader]; | |
GetGLError(); | |
[self setupDisplayLink]; | |
NSLog(@"setupDisplayLink complete"); | |
GetGLError(); | |
} | |
return self; | |
} | |
- (void)dealloc | |
{ | |
[_context release]; | |
_context = nil; | |
[super dealloc]; | |
} | |
@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
varying lowp vec4 DestinationColor; // 1 | |
void main(void) { // 2 | |
gl_FragColor = DestinationColor; // 3 | |
} |
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
attribute vec4 Position; // 1 | |
attribute vec4 SourceColor; // 2 | |
varying vec4 DestinationColor; // 3 | |
uniform mat4 Projection; | |
uniform mat4 Modelview; | |
void main(void) { // 4 | |
DestinationColor = SourceColor; // 5 | |
gl_Position = Projection * Modelview * Position; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment