I'm trying to teach myself Xcode, Objective-C, iOS app development, and GLSL all at once. (Probably not advisable, I know. ;-) I've been modifying the GLCameraRipple example, and had a lot of success so far! But I got stumped today when I tried to create some new vertex and fragment shaders.
The example comes with shaders called "Shader.vsh" and "Shader.fsh". I used File->Duplicate to make copies of them, which I called "Reflection.vsh" and "Reflection.fsh" respectively. The problem is that I can't get Xcode to recognize the new shaders. This code, which loads up the original vertex shader, works just fine:
vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
NSLog(@"Original vertex shader should be here: %@", vertShaderPathname);
if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
NSLog(@"Failed to compile original vertex shader");
return NO;
}
But this code, which tries to load my new "Reflection.vsh" shader, fails. Specifically, the reflectVertShaderPathname string comes back with a value of (null).
reflectVertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Reflection" ofType:@"vsh"];
NSLog(@"Reflection vertex shader should be here: %@", reflectVertShaderPathname);
if (![self compileShader:&reflectVertShader type:GL_VERTEX_SHADER file:reflectVertShaderPathname]) {
NSLog(@"Failed to compile reflection vertex shader");
return NO;
}
What do I have to do to make this work? I can't even tell where to start: is Xcode failing to include my new shaders in the NSBundle it makes when compiling this for the iPad? What magic voodoo do I have to invoke to convince Xcode to load up my new shaders? (Or am I looking for answers in the wrong place entirely?) Has anyone else run into a similar problem before?
Inspecting the "project.pbxproj" file in a text editor, I noticed a section where the shaders are being treated differently:
/* Begin PBXResourcesBuildPhase section */
B66E3E2C13E9E79C00D2ACF0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B66E3E4713E9E79C00D2ACF0 /* Shader.fsh in Resources */,
B66E3E4913E9E79C00D2ACF0 /* Shader.vsh in Resources */,
B66E3E4F13E9E79C00D2ACF0 /* RippleViewController_iPhone.xib in Resources */,
B66E3E5213E9E79C00D2ACF0 /* RippleViewController_iPad.xib in Resources */,
B6388B2C141AB58300DA02FB /* Icon-72.png in Resources */,
B6388B2D141AB58300DA02FB /* Icon-Small-50.png in Resources */,
B6388B2E141AB58300DA02FB /* Icon-Small.png in Resources */,
B6388B2F141AB58300DA02FB /* Icon-Small@2x.png in Resources */,
B6388B30141AB58300DA02FB /* Icon.png in Resources */,
B6388B31141AB58300DA02FB /* Icon@2x.png in Resources */,
C3E55C21175C49F9007C299D /* Default-568h@2x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
B66E3E2A13E9E79C00D2ACF0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B66E3E4113E9E79C00D2ACF0 /* main.m in Sources */,
B66E3E4513E9E79C00D2ACF0 /* AppDelegate.m in Sources */,
B66E3E4C13E9E79C00D2ACF0 /* RippleViewController.m in Sources */,
B6670DB413E9FD9F00AEF9EC /* RippleModel.m in Sources */,
C359BF4D175EA71C00D801B9 /* Reflection.fsh in Sources */,
C359BF4F175EA72A00D801B9 /* Reflection.vsh in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
So it looks like "Shader.vsh" is in something called "Resources", and "Reflection.vsh" is in something called "Sources". I assume that's part of the problem. But (a) what does that even mean, and (b) how should I fix it? Is it safe to just edit project.pbxproj in a text editor???
You've almost got it - xcode needs to know these are resources that need to be copied over, not source. No need to edit project files by hand, it's easy to fix in xcode:
That's it! Keep in mind, you'll have to do this for every new shader you add.