+EffectChain::Phase EffectChain::compile_glsl_program(unsigned start_index, unsigned end_index)
+{
+ bool input_needs_mipmaps = false;
+ std::string frag_shader = read_file("header.frag");
+ for (unsigned i = start_index; i < end_index; ++i) {
+ char effect_id[256];
+ sprintf(effect_id, "eff%d", i);
+
+ frag_shader += "\n";
+ frag_shader += std::string("#define FUNCNAME ") + effect_id + "\n";
+ frag_shader += replace_prefix(effects[i]->output_convenience_uniforms(), effect_id);
+ frag_shader += replace_prefix(effects[i]->output_fragment_shader(), effect_id);
+ frag_shader += "#undef PREFIX\n";
+ frag_shader += "#undef FUNCNAME\n";
+ frag_shader += "#undef LAST_INPUT\n";
+ frag_shader += std::string("#define LAST_INPUT ") + effect_id + "\n";
+ frag_shader += "\n";
+
+ input_needs_mipmaps |= effects[i]->needs_mipmaps();
+ }
+ frag_shader.append(read_file("footer.frag"));
+ printf("%s\n", frag_shader.c_str());
+
+ GLuint glsl_program_num = glCreateProgram();
+ GLuint vs_obj = compile_shader(read_file("vs.vert"), GL_VERTEX_SHADER);
+ GLuint fs_obj = compile_shader(frag_shader, GL_FRAGMENT_SHADER);
+ glAttachShader(glsl_program_num, vs_obj);
+ check_error();
+ glAttachShader(glsl_program_num, fs_obj);
+ check_error();
+ glLinkProgram(glsl_program_num);
+ check_error();
+
+ Phase phase;
+ phase.glsl_program_num = glsl_program_num;
+ phase.input_needs_mipmaps = input_needs_mipmaps;
+ phase.start = start_index;
+ phase.end = end_index;
+
+ return phase;
+}
+