I am curious as to whether you can have more than one shader in an Open GL ES 2.0 program.
Here is my code the shaders. The attributes and uniforms however only retrieve the variables from the rigid.vert and rigid.frag shader:
- (BOOL)loadShaders
{
GLuint rigidVertShader, rigidFragShader, skinningVertShader, skinningFragShader;
NSString *rigidVertShaderPathname, *rigidFragShaderPathname, *skinningVertShaderPathname, *skinningFragShaderPathname;
// Create shader program.
_program = glCreateProgram();
// Create and compile rigid vertex shader.
rigidVertShaderPathname = [[NSBundle mainBundle] pathForResource:@"rigid" ofType:@"vert"];
if (![self compileShader:&rigidVertShader type:GL_VERTEX_SHADER file:rigidVertShaderPathname]) {
NSLog(@"Failed to compile rigid vertex shader");
return NO;
}
// Create and compile rigid fragment shader.
rigidFragShaderPathname = [[NSBundle mainBundle] pathForResource:@"rigid" ofType:@"frag"];
if (![self compileShader:&rigidFragShader type:GL_FRAGMENT_SHADER file:rigidFragShaderPathname]) {
NSLog(@"Failed to compile rigid fragment shader");
return NO;
}
// Create and compile skinning vertex shader.
skinningVertShaderPathname = [[NSBundle mainBundle] pathForResource:@"skinning" ofType:@"vert"];
if (![self compileShader:&skinningVertShader type:GL_VERTEX_SHADER file:skinningVertShaderPathname]) {
NSLog(@"Failed to compile skinning vertex shader");
return NO;
}
// Create and compile skinning fragment shader.
skinningFragShaderPathname = [[NSBundle mainBundle] pathForResource:@"skinning" ofType:@"frag"];
if (![self compileShader:&skinningFragShader type:GL_FRAGMENT_SHADER file:skinningFragShaderPathname]) {
NSLog(@"Failed to compile skinning fragment shader");
return NO;
}
// Attach rigid vertex shader to program.
glAttachShader(_program, rigidVertShader);
// Attach rigid fragment shader to program.
glAttachShader(_program, rigidFragShader);
// Attach skinning vertex shader to program.
glAttachShader(_program, skinningVertShader);
// Attach skinning fragment shader to program.
glAttachShader(_program, skinningFragShader);
// Link program.
if (![self linkProgram:_program]) {
NSLog(@"Failed to link program: %d", _program);
if (rigidVertShader) {
glDeleteShader(rigidVertShader);
rigidVertShader = 0;
}
if (rigidFragShader) {
glDeleteShader(rigidFragShader);
rigidFragShader = 0;
}
if (skinningVertShader) {
glDeleteShader(skinningVertShader);
skinningVertShader = 0;
}
if (skinningFragShader) {
glDeleteShader(skinningFragShader);
skinningFragShader = 0;
}
if (_program) {
glDeleteProgram(_program);
_program = 0;
}
return NO;
}
// GET UNIFORM LOCATIONS
// Dictionary to store each active uniform
NSMutableDictionary *m_uniforms = [[NSMutableDictionary alloc] init];
int m_nUniforms = -1;
glGetProgramiv( _program, GL_ACTIVE_UNIFORMS, &m_nUniforms );
for(GLuint i = 0; i < m_nUniforms; i++) {
int name_len=-1, num=-1;
GLenum type = GL_ZERO;
char uniformName[100];
glGetActiveUniform( _program, i, sizeof(uniformName)-1, &name_len, &num, &type, uniformName );
uniformName[name_len] = 0;
GLuint uniform = glGetUniformLocation( _program, uniformName );
[m_uniforms setObject:[NSNumber numberWithUnsignedInt:uniform]
forKey:[NSString stringWithUTF8String:uniformName]];
}
// GET ATTRIBUTE LOCATIONS
// Dictionary to store each active attribute
NSMutableDictionary *m_attributes = [[NSMutableDictionary alloc] init];
int m_nAttributes = -1;
glGetProgramiv( _program, GL_ACTIVE_ATTRIBUTES, &m_nAttributes );
for(GLuint i = 0; i < m_nAttributes; i++) {
int name_len=-1, num=-1;
GLenum type = GL_ZERO;
char attributesName[100];
glGetActiveAttrib( _program, i, sizeof(attributesName)-1, &name_len, &num, &type, attributesName );
attributesName[name_len] = 0;
GLuint attributes = glGetAttribLocation( _program, attributesName );
[m_attributes setObject:[NSNumber numberWithUnsignedInt:attributes]
forKey:[NSString stringWithUTF8String:attributesName]];
}
// Release vertex and fragment shaders.
if (rigidVertShader) {
glDetachShader(_program, rigidVertShader);
glDeleteShader(rigidVertShader);
}
if (rigidFragShader) {
glDetachShader(_program, rigidFragShader);
glDeleteShader(rigidFragShader);
}
if (skinningVertShader) {
glDetachShader(_program, skinningVertShader);
glDeleteShader(skinningVertShader);
}
if (skinningFragShader) {
glDetachShader(_program, skinningFragShader);
glDeleteShader(skinningFragShader);
}
return YES;
}