program_shaders.erase(shader_it);
}
-GLuint ResourcePool::compile_glsl_program(const string& vertex_shader, const string& fragment_shader)
+GLuint ResourcePool::compile_glsl_program(const string& vertex_shader,
+ const string& fragment_shader,
+ const vector<string>& fragment_shader_outputs)
{
GLuint glsl_program_num;
pthread_mutex_lock(&lock);
- const pair<string, string> key(vertex_shader, fragment_shader);
+
+ // Augment the fragment shader program text with the outputs, so that they become
+ // part of the key. Also potentially useful for debugging.
+ string fragment_shader_processed = fragment_shader;
+ for (unsigned output_index = 0; output_index < fragment_shader_outputs.size(); ++output_index) {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "// Bound output: %s\n", fragment_shader_outputs[output_index].c_str());
+ fragment_shader_processed += buf;
+ }
+
+ const pair<string, string> key(vertex_shader, fragment_shader_processed);
if (programs.count(key)) {
// Already in the cache. Increment the refcount, or take it off the freelist
// if it's zero.
check_error();
GLuint vs_obj = compile_shader(vertex_shader, GL_VERTEX_SHADER);
check_error();
- GLuint fs_obj = compile_shader(fragment_shader, GL_FRAGMENT_SHADER);
+ GLuint fs_obj = compile_shader(fragment_shader_processed, GL_FRAGMENT_SHADER);
check_error();
glAttachShader(glsl_program_num, vs_obj);
check_error();
glAttachShader(glsl_program_num, fs_obj);
check_error();
+
+ // Bind the outputs, if we have multiple ones.
+ if (fragment_shader_outputs.size() > 1) {
+ for (unsigned output_index = 0; output_index < fragment_shader_outputs.size(); ++output_index) {
+ glBindFragDataLocation(glsl_program_num, output_index,
+ fragment_shader_outputs[output_index].c_str());
+ }
+ }
+
glLinkProgram(glsl_program_num);
check_error();
perror(filename);
exit(1);
}
- fprintf(fp, "%s\n", fragment_shader.c_str());
+ fprintf(fp, "%s\n", fragment_shader_processed.c_str());
fclose(fp);
}
case GL_RGBA32F_ARB:
case GL_RGBA16F_ARB:
case GL_RGBA8:
+ case GL_RGB10_A2:
case GL_SRGB8_ALPHA8:
format = GL_RGBA;
break;
case GL_RGB32F:
case GL_RGB16F:
+ case GL_R11F_G11F_B10F:
case GL_RGB8:
+ case GL_RGB10:
case GL_SRGB8:
case GL_RGB565:
+ case GL_RGB9_E5:
format = GL_RGB;
break;
case GL_RG32F:
case GL_RGBA16F_ARB:
case GL_RGB32F:
case GL_RGB16F:
+ case GL_R11F_G11F_B10F:
+ case GL_RGB9_E5:
case GL_RG32F:
case GL_RG16F:
case GL_R32F:
case GL_SRGB8:
case GL_RGBA8:
case GL_RGB8:
+ case GL_RGB10_A2:
+ case GL_RGB10:
case GL_RG8:
case GL_R8:
type = GL_UNSIGNED_BYTE;
case GL_RGB16F_ARB:
bytes_per_pixel = 6;
break;
+ case GL_R11F_G11F_B10F:
+ bytes_per_pixel = 4;
+ break;
+ case GL_RGB9_E5:
+ bytes_per_pixel = 4;
+ break;
case GL_RGBA8:
case GL_SRGB8_ALPHA8:
+ case GL_RGB10_A2:
+ case GL_RGB10:
bytes_per_pixel = 4;
break;
case GL_RGB8: