Created
April 29, 2012 22:26
-
-
Save marknorgren/2553555 to your computer and use it in GitHub Desktop.
openGL ES 2.0 VAO VBO setup
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
GLError GL_INVALID_VALUE set in MRKOpenGLView.m Line:374 | |
GLError GL_INVALID_VALUE set in MRKOpenGLView.m Line:202 | |
GLError GL_INVALID_VALUE set in MRKOpenGLView.m Line:205 |
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
// | |
// MRKOpenGLView.m | |
// openGL_Example | |
// | |
// Created by Mark Norgren on 4/17/12. | |
// Copyright (c) 2012 Marked Systems. All rights reserved. | |
// | |
#import "MRKOpenGLView.h" | |
#import "CC3GLMatrix.h" | |
#import "sourceUtil.h" | |
#import "glUtil.h" | |
#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 MRKOpenGLView | |
@synthesize camera; | |
//#define glBindVertexArray glBindVertexArrayOES | |
//#define glGenVertexArrays glGenVertexArraysOES | |
//#define glDeleteVertexArrays glDeleteVertexArraysOES | |
/** CAR OBJECT **/ | |
#define CAR_WIDTH 2.0f | |
#define CAR_HEIGHT 2.0f | |
#define CAR_LENGTH 5.0f | |
#define STAGE_WIDTH 100.0f | |
#define STAGE_DEPTH 100.0f | |
enum VAO_OBJECTS | |
{ | |
CUBE, | |
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 7 | |
GLuint programHandle; | |
GLuint vPosition; | |
GLuint vColor; | |
GLuint vNormal; | |
GLuint vao[NUMBER_OF_VBO_OBJECTS]; | |
GLuint vbo[NUMBER_OF_VBO_OBJECTS]; | |
typedef struct { | |
float Position[3]; | |
float Color[4]; | |
} Vertex; | |
const Vertex Vertices[] = { | |
//vertex //color | |
{{2, -.1, -7}, {.5, .5, .5, 1}}, | |
{{2, -.1, 7}, {.5, .5, .5, 1}}, | |
{{-2, -.1, 7}, {.5, .5, .5, 1}}, | |
{{-2, -.1, -7}, {.5, .5, .5, 1}} | |
}; | |
const GLubyte Indices[] = { | |
0, 1, 2, | |
2, 3, 0 | |
}; | |
//need some arrays to store cube attributes | |
GLuint vao[NUMBER_OF_VBO_OBJECTS]; | |
GLuint vbo[NUMBER_OF_VBO_OBJECTS]; | |
CC3Vector4 stageVerts[6]; | |
CC3Vector4 stageColors[6]; | |
CC3Vector stageNormals[6]; | |
void generateStage() { | |
for(int i=0; i<6; i++){ | |
stageColors[i] = CC3Vector4Make(0.5, 0.5, 0.5, 1.0); //front | |
stageNormals[i] = CC3VectorMake(0.0,1.0,0.0); | |
} | |
stageVerts[0] = CC3Vector4Make(-(STAGE_WIDTH/2.0f), 0.0f, -(STAGE_DEPTH/2.0f), 1.0); | |
stageVerts[1] = CC3Vector4Make(-(STAGE_WIDTH/2.0f), 0.0f, (STAGE_DEPTH/2.0f), 1.0); | |
stageVerts[2] = CC3Vector4Make((STAGE_WIDTH/2.0f), 0.0f, (STAGE_DEPTH/2.0f), 1.0); | |
stageVerts[3] = CC3Vector4Make((STAGE_WIDTH/2.0f), 0.0f, (STAGE_DEPTH/2.0f), 1.0); | |
stageVerts[4] = CC3Vector4Make((STAGE_WIDTH/2.0f), 0.0f, -(STAGE_DEPTH/2.0f), 1.0); | |
stageVerts[5] = CC3Vector4Make(-(STAGE_WIDTH/2.0f), 0.0f, -(STAGE_DEPTH/2.0f), 1.0); | |
} | |
- (void)initGL { | |
glGenVertexArrays(NUMBER_OF_VAO_OBJECTS,vao); | |
GetGLError(); | |
generateStage(); | |
GetGLError(); | |
/********************************************************* | |
* STAGE | |
* | |
*********************************************************/ | |
// Create a vertex array object | |
glBindVertexArrayOES( vao[STAGE] ); | |
glGenBuffers( SHADER_ATTRIBS_PER_OBJECT, &vbo[STAGE_VERTS] ); | |
glBindBuffer( GL_ARRAY_BUFFER, vbo[STAGE_VERTS] ); | |
glBufferData( GL_ARRAY_BUFFER, sizeof(stageVerts), stageVerts, GL_STATIC_DRAW); | |
vPosition = glGetAttribLocation(programHandle, "vPosition"); | |
glEnableVertexAttribArray(vPosition); | |
glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, 0); | |
GetGLError(); | |
//and now our colors for each vertex | |
glBindBuffer( GL_ARRAY_BUFFER, vbo[STAGE_COLORS] ); | |
glBufferData( GL_ARRAY_BUFFER, sizeof(stageColors), stageColors, GL_STATIC_DRAW ); | |
vColor = glGetAttribLocation(programHandle, "vColor"); | |
glEnableVertexAttribArray(vColor); | |
glVertexAttribPointer(vColor, 4, GL_FLOAT, GL_FALSE, 0, 0); | |
GetGLError(); | |
//normals for each vertex | |
glBindBuffer( GL_ARRAY_BUFFER, vbo[STAGE_NORMALS] ); | |
GetGLError(); | |
glBufferData( GL_ARRAY_BUFFER, sizeof(stageNormals), stageNormals, GL_STATIC_DRAW ); | |
GetGLError(); | |
vNormal = glGetAttribLocation(programHandle, "vNormal"); | |
GetGLError(); | |
glEnableVertexAttribArray(vNormal); | |
GetGLError(); | |
glVertexAttribPointer(vNormal, 3, GL_FLOAT, GL_FALSE, 0, 0); | |
GetGLError(); | |
} | |
+ (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)setupFrameBuffer { | |
GLuint framebuffer; | |
glGenFramebuffers(1, &framebuffer); | |
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); | |
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
GL_RENDERBUFFER, _colorRenderBuffer); | |
} | |
/* NOT CURRENTLY USING THIS */ | |
- (void) configureVertexArrayObject | |
{ | |
// Create and bind the vertex array object. | |
glGenVertexArrays(NUMBER_OF_VAO_OBJECTS,&vao[STAGE]); | |
//glBindVertexArray(vao[STAGE]); | |
// Configure the attributes in the VAO. | |
glBindBuffer(GL_ARRAY_BUFFER, vbo[STAGE_VERTS]); | |
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); | |
glEnableVertexAttribArray(_positionSlot); | |
glBindBuffer(GL_ARRAY_BUFFER, vbo[STAGE_COLORS]); | |
glVertexAttribPointer(_colorSlot, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), 0); | |
glEnableVertexAttribArray(_colorSlot); | |
// Bind back to the default state. | |
glBindBuffer(GL_ARRAY_BUFFER,0); | |
glBindVertexArrayOES(0); | |
} | |
- (void)render { | |
glClearColor(0, 0, 0, 1.0); | |
glClear(GL_COLOR_BUFFER_BIT); | |
CC3GLMatrix *projection = [CC3GLMatrix matrix]; | |
float h = 100.0f * self.frame.size.height / self.frame.size.width; | |
// 100 gives 58.593750 for height | |
NSLog(@"height: %f", h); | |
/* From CC3 library - | |
* populateFromFrustumLeft - Populates this matrix as a perspective projection matrix with the specified frustum dimensions. | |
*/ | |
[projection populateFromFrustumLeft:-50 andRight:50 andBottom:-h/2 andTop:h/2 andNear:2 andFar:50]; | |
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix); | |
glViewport(0, 0, self.frame.size.width, self.frame.size.height); | |
glBindVertexArray(vao[STAGE]); | |
glDrawArrays(GL_TRIANGLES, 0, 6); | |
[_context presentRenderbuffer:GL_RENDERBUFFER]; | |
} | |
- (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 { | |
// 1 | |
GLuint vertexShader = [self compileShader:@"SimpleVertex" | |
withType:GL_VERTEX_SHADER]; | |
GLuint fragmentShader = [self compileShader:@"SimpleFragment" | |
withType:GL_FRAGMENT_SHADER]; | |
// 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); | |
} | |
GetGLError(); | |
// 4 | |
glUseProgram(programHandle); | |
GetGLError(); | |
// 5 | |
//_positionSlot = glGetAttribLocation(programHandle, "Position"); | |
//_colorSlot = glGetAttribLocation(programHandle, "SourceColor"); | |
vPosition = glGetAttribLocation(programHandle, "vPosition"); | |
vColor = glGetAttribLocation(programHandle, "vColor"); | |
vNormal = glGetAttribLocation(programHandle, "vNormal"); | |
GetGLError(); | |
//glEnableVertexAttribArray(_positionSlot); | |
GetGLError(); | |
//glEnableVertexAttribArray(_colorSlot); | |
GetGLError(); | |
glEnableVertexAttribArray(vPosition); | |
GetGLError(); | |
glEnableVertexAttribArray(vColor); | |
GetGLError(); | |
glEnableVertexAttribArray(vNormal); | |
GetGLError(); | |
_projectionUniform = glGetUniformLocation(programHandle, "Projection"); | |
GetGLError(); | |
} | |
- (id)initWithFrame:(CGRect)frame | |
{ | |
self = [super initWithFrame:frame]; | |
if (self) { | |
[self setupLayer]; | |
GetGLError(); | |
[self setupContext]; | |
GetGLError(); | |
[self setupRenderBuffer]; | |
GetGLError(); | |
[self setupFrameBuffer]; | |
GetGLError(); | |
[self compileShaders]; | |
GetGLError(); | |
// maps to our init function | |
[self initGL]; | |
GetGLError(); | |
// maps to our display function | |
[self render]; | |
GetGLError(); | |
} | |
return self; | |
} | |
/* | |
// Only override drawRect: if you perform custom drawing. | |
// An empty implementation adversely affects performance during animation. | |
- (void)drawRect:(CGRect)rect | |
{ | |
// Drawing code | |
} | |
*/ | |
@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 vPosition; | |
attribute vec4 vColor; | |
attribute vec4 vNormal; | |
varying vec4 DestinationColor; // 3 | |
// Add right before the main | |
uniform mat4 Projection; | |
void main(void) { // 4 | |
DestinationColor = vColor; // 5 | |
gl_Position = Projection * vPosition; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
According to the OpenGL ES 2.0 API (https://www.khronos.org/registry/OpenGL-Refpages/es2.0/), APIs supporting VAO such as glGenVertexArrays, glBindVertexArray do not exist!