|
|
@@ -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); |
|
|
|