- // replace spaces in the cachename with _ characters
- for (i = 0;cachename[i];i++)
- if (cachename[i] == ' ')
- cachename[i] = '_';
-
- // now append the shader text itself
- vertstrings_list[vertstrings_count++] = vertexstring;
- geomstrings_list[geomstrings_count++] = geometrystring;
- fragstrings_list[fragstrings_count++] = fragmentstring;
-
- // if any sources were NULL, clear the respective list
- if (!vertexstring)
- vertstrings_count = 0;
- if (!geometrystring)
- geomstrings_count = 0;
- if (!fragmentstring)
- fragstrings_count = 0;
-
- vertstring_length = 0;
- for (i = 0;i < vertstrings_count;i++)
- vertstring_length += strlen(vertstrings_list[i]);
- vertstring = t = (char *)Mem_Alloc(tempmempool, vertstring_length + 1);
- for (i = 0;i < vertstrings_count;t += strlen(vertstrings_list[i]), i++)
- memcpy(t, vertstrings_list[i], strlen(vertstrings_list[i]));
-
- geomstring_length = 0;
- for (i = 0;i < geomstrings_count;i++)
- geomstring_length += strlen(geomstrings_list[i]);
- geomstring = t = (char *)Mem_Alloc(tempmempool, geomstring_length + 1);
- for (i = 0;i < geomstrings_count;t += strlen(geomstrings_list[i]), i++)
- memcpy(t, geomstrings_list[i], strlen(geomstrings_list[i]));
-
- fragstring_length = 0;
- for (i = 0;i < fragstrings_count;i++)
- fragstring_length += strlen(fragstrings_list[i]);
- fragstring = t = (char *)Mem_Alloc(tempmempool, fragstring_length + 1);
- for (i = 0;i < fragstrings_count;t += strlen(fragstrings_list[i]), i++)
- memcpy(t, fragstrings_list[i], strlen(fragstrings_list[i]));
-
- // try to load the cached shader, or generate one
- R_HLSL_CacheShader(p, cachename, vertstring, fragstring);
-
- if ((p->vertexshader || !vertstring[0]) && (p->pixelshader || !fragstring[0]))
- Con_DPrintf("^5HLSL shader %s compiled.\n", permutationname);
- else
- Con_Printf("^1HLSL shader %s failed! some features may not work properly.\n", permutationname);
-
- // free the strings
- if (vertstring)
- Mem_Free(vertstring);
- if (geomstring)
- Mem_Free(geomstring);
- if (fragstring)
- Mem_Free(fragstring);
- if (vertexstring)
- Mem_Free(vertexstring);
- if (geometrystring)
- Mem_Free(geometrystring);
- if (fragmentstring)
- Mem_Free(fragmentstring);
-}
-
-static inline void hlslVSSetParameter16f(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 4);}
-static inline void hlslVSSetParameter4fv(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 1);}
-static inline void hlslVSSetParameter4f(D3DVSREGISTER_t r, float x, float y, float z, float w) {float temp[4];Vector4Set(temp, x, y, z, w);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
-static inline void hlslVSSetParameter3f(D3DVSREGISTER_t r, float x, float y, float z) {float temp[4];Vector4Set(temp, x, y, z, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
-static inline void hlslVSSetParameter2f(D3DVSREGISTER_t r, float x, float y) {float temp[4];Vector4Set(temp, x, y, 0, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
-static inline void hlslVSSetParameter1f(D3DVSREGISTER_t r, float x) {float temp[4];Vector4Set(temp, x, 0, 0, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
-
-static inline void hlslPSSetParameter16f(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 4);}
-static inline void hlslPSSetParameter4fv(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 1);}
-static inline void hlslPSSetParameter4f(D3DPSREGISTER_t r, float x, float y, float z, float w) {float temp[4];Vector4Set(temp, x, y, z, w);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
-static inline void hlslPSSetParameter3f(D3DPSREGISTER_t r, float x, float y, float z) {float temp[4];Vector4Set(temp, x, y, z, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
-static inline void hlslPSSetParameter2f(D3DPSREGISTER_t r, float x, float y) {float temp[4];Vector4Set(temp, x, y, 0, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
-static inline void hlslPSSetParameter1f(D3DPSREGISTER_t r, float x) {float temp[4];Vector4Set(temp, x, 0, 0, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
-
-void R_SetupShader_SetPermutationHLSL(unsigned int mode, unsigned int permutation)
-{
- r_hlsl_permutation_t *perm = R_HLSL_FindPermutation(mode, permutation);
- if (r_hlsl_permutation != perm)
- {
- r_hlsl_permutation = perm;
- if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
- {
- if (!r_hlsl_permutation->compiled)
- R_HLSL_CompilePermutation(perm, mode, permutation);
- if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
- {
- // remove features until we find a valid permutation
- int i;
- for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
- {
- // reduce i more quickly whenever it would not remove any bits
- int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
- if (!(permutation & j))
- continue;
- permutation -= j;
- r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
- if (!r_hlsl_permutation->compiled)
- R_HLSL_CompilePermutation(perm, mode, permutation);
- if (r_hlsl_permutation->vertexshader || r_hlsl_permutation->pixelshader)
- break;
- }
- if (i >= SHADERPERMUTATION_COUNT)
- {
- //Con_Printf("Could not find a working Cg shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
- r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
- return; // no bit left to clear, entire mode is broken
- }
- }
- }
- IDirect3DDevice9_SetVertexShader(vid_d3d9dev, r_hlsl_permutation->vertexshader);
- IDirect3DDevice9_SetPixelShader(vid_d3d9dev, r_hlsl_permutation->pixelshader);
- }
- hlslVSSetParameter16f(D3DVSREGISTER_ModelViewProjectionMatrix, gl_modelviewprojection16f);
- hlslVSSetParameter16f(D3DVSREGISTER_ModelViewMatrix, gl_modelview16f);
- hlslPSSetParameter1f(D3DPSREGISTER_ClientTime, cl.time);
-}
-#endif
-
-void R_GLSL_Restart_f(void)
-{
- unsigned int i, limit;
- if (glslshaderstring && glslshaderstring != builtinshaderstring)
- Mem_Free(glslshaderstring);
- glslshaderstring = NULL;
- if (cgshaderstring && cgshaderstring != builtincgshaderstring)
- Mem_Free(cgshaderstring);
- cgshaderstring = NULL;
- if (hlslshaderstring && hlslshaderstring != builtincgshaderstring)
- Mem_Free(hlslshaderstring);
- hlslshaderstring = NULL;
- switch(vid.renderpath)
- {
- case RENDERPATH_D3D9:
-#ifdef SUPPORTD3D
- {
- r_hlsl_permutation_t *p;
- r_hlsl_permutation = NULL;
-// cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
-// cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
-// cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
-// cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
- limit = Mem_ExpandableArray_IndexRange(&r_hlsl_permutationarray);
- for (i = 0;i < limit;i++)
- {
- if ((p = (r_hlsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_hlsl_permutationarray, i)))
- {
- if (p->vertexshader)
- IDirect3DVertexShader9_Release(p->vertexshader);
- if (p->pixelshader)
- IDirect3DPixelShader9_Release(p->pixelshader);
- Mem_ExpandableArray_FreeRecord(&r_hlsl_permutationarray, (void*)p);
- }
- }
- memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
- }
-#endif
- break;
- case RENDERPATH_D3D10:
- Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
- break;
- case RENDERPATH_D3D11:
- Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
- break;
- case RENDERPATH_GL20:
- {
- r_glsl_permutation_t *p;
- r_glsl_permutation = NULL;
- limit = Mem_ExpandableArray_IndexRange(&r_glsl_permutationarray);
- for (i = 0;i < limit;i++)
- {
- if ((p = (r_glsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_glsl_permutationarray, i)))
- {
- GL_Backend_FreeProgram(p->program);
- Mem_ExpandableArray_FreeRecord(&r_glsl_permutationarray, (void*)p);
- }
- }
- memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
- }
- break;
- case RENDERPATH_CGGL:
-#ifdef SUPPORTCG
- {
- r_cg_permutation_t *p;
- r_cg_permutation = NULL;
- cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
- cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
- cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
- cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
- limit = Mem_ExpandableArray_IndexRange(&r_cg_permutationarray);
- for (i = 0;i < limit;i++)
- {
- if ((p = (r_cg_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_cg_permutationarray, i)))
- {
- if (p->vprogram)
- cgDestroyProgram(p->vprogram);
- if (p->fprogram)
- cgDestroyProgram(p->fprogram);
- Mem_ExpandableArray_FreeRecord(&r_cg_permutationarray, (void*)p);
- }
- }
- memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash));
- }
-#endif
- break;
- case RENDERPATH_GL13:
- case RENDERPATH_GL11:
- break;
- }
-}
-
-void R_GLSL_DumpShader_f(void)
-{
- int i;
- qfile_t *file;
-
- file = FS_OpenRealFile("glsl/default.glsl", "w", false);
- if (file)
- {
- FS_Print(file, "/* The engine may define the following macros:\n");
- FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
- for (i = 0;i < SHADERMODE_COUNT;i++)
- FS_Print(file, glslshadermodeinfo[i].pretext);
- for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
- FS_Print(file, shaderpermutationinfo[i].pretext);
- FS_Print(file, "*/\n");
- FS_Print(file, builtinshaderstring);
- FS_Close(file);
- Con_Printf("glsl/default.glsl written\n");
- }
- else
- Con_Printf("failed to write to glsl/default.glsl\n");
-
-#ifdef SUPPORTCG
- file = FS_OpenRealFile("cg/default.cg", "w", false);
- if (file)
- {
- FS_Print(file, "/* The engine may define the following macros:\n");
- FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
- for (i = 0;i < SHADERMODE_COUNT;i++)
- FS_Print(file, cgshadermodeinfo[i].pretext);
- for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
- FS_Print(file, shaderpermutationinfo[i].pretext);
- FS_Print(file, "*/\n");
- FS_Print(file, builtincgshaderstring);
- FS_Close(file);
- Con_Printf("cg/default.cg written\n");
- }
- else
- Con_Printf("failed to write to cg/default.cg\n");
-#endif
-
-#ifdef SUPPORTD3D
- file = FS_OpenRealFile("hlsl/default.hlsl", "w", false);
- if (file)
- {
- FS_Print(file, "/* The engine may define the following macros:\n");
- FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
- for (i = 0;i < SHADERMODE_COUNT;i++)
- FS_Print(file, hlslshadermodeinfo[i].pretext);
- for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
- FS_Print(file, shaderpermutationinfo[i].pretext);
- FS_Print(file, "*/\n");
- FS_Print(file, builtincgshaderstring);
- FS_Close(file);
- Con_Printf("hlsl/default.hlsl written\n");
- }
- else
- Con_Printf("failed to write to hlsl/default.hlsl\n");
-#endif
-}
-
-void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale)
-{
- if (!second)
- texturemode = GL_MODULATE;
- switch (vid.renderpath)
- {
- case RENDERPATH_D3D9:
-#ifdef SUPPORTD3D
- R_SetupShader_SetPermutationHLSL(SHADERMODE_GENERIC, (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (r_shadow_glossexact.integer ? SHADERPERMUTATION_EXACTSPECULARMATH : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
- R_Mesh_TexBind(GL20TU_FIRST , first );
- R_Mesh_TexBind(GL20TU_SECOND, second);
-#endif
- break;
- case RENDERPATH_D3D10:
- Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
- break;
- case RENDERPATH_D3D11:
- Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
- break;
- case RENDERPATH_GL20:
- R_SetupShader_SetPermutationGLSL(SHADERMODE_GENERIC, (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (r_shadow_glossexact.integer ? SHADERPERMUTATION_EXACTSPECULARMATH : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
- R_Mesh_TexBind(GL20TU_FIRST , first );
- R_Mesh_TexBind(GL20TU_SECOND, second);
- break;
- case RENDERPATH_CGGL:
-#ifdef SUPPORTCG
- CHECKCGERROR
- R_SetupShader_SetPermutationCG(SHADERMODE_GENERIC, (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (r_shadow_glossexact.integer ? SHADERPERMUTATION_EXACTSPECULARMATH : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
- if (r_cg_permutation->fp_Texture_First ) CG_BindTexture(r_cg_permutation->fp_Texture_First , first );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Second) CG_BindTexture(r_cg_permutation->fp_Texture_Second, second);CHECKCGERROR
-#endif
- break;
- case RENDERPATH_GL13:
- R_Mesh_TexBind(0, first );
- R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
- R_Mesh_TexBind(1, second);
- if (second)
- R_Mesh_TexCombine(1, texturemode, texturemode, rgbscale, 1);
- break;
- case RENDERPATH_GL11:
- R_Mesh_TexBind(0, first );
- break;
- }
-}