+ GLenum type;
+ switch(*i)
+ {
+ case SL::Stage::VERTEX:
+ { static Require _req(ARB_vertex_shader); }
+ type = GL_VERTEX_SHADER;
+ break;
+ case SL::Stage::GEOMETRY:
+ { static Require _req(ARB_geometry_shader4); }
+ type = GL_GEOMETRY_SHADER;
+ break;
+ case SL::Stage::FRAGMENT:
+ { static Require _req(ARB_fragment_shader); }
+ type = GL_FRAGMENT_SHADER;
+ break;
+ default:
+ throw invalid_operation("Program::add_stages");
+ }
+
+ unsigned stage_id = glCreateShader(type);
+ shader_ids.push_back(stage_id);
+ glAttachShader(id, stage_id);
+
+ string stage_src = compiler.get_stage_glsl(*i);
+ const char *src_ptr = stage_src.data();
+ int src_len = stage_src.size();
+ glShaderSource(stage_id, 1, &src_ptr, &src_len);
+
+ if(*i==SL::Stage::VERTEX)
+ {
+ const map<string, unsigned> &attribs = compiler.get_vertex_attributes();
+ for(map<string, unsigned>::const_iterator j=attribs.begin(); j!=attribs.end(); ++j)
+ glBindAttribLocation(id, j->second, j->first.c_str());
+ }
+
+ if(*i==SL::Stage::FRAGMENT && EXT_gpu_shader4)
+ {
+ const map<string, unsigned> &frag_outs = compiler.get_fragment_outputs();
+ for(map<string, unsigned>::const_iterator j=frag_outs.begin(); j!=frag_outs.end(); ++j)
+ glBindFragDataLocation(id, j->second, j->first.c_str());
+ }