diff --git a/src/shader.cpp b/src/shader.cpp index 93fc88f5..b0a8da55 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -38,20 +38,42 @@ class ShaderData private: GLuint prog_id, vert_id, frag_id; + uint32_t vert_crc, frag_crc; + + /* Global shader cache */ + static Shader *shaders[]; + static int nshaders; }; +Shader *ShaderData::shaders[256]; +int ShaderData::nshaders = 0; + /* * Public Shader class */ Shader *Shader::Create(char const *vert, char const *frag) { - return new Shader(vert, frag); + uint32_t new_vert_crc = Hash::Crc32(vert); + uint32_t new_frag_crc = Hash::Crc32(frag); + + for (int n = 0; n < ShaderData::nshaders; n++) + { + if (ShaderData::shaders[n]->data->vert_crc == new_vert_crc + && ShaderData::shaders[n]->data->frag_crc == new_frag_crc) + return ShaderData::shaders[n]; + } + + Shader *ret = new Shader(vert, frag); + ShaderData::shaders[ShaderData::nshaders] = ret; + ShaderData::nshaders++; + return ret; } void Shader::Destroy(Shader *shader) { - delete shader; + /* XXX: do nothing! the shader should remain in cache */ + (void)shader; } Shader::Shader(char const *vert, char const *frag) @@ -60,6 +82,7 @@ Shader::Shader(char const *vert, char const *frag) char buf[4096]; GLsizei len; + data->vert_crc = Hash::Crc32(vert); data->vert_id = glCreateShader(GL_VERTEX_SHADER); glShaderSource(data->vert_id, 1, &vert, NULL); glCompileShader(data->vert_id); @@ -68,6 +91,7 @@ Shader::Shader(char const *vert, char const *frag) if (len > 0) fprintf(stderr, "ERROR: failed to compile vertex shader: %s", buf); + data->frag_crc = Hash::Crc32(frag); data->frag_id = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(data->frag_id, 1, &frag, NULL); glCompileShader(data->frag_id);