Skip to content

Instantly share code, notes, and snippets.

@marknorgren
Created May 5, 2012 21:31
Show Gist options
  • Save marknorgren/2605701 to your computer and use it in GitHub Desktop.
Save marknorgren/2605701 to your computer and use it in GitHub Desktop.
SEIS 750 Final Project - OutForADrive - iOS
//
// 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
varying lowp vec4 DestinationColor; // 1
void main(void) { // 2
gl_FragColor = DestinationColor; // 3
}
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