+int R_Shadow_CompileShaderPermutation(int permutation)
+{
+ if (r_shadow_program_compiledlight[permutation])
+ return r_shadow_program_light[permutation];
+ r_shadow_program_compiledlight[permutation] = true;
+ char *vertstring, *fragstring;
+ int vertstrings_count;
+ int fragstrings_count;
+ const char *vertstrings_list[SHADERPERMUTATION_COUNT+1];
+ const char *fragstrings_list[SHADERPERMUTATION_COUNT+1];
+ char permutationname[256];
+ vertstring = (char *)FS_LoadFile("glsl/light.vert", tempmempool, false, NULL);
+ fragstring = (char *)FS_LoadFile("glsl/light.frag", tempmempool, false, NULL);
+ vertstrings_count = 0;
+ fragstrings_count = 0;
+ permutationname[0] = 0;
+ if (permutation & SHADERPERMUTATION_COLORMAPPING)
+ {
+ vertstrings_list[vertstrings_count++] = "#define USECOLORMAPPING\n";
+ fragstrings_list[fragstrings_count++] = "#define USECOLORMAPPING\n";
+ strlcat(permutationname, " colormapping", sizeof(permutationname));
+ }
+ if (permutation & SHADERPERMUTATION_SPECULAR)
+ {
+ vertstrings_list[vertstrings_count++] = "#define USESPECULAR\n";
+ fragstrings_list[fragstrings_count++] = "#define USESPECULAR\n";
+ strlcat(permutationname, " specular", sizeof(permutationname));
+ }
+ if (permutation & SHADERPERMUTATION_FOG)
+ {
+ vertstrings_list[vertstrings_count++] = "#define USEFOG\n";
+ fragstrings_list[fragstrings_count++] = "#define USEFOG\n";
+ strlcat(permutationname, " fog", sizeof(permutationname));
+ }
+ if (permutation & SHADERPERMUTATION_CUBEFILTER)
+ {
+ vertstrings_list[vertstrings_count++] = "#define USECUBEFILTER\n";
+ fragstrings_list[fragstrings_count++] = "#define USECUBEFILTER\n";
+ strlcat(permutationname, " cubefilter", sizeof(permutationname));
+ }
+ if (permutation & SHADERPERMUTATION_OFFSETMAPPING)
+ {
+ vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING\n";
+ fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING\n";
+ strlcat(permutationname, " offsetmapping", sizeof(permutationname));
+ }
+ if (permutation & SHADERPERMUTATION_SURFACENORMALIZE)
+ {
+ vertstrings_list[vertstrings_count++] = "#define SURFACENORMALIZE\n";
+ fragstrings_list[fragstrings_count++] = "#define SURFACENORMALIZE\n";
+ strlcat(permutationname, " surfacenormalize", sizeof(permutationname));
+ }
+ if (permutation & SHADERPERMUTATION_GEFORCEFX)
+ {
+ vertstrings_list[vertstrings_count++] = "#define GEFORCEFX\n";
+ fragstrings_list[fragstrings_count++] = "#define GEFORCEFX\n";
+ strlcat(permutationname, " halffloat", sizeof(permutationname));
+ }
+ vertstrings_list[vertstrings_count++] = vertstring ? vertstring : builtinshader_light_vert;
+ fragstrings_list[fragstrings_count++] = fragstring ? fragstring : builtinshader_light_frag;
+ r_shadow_program_light[permutation] = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, fragstrings_count, fragstrings_list);
+ if (r_shadow_program_light[permutation])
+ {
+ qglUseProgramObjectARB(r_shadow_program_light[permutation]);
+ qglUniform1iARB(qglGetUniformLocationARB(r_shadow_program_light[permutation], "Texture_Normal"), 0);CHECKGLERROR
+ qglUniform1iARB(qglGetUniformLocationARB(r_shadow_program_light[permutation], "Texture_Color"), 1);CHECKGLERROR
+ if (permutation & SHADERPERMUTATION_SPECULAR)
+ {
+ qglUniform1iARB(qglGetUniformLocationARB(r_shadow_program_light[permutation], "Texture_Gloss"), 2);CHECKGLERROR
+ }
+ if (permutation & SHADERPERMUTATION_CUBEFILTER)
+ {
+ qglUniform1iARB(qglGetUniformLocationARB(r_shadow_program_light[permutation], "Texture_Cube"), 3);CHECKGLERROR
+ }
+ if (permutation & SHADERPERMUTATION_FOG)
+ {
+ qglUniform1iARB(qglGetUniformLocationARB(r_shadow_program_light[permutation], "Texture_FogMask"), 4);CHECKGLERROR
+ }
+ qglUniform1iARB(qglGetUniformLocationARB(r_shadow_program_light[permutation], "Texture_Pants"), 5);CHECKGLERROR
+ qglUniform1iARB(qglGetUniformLocationARB(r_shadow_program_light[permutation], "Texture_Shirt"), 6);CHECKGLERROR
+ qglUseProgramObjectARB(0);
+ }
+ else
+ Con_Printf("permutation%s failed for shader %s, some features may not work properly!\n", permutationname, "glsl/light");
+ if (fragstring)
+ Mem_Free(fragstring);
+ if (vertstring)
+ Mem_Free(vertstring);
+ return r_shadow_program_light[permutation];
+}
+