public static shader_t parseShader(String name, ShaderTokenizer tokens) { string param; String brace = tokens.next(); if (brace != "{") { return(null); } shader_t shader = new shader_t(); shader.name = name; // Parse a shader while (!tokens.EOF()) { String token = tokens.next().ToLower(); if (token == "}") { break; } switch (token) { case "{": { stage_t stage = ShaderParser.parseStage(tokens); // I really really really don't like doing this, which basically just forces lightmaps to use the 'filter' blendmode // but if I don't a lot of textures end up looking too bright. I'm sure I'm jsut missing something, and this shouldn't // be needed. if (stage.isLightmap == true && (stage.hasBlendFunc == true)) { stage.blendSrc = "GL_DST_COLOR"; stage.blendDest = "GL_ZERO"; } // I'm having a ton of trouble getting lightingSpecular to work properly, // so this little hack gets it looking right till I can figure out the problem if (stage.alphaGen == "lightingspecular") { stage.blendSrc = "GL_ONE"; stage.blendDest = "GL_ZERO"; stage.hasBlendFunc = false; stage.depthWrite = true; shader.stages = new List <stage_t>(); } if (stage.hasBlendFunc == true) { shader.blend = true; } else { shader.opaque = true; } shader.stages.Add(stage); } break; case "cull": shader.cull = tokens.next(); break; case "deformvertexes": deform_t deform = new deform_t(); deform.type = tokens.next().ToLower(); switch (deform.type) { case "wave": deform.spread = 1.0 / double.Parse(tokens.next()); deform.waveform = ShaderParser.parseWaveform(tokens); break; default: deform = null; break; } if (deform != null) { shader.vertexDeforms.Add(deform); } break; case "sort": String sort = tokens.next().ToLower(); switch (sort) { case "portal": shader.sort = 1; break; case "sky": shader.sort = 2; break; case "opaque": shader.sort = 3; break; case "banner": shader.sort = 6; break; case "underwater": shader.sort = 8; break; case "additive": shader.sort = 9; break; case "nearest": shader.sort = 16; break; default: shader.sort = int.Parse(sort); break; } ; break; case "surfaceparm": param = tokens.next().ToLower(); switch (param) { case "sky": shader.sky = true; break; default: break; } break; case "skyparms": param = tokens.next().ToLower(); shader.sky_env_map = new sky_env_map_p(param);; break; default: break; } } if (shader.sort < 0 || shader.sort == 0) { shader.sort = (shader.opaque ? 3 : 9); } //if(!shader['sort']) { //shader['sort'] = (shader['opaque'] ? 3 : 9); //} return(shader); }
public static stage_t parseStage(ShaderTokenizer tokens) { stage_t stage = new stage_t(); String map; // Parse a shader while (!tokens.EOF()) { String token = tokens.next(); if (token == "}") { break; } switch (token.ToLower()) { case "clampmap": stage.clamp = true; break; case "map": map = tokens.next(); if (!Config.preserve_tga_images) { //Regex r; //r = new Regex("(\\.jpg|\\.tga)"); map = map.Replace(".tga", ".jpg"); //map = r.Replace(map, ".jpg"); //map = map.replaceAll(new RegExp(r'(\.jpg|\.tga)'), '.jpg'); } stage.map = map; //stage.map = tokens.next().replaceAll(/(\.jpg|\.tga)/, '.jpg'); break; case "animmap": stage.map = "anim"; stage.animFreq = double.Parse(tokens.next()); String nextMap = tokens.next(); while (nextMap.Contains(".tga") || nextMap.Contains(".jpg")) //while(nextMap.match(/(\.jpg|\.tga)/)) { map = nextMap; if (!Config.preserve_tga_images) { map = map.Replace(".tga", ".jpg"); //map = nextMap.replaceAll(new RegExp(r'(\.jpg|\.tga)'), '.jpg'); } // stage.animMaps.Add(map); //stage.animMaps.push(nextMap.replace(/(\.jpg|\.tga)/, '.jpg')); nextMap = tokens.next(); } tokens.prev(); break; case "rgbgen": stage.rgbGen = tokens.next().ToLower();; switch (stage.rgbGen) { case "wave": stage.rgbWaveform = ShaderParser.parseWaveform(tokens); if (stage.rgbWaveform == null) { stage.rgbGen = "identity"; } break; } ; break; case "alphagen": stage.alphaGen = tokens.next().ToLower(); switch (stage.alphaGen) { case "wave": stage.alphaWaveform = ShaderParser.parseWaveform(tokens); if (stage.alphaWaveform == null) { stage.alphaGen = "1.0"; } break; default: break; } ; break; case "alphafunc": stage.alphaFunc = tokens.next().ToUpper(); break; case "blendfunc": stage.blendSrc = tokens.next(); stage.hasBlendFunc = true; if (stage.depthWriteOverride == false) { stage.depthWrite = false; } switch (stage.blendSrc) { case "add": stage.blendSrc = "GL_ONE"; stage.blendDest = "GL_ONE"; break; case "blend": stage.blendSrc = "GL_SRC_ALPHA"; stage.blendDest = "GL_ONE_MINUS_SRC_ALPHA"; break; case "filter": stage.blendSrc = "GL_DST_COLOR"; stage.blendDest = "GL_ZERO"; break; default: stage.blendDest = tokens.next(); break; } break; case "depthfunc": stage.depthFunc = tokens.next().ToLower(); break; case "depthwrite": stage.depthWrite = true; stage.depthWriteOverride = true; break; case "tcmod": tcMod_t tcMod = new tcMod_t(); tcMod.type = tokens.next().ToLower(); switch (tcMod.type) { case "rotate": tcMod.angle = double.Parse(tokens.next()) * (Math.PI / 180); break; case "scale": tcMod.scaleX = double.Parse(tokens.next()); tcMod.scaleY = double.Parse(tokens.next()); break; case "scroll": tcMod.sSpeed = double.Parse(tokens.next()); tcMod.tSpeed = double.Parse(tokens.next()); break; case "stretch": tcMod.waveform = ShaderParser.parseWaveform(tokens); if (tcMod.waveform == null) { tcMod.type = null; } break; case "turb": tcMod.turbulance = new turbulance_t(); tcMod.turbulance.@base = double.Parse(tokens.next()); tcMod.turbulance.amp = double.Parse(tokens.next()); tcMod.turbulance.phase = double.Parse(tokens.next()); tcMod.turbulance.freq = double.Parse(tokens.next()); break; default: tcMod.type = null; break; } if (tcMod.type != null) { stage.tcMods.Add(tcMod); } break; case "tcgen": stage.tcGen = tokens.next(); break; default: break; } } if (stage.blendSrc == "GL_ONE" && stage.blendDest == "GL_ZERO") { stage.hasBlendFunc = false; stage.depthWrite = true; } stage.isLightmap = stage.map == "\\$lightmap"; return(stage); }