Skip to content

Instantly share code, notes, and snippets.

@marknorgren
Created April 29, 2012 22:26
Show Gist options
  • Save marknorgren/2553555 to your computer and use it in GitHub Desktop.
Save marknorgren/2553555 to your computer and use it in GitHub Desktop.
openGL ES 2.0 VAO VBO setup
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
//
// 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
varying lowp vec4 DestinationColor; // 1
void main(void) { // 2
gl_FragColor = DestinationColor; // 3
}
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;
}
@tielei
Copy link

tielei commented Aug 22, 2017

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment