bool GLShader::buildLightShaderVariant(int lightType, int variantFlag) { const char *lightIds[MAX_LIGHTS] = {"0","1","2","3","4","5","6","7"}; const char *lightIdToken = "%LIGHTID%"; const char *lightLoopStartToken = "%LIGHTLOOP:START%"; const char *lightLoopEndToken = "%LIGHTLOOP:END%"; int lightLoopStartTokenLen = 17; int lightLoopEndTokenLen = 15; bool isMultiLight = light_multi[lightType]; std::string lightFrag; std::string lightVert; lightFrag.append(light_frag_str[lightType]); lightVert.append(light_vert_str[lightType]); searchAndReplace(lightFrag,"%hasColorMap%",(variantFlag & SHADER_VARIANT_COLOR)?"1":"0"); searchAndReplace(lightVert,"%hasColorMap%",(variantFlag & SHADER_VARIANT_COLOR)?"1":"0"); searchAndReplace(lightFrag,"%hasAlphaMap%",(variantFlag & SHADER_VARIANT_ALPHA)?"1":"0"); searchAndReplace(lightVert,"%hasAlphaMap%",(variantFlag & SHADER_VARIANT_ALPHA)?"1":"0"); searchAndReplace(lightFrag,"%hasSpecMap%",(variantFlag & SHADER_VARIANT_SPECULAR)?"1":"0"); searchAndReplace(lightVert,"%hasSpecMap%",(variantFlag & SHADER_VARIANT_SPECULAR)?"1":"0"); searchAndReplace(lightFrag,"%hasLumiMap%",(variantFlag & SHADER_VARIANT_LUMINOSITY)?"1":"0"); searchAndReplace(lightVert,"%hasLumiMap%",(variantFlag & SHADER_VARIANT_LUMINOSITY)?"1":"0"); searchAndReplace(lightFrag,"%hasBumpMap%",(variantFlag & SHADER_VARIANT_BUMP)?"1":"0"); searchAndReplace(lightVert,"%hasBumpMap%",(variantFlag & SHADER_VARIANT_BUMP)?"1":"0"); searchAndReplace(lightFrag,"%hasShadowMap0%",(variantFlag & SHADER_VARIANT_SHADOW0)?"1":"0"); searchAndReplace(lightVert,"%hasShadowMap0%",(variantFlag & SHADER_VARIANT_SHADOW0)?"1":"0"); searchAndReplace(lightFrag,"%hasShadowMap1%",(variantFlag & SHADER_VARIANT_SHADOW1)?"1":"0"); searchAndReplace(lightVert,"%hasShadowMap1%",(variantFlag & SHADER_VARIANT_SHADOW1)?"1":"0"); searchAndReplace(lightFrag,"%hasShadowMap2%",(variantFlag & SHADER_VARIANT_SHADOW2)?"1":"0"); searchAndReplace(lightVert,"%hasShadowMap2%",(variantFlag & SHADER_VARIANT_SHADOW2)?"1":"0"); searchAndReplace(lightFrag,"%hasShadowMap3%",(variantFlag & SHADER_VARIANT_SHADOW3)?"1":"0"); searchAndReplace(lightVert,"%hasShadowMap3%",(variantFlag & SHADER_VARIANT_SHADOW3)?"1":"0"); searchAndReplace(lightFrag,"%hasShadowMap4%",(variantFlag & SHADER_VARIANT_SHADOW4)?"1":"0"); searchAndReplace(lightVert,"%hasShadowMap4%",(variantFlag & SHADER_VARIANT_SHADOW4)?"1":"0"); searchAndReplace(lightFrag,"%hasShadowMap5%",(variantFlag & SHADER_VARIANT_SHADOW5)?"1":"0"); searchAndReplace(lightVert,"%hasShadowMap5%",(variantFlag & SHADER_VARIANT_SHADOW5)?"1":"0"); searchAndReplace(lightFrag,"%hasShadowMap6%",(variantFlag & SHADER_VARIANT_SHADOW6)?"1":"0"); searchAndReplace(lightVert,"%hasShadowMap6%",(variantFlag & SHADER_VARIANT_SHADOW6)?"1":"0"); searchAndReplace(lightFrag,"%hasShadowMap7%",(variantFlag & SHADER_VARIANT_SHADOW7)?"1":"0"); searchAndReplace(lightVert,"%hasShadowMap7%",(variantFlag & SHADER_VARIANT_SHADOW7)?"1":"0"); searchAndReplace(lightFrag,"%hasReflectionMap%",(variantFlag & SHADER_VARIANT_REFLECTION)?"1":"0"); searchAndReplace(lightVert,"%hasReflectionMap%",(variantFlag & SHADER_VARIANT_REFLECTION)?"1":"0"); searchAndReplace(lightFrag,"%hasEnvSphereMap%",(variantFlag & SHADER_VARIANT_ENVSPHEREMAP)?"1":"0"); searchAndReplace(lightVert,"%hasEnvSphereMap%",(variantFlag & SHADER_VARIANT_ENVSPHEREMAP)?"1":"0"); searchAndReplace(lightFrag,"%hasLightMap%",(variantFlag & SHADER_VARIANT_LIGHTMAP)?"1":"0"); searchAndReplace(lightVert,"%hasLightMap%",(variantFlag & SHADER_VARIANT_LIGHTMAP)?"1":"0"); searchAndReplace(lightFrag,"%hasParallaxMap%",(variantFlag & SHADER_VARIANT_PARALLAX)?"1":"0"); searchAndReplace(lightVert,"%hasParallaxMap%",(variantFlag & SHADER_VARIANT_PARALLAX)?"1":"0"); if (isMultiLight) { std::vector<unsigned int> loopStarts; std::vector<unsigned int> loopEnds; for (int i = 0; i < MAX_LIGHTS; i++) { GLShader *tmpShader = new GLShader(); std::string thisFrag; std::string thisVert; std::vector<std::string> lightVertLoops; std::vector<std::string> lightFragLoops; std::vector<std::string> lightVertLoopsAccum; std::vector<std::string> lightFragLoopsAccum; std::vector<unsigned int> startFragLoops; std::vector<unsigned int> endFragLoops; std::vector<unsigned int> startVertLoops; std::vector<unsigned int> endVertLoops; // printf("finding loops.."); findLoops(lightVert,lightLoopStartToken,lightLoopEndToken,startVertLoops,endVertLoops); findLoops(lightFrag,lightLoopStartToken,lightLoopEndToken,startFragLoops,endFragLoops); // printf("done.\n"); if (startVertLoops.size() != endVertLoops.size()) { Logger::log(LOG_ERROR,"Error multilight type %d: Mismatched vertex shader light loop scopes\n",lightType); return false; } if (startFragLoops.size() != endFragLoops.size()) { Logger::log(LOG_ERROR,"Error multilight type %d: Mismatched fragment shader light loop scopes\n",lightType); return false; } lightFragLoops.resize(startFragLoops.size()); lightVertLoops.resize(startVertLoops.size()); lightFragLoopsAccum.resize(startFragLoops.size()); lightVertLoopsAccum.resize(startVertLoops.size()); thisFrag.append(lightFrag); thisVert.append(lightVert); int numVertLoops = startVertLoops.size(); int numFragLoops = startFragLoops.size(); for (int j = 0; j < numVertLoops; j++) { lightVertLoops[j].append(lightVert.substr(startVertLoops[j], endVertLoops[j]-startVertLoops[j]+lightLoopEndTokenLen)); // printf("lightVertLoops %d: %s\n\n",j,lightVertLoops[j].c_str()); for (int k = 0; k <= i; k++) { std::string thisVertLoop; thisVertLoop.append(lightVert.substr(startVertLoops[j]+lightLoopStartTokenLen, endVertLoops[j]-startVertLoops[j]-lightLoopStartTokenLen)); searchAndReplace(thisVertLoop,lightIdToken,lightIds[k]); // printf("thisVertLoop %d: %s\n\n",j,thisVertLoop.c_str()); lightVertLoopsAccum[j].append(thisVertLoop); } // printf("lightVertLoopsAccum %d: %s\n\n",j,lightVertLoopsAccum[j].c_str()); } for (int j = 0; j < numFragLoops; j++) { lightFragLoops[j].append(lightFrag.substr(startFragLoops[j], endFragLoops[j]-startFragLoops[j]+lightLoopEndTokenLen)); // printf("lightFragLoops %d: %s\n\n",j,lightFragLoops[j].c_str()); for (int k = 0; k <= i; k++) { std::string thisFragLoop; thisFragLoop.append(lightFrag.substr(startFragLoops[j]+lightLoopStartTokenLen, endFragLoops[j]-startFragLoops[j]-lightLoopStartTokenLen)); searchAndReplace(thisFragLoop,lightIdToken,lightIds[k]); lightFragLoopsAccum[j].append(thisFragLoop); // printf("lightFragLoop %d: %s\n\n",j,thisFragLoop.c_str()); } // printf("lightFragLoopsAccum %d: %s\n\n",j,lightFragLoopsAccum[j].c_str()); } for (int j = 0; j < numFragLoops; j++) { searchAndReplace(thisFrag,lightFragLoops[j].c_str(),lightFragLoopsAccum[j].c_str()); } for (int j = 0; j < numVertLoops; j++) { searchAndReplace(thisVert,lightVertLoops[j].c_str(),lightVertLoopsAccum[j].c_str()); } //printf("building variant light shader %d, light #%d, variant flag %d\n\n",lightType,i,variantFlag); if (!tmpShader->setup(thisVert.c_str(),thisFrag.c_str(),NULL)) { //printf("light shader variant build failure.\n\n"); return false; } lightShader[lightType][variantFlag].push_back(tmpShader); } } else { for (int i = 0; i < MAX_LIGHTS; i++) { GLShader *tmpShader = new GLShader(); std::string thisFrag; std::string thisVert; thisFrag.append(lightFrag); thisVert.append(lightVert); searchAndReplace(thisFrag,lightIdToken,lightIds[i]); searchAndReplace(thisVert,lightIdToken,lightIds[i]); //printf("building variant light shader %d, light #%d, variant flag %d\n\n",lightType,i,variantFlag); if (!tmpShader->setup(thisVert.c_str(),thisFrag.c_str(),NULL)) { //printf("light shader variant build failure.\n\n"); return false; } lightShader[lightType][variantFlag].push_back(tmpShader); } } return true; }
CGFlow::CGFlow( CGAsmSeq &t_assem ):assem(t_assem){ buildFlow(); findLoops(); _flows.push_back( this ); }