/// <summary> /// /// </summary> /// <param name="stream"></param> /// <param name="shader"></param> protected void ParseNewShaderPass(StreamReader stream, Quake3Shader shader) { string line; var pass = new ShaderPass(); // Default pass details pass.animNumFrames = 0; pass.blend = LayerBlendOperation.Replace; pass.blendDest = SceneBlendFactor.Zero; pass.blendSrc = SceneBlendFactor.One; pass.depthFunc = CompareFunction.LessEqual; pass.flags = 0; pass.rgbGenFunc = ShaderGen.Identity; pass.tcModRotate = 0; pass.tcModScale[0] = pass.tcModScale[1] = 1.0f; pass.tcModScroll[0] = pass.tcModScroll[1] = 0.0f; pass.tcModStretchWave = ShaderWaveType.None; pass.tcModTransform[0] = pass.tcModTransform[1] = 0.0f; pass.tcModTurbOn = false; pass.tcModTurb[0] = pass.tcModTurb[1] = pass.tcModTurb[2] = pass.tcModTurb[3] = 0.0f; pass.texGen = ShaderTextureGen.Base; pass.addressMode = TextureAddressing.Wrap; pass.customBlend = false; pass.alphaVal = 0; pass.alphaFunc = CompareFunction.AlwaysPass; shader.Pass.Add(pass); while ((line = stream.ReadLine()) != null) { line = line.Trim(); // Ignore comments & blanks if ((line != String.Empty) && !line.StartsWith("//")) { if (line == "}") { return; } else { ParseShaderPassAttrib(line, shader, pass); } } } }
protected void ParseShaderPassAttrib(string line, Quake3Shader shader, ShaderPass pass) { string[] attribParams = line.Split(' ', '\t'); attribParams[0] = attribParams[0].ToLower(); LogManager.Instance.Write("Attrib {0}", attribParams[0]); if((attribParams[0] != "map") && (attribParams[0] != "clampmap") && (attribParams[0] != "animmap")) { // lower case all except textures for (int i = 1; i < attribParams.Length; i++) { attribParams[i] = attribParams[i].ToLower(); } } // MAP if(attribParams[0] == "map") { pass.textureName = attribParams[1]; if (attribParams[1].ToLower() == "$lightmap") { pass.texGen = ShaderTextureGen.Lightmap; } } // CLAMPMAP else if(attribParams[0] == "clampmap") { pass.textureName = attribParams[1]; if(attribParams[1].ToLower() == "$lightmap") pass.texGen = ShaderTextureGen.Lightmap; pass.addressMode = TextureAddressing.Clamp; } // ANIMMAP else if(attribParams[0] == "animmap") { pass.animFps = StringConverter.ParseFloat(attribParams[1]); pass.animNumFrames = attribParams.Length - 2; for(uint frame = 0; frame < pass.animNumFrames; frame++) pass.frames[frame] = attribParams[frame + 2]; } // BLENDFUNC else if(attribParams[0] == "blendfunc") { if((attribParams[1] == "add") || (attribParams[1] == "gl_add")) { pass.blend = LayerBlendOperation.Add; pass.blendDest = SceneBlendFactor.One; pass.blendSrc = SceneBlendFactor.One; } else if((attribParams[1] == "filter") || (attribParams[1] == "gl_filter")) { pass.blend = LayerBlendOperation.Modulate; pass.blendDest = SceneBlendFactor.Zero; pass.blendSrc = SceneBlendFactor.DestColor; } else if((attribParams[1] == "blend") || (attribParams[1] == "gl_blend")) { pass.blend = LayerBlendOperation.AlphaBlend; pass.blendDest = SceneBlendFactor.OneMinusSourceAlpha; pass.blendSrc = SceneBlendFactor.SourceAlpha; } else { // Manual blend pass.blendSrc = ConvertBlendFunc(attribParams[1]); pass.blendDest = ConvertBlendFunc(attribParams[2]); // Detect common blends if((pass.blendSrc == SceneBlendFactor.One) && (pass.blendDest == SceneBlendFactor.Zero)) pass.blend = LayerBlendOperation.Replace; else if((pass.blendSrc == SceneBlendFactor.One) && (pass.blendDest == SceneBlendFactor.One)) pass.blend = LayerBlendOperation.Add; else if(((pass.blendSrc == SceneBlendFactor.Zero) && (pass.blendDest == SceneBlendFactor.SourceColor)) || ((pass.blendSrc == SceneBlendFactor.DestColor) && (pass.blendDest == SceneBlendFactor.Zero))) pass.blend = LayerBlendOperation.Modulate; else if((pass.blendSrc == SceneBlendFactor.SourceAlpha) && (pass.blendDest == SceneBlendFactor.OneMinusSourceAlpha)) pass.blend = LayerBlendOperation.AlphaBlend; else pass.customBlend = true; // NB other custom blends might not work due to OGRE trying to use multitexture over multipass } } // RGBGEN else if(attribParams[0] == "rgbgen") { // TODO } // ALPHAGEN else if(attribParams[0] == "alphagen") { // TODO } // TCGEN else if(attribParams[0] == "tcgen") { if(attribParams[1] == "base") pass.texGen = ShaderTextureGen.Base; else if(attribParams[1] == "lightmap") pass.texGen = ShaderTextureGen.Lightmap; else if(attribParams[1] == "environment") pass.texGen = ShaderTextureGen.Environment; } // TCMOD else if(attribParams[0] == "tcmod") { if(attribParams[1] == "rotate") { pass.tcModRotate = -StringConverter.ParseFloat(attribParams[2]) / 360; // +ve is clockwise degrees in Q3 shader, anticlockwise complete rotations in Ogre } else if(attribParams[1] == "scroll") { pass.tcModScroll[0] = StringConverter.ParseFloat(attribParams[2]); pass.tcModScroll[1] = StringConverter.ParseFloat(attribParams[3]); } else if(attribParams[1] == "scale") { pass.tcModScale[0] = StringConverter.ParseFloat(attribParams[2]); pass.tcModScale[1] = StringConverter.ParseFloat(attribParams[3]); } else if(attribParams[1] == "stretch") { if(attribParams[2] == "sin") pass.tcModStretchWave = ShaderWaveType.Sin; else if(attribParams[2] == "triangle") pass.tcModStretchWave = ShaderWaveType.Triangle; else if(attribParams[2] == "square") pass.tcModStretchWave = ShaderWaveType.Square; else if(attribParams[2] == "sawtooth") pass.tcModStretchWave = ShaderWaveType.SawTooth; else if(attribParams[2] == "inversesawtooth") pass.tcModStretchWave = ShaderWaveType.InverseSawtooth; pass.tcModStretchParams[0] = StringConverter.ParseFloat(attribParams[3]); pass.tcModStretchParams[1] = StringConverter.ParseFloat(attribParams[4]); pass.tcModStretchParams[2] = StringConverter.ParseFloat(attribParams[5]); pass.tcModStretchParams[3] = StringConverter.ParseFloat(attribParams[6]); } } // TURB else if(attribParams[0] == "turb") { pass.tcModTurbOn = true; pass.tcModTurb[0] = StringConverter.ParseFloat(attribParams[2]); pass.tcModTurb[1] = StringConverter.ParseFloat(attribParams[3]); pass.tcModTurb[2] = StringConverter.ParseFloat(attribParams[4]); pass.tcModTurb[3] = StringConverter.ParseFloat(attribParams[5]); } // DEPTHFUNC else if(attribParams[0] == "depthfunc") { // TODO } // DEPTHWRITE else if(attribParams[0] == "depthwrite") { // TODO } // ALPHAFUNC else if(attribParams[0] == "alphafunc") { if(attribParams[1] == "gt0") { pass.alphaVal = 0; pass.alphaFunc = CompareFunction.Greater; } else if(attribParams[1] == "ge128") { pass.alphaVal = 128; pass.alphaFunc = CompareFunction.GreaterEqual; } else if(attribParams[1] == "lt128") { pass.alphaVal = 128; pass.alphaFunc = CompareFunction.Less; } } }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="shader"></param> /// <param name="pass"></param> protected void ParseShaderPassAttrib(string line, Quake3Shader shader, ShaderPass pass) { string[] attribParams = line.Split(' ', '\t'); attribParams[0] = attribParams[0].ToLower(); LogManager.Instance.Write("Attrib {0}", attribParams[0]); if ((attribParams[0] != "map") && (attribParams[0] != "clampmap") && (attribParams[0] != "animmap")) { // lower case all except textures for (int i = 1; i < attribParams.Length; ++i) { attribParams[i] = attribParams[i].ToLower(); } } // MAP if (attribParams[0] == "map") { pass.textureName = attribParams[1]; if (attribParams[1].ToLower() == "$lightmap") { pass.texGen = ShaderTextureGen.Lightmap; } } // CLAMPMAP else if (attribParams[0] == "clampmap") { pass.textureName = attribParams[1]; if (attribParams[1].ToLower() == "$lightmap") { pass.texGen = ShaderTextureGen.Lightmap; } pass.addressMode = TextureAddressing.Clamp; } // ANIMMAP else if (attribParams[0] == "animmap") { pass.animFps = StringConverter.ParseFloat(attribParams[1]); pass.animNumFrames = attribParams.Length - 2; for (uint frame = 0; frame < pass.animNumFrames; ++frame) { pass.frames[frame] = attribParams[frame + 2]; } } // BLENDFUNC else if (attribParams[0] == "blendfunc") { if ((attribParams[1] == "add") || (attribParams[1] == "gl_add")) { pass.blend = LayerBlendOperation.Add; pass.blendDest = SceneBlendFactor.One; pass.blendSrc = SceneBlendFactor.One; } else if ((attribParams[1] == "filter") || (attribParams[1] == "gl_filter")) { pass.blend = LayerBlendOperation.Modulate; pass.blendDest = SceneBlendFactor.Zero; pass.blendSrc = SceneBlendFactor.DestColor; } else if ((attribParams[1] == "blend") || (attribParams[1] == "gl_blend")) { pass.blend = LayerBlendOperation.AlphaBlend; pass.blendDest = SceneBlendFactor.OneMinusSourceAlpha; pass.blendSrc = SceneBlendFactor.SourceAlpha; } else { // Manual blend pass.blendSrc = ConvertBlendFunc(attribParams[1]); pass.blendDest = ConvertBlendFunc(attribParams[2]); // Detect common blends if ((pass.blendSrc == SceneBlendFactor.One) && (pass.blendDest == SceneBlendFactor.Zero)) { pass.blend = LayerBlendOperation.Replace; } else if ((pass.blendSrc == SceneBlendFactor.One) && (pass.blendDest == SceneBlendFactor.One)) { pass.blend = LayerBlendOperation.Add; } else if (((pass.blendSrc == SceneBlendFactor.Zero) && (pass.blendDest == SceneBlendFactor.SourceColor)) || ((pass.blendSrc == SceneBlendFactor.DestColor) && (pass.blendDest == SceneBlendFactor.Zero))) { pass.blend = LayerBlendOperation.Modulate; } else if ((pass.blendSrc == SceneBlendFactor.SourceAlpha) && (pass.blendDest == SceneBlendFactor.OneMinusSourceAlpha)) { pass.blend = LayerBlendOperation.AlphaBlend; } else { pass.customBlend = true; } // NB other custom blends might not work due to OGRE trying to use multitexture over multipass } } // RGBGEN else if (attribParams[0] == "rgbgen") { // TODO } // ALPHAGEN else if (attribParams[0] == "alphagen") { // TODO } // TCGEN else if (attribParams[0] == "tcgen") { if (attribParams[1] == "base") { pass.texGen = ShaderTextureGen.Base; } else if (attribParams[1] == "lightmap") { pass.texGen = ShaderTextureGen.Lightmap; } else if (attribParams[1] == "environment") { pass.texGen = ShaderTextureGen.Environment; } } // TCMOD else if (attribParams[0] == "tcmod") { if (attribParams[1] == "rotate") { pass.tcModRotate = -StringConverter.ParseFloat(attribParams[2]) / 360; // +ve is clockwise degrees in Q3 shader, anticlockwise complete rotations in Ogre } else if (attribParams[1] == "scroll") { pass.tcModScroll[0] = StringConverter.ParseFloat(attribParams[2]); pass.tcModScroll[1] = StringConverter.ParseFloat(attribParams[3]); } else if (attribParams[1] == "scale") { pass.tcModScale[0] = StringConverter.ParseFloat(attribParams[2]); pass.tcModScale[1] = StringConverter.ParseFloat(attribParams[3]); } else if (attribParams[1] == "stretch") { if (attribParams[2] == "sin") { pass.tcModStretchWave = ShaderWaveType.Sin; } else if (attribParams[2] == "triangle") { pass.tcModStretchWave = ShaderWaveType.Triangle; } else if (attribParams[2] == "square") { pass.tcModStretchWave = ShaderWaveType.Square; } else if (attribParams[2] == "sawtooth") { pass.tcModStretchWave = ShaderWaveType.SawTooth; } else if (attribParams[2] == "inversesawtooth") { pass.tcModStretchWave = ShaderWaveType.InverseSawtooth; } pass.tcModStretchParams[0] = StringConverter.ParseFloat(attribParams[3]); pass.tcModStretchParams[1] = StringConverter.ParseFloat(attribParams[4]); pass.tcModStretchParams[2] = StringConverter.ParseFloat(attribParams[5]); pass.tcModStretchParams[3] = StringConverter.ParseFloat(attribParams[6]); } } // TURB else if (attribParams[0] == "turb") { pass.tcModTurbOn = true; pass.tcModTurb[0] = StringConverter.ParseFloat(attribParams[2]); pass.tcModTurb[1] = StringConverter.ParseFloat(attribParams[3]); pass.tcModTurb[2] = StringConverter.ParseFloat(attribParams[4]); pass.tcModTurb[3] = StringConverter.ParseFloat(attribParams[5]); } // DEPTHFUNC else if (attribParams[0] == "depthfunc") { // TODO } // DEPTHWRITE else if (attribParams[0] == "depthwrite") { // TODO } // ALPHAFUNC else if (attribParams[0] == "alphafunc") { if (attribParams[1] == "gt0") { pass.alphaVal = 0; pass.alphaFunc = CompareFunction.Greater; } else if (attribParams[1] == "ge128") { pass.alphaVal = 128; pass.alphaFunc = CompareFunction.GreaterEqual; } else if (attribParams[1] == "lt128") { pass.alphaVal = 128; pass.alphaFunc = CompareFunction.Less; } } }
protected void ParseNewShaderPass(StreamReader stream, Quake3Shader shader) { string line; ShaderPass pass = new ShaderPass(); // Default pass details pass.animNumFrames = 0; pass.blend = LayerBlendOperation.Replace; pass.blendDest = SceneBlendFactor.Zero; pass.depthFunc = CompareFunction.LessEqual; pass.flags = 0; pass.rgbGenFunc = ShaderGen.Identity; pass.tcModRotate = 0; pass.tcModScale[0] = pass.tcModScale[1] = 1.0f; pass.tcModScroll[0] = pass.tcModScroll[1] = 0.0f; pass.tcModStretchWave = ShaderWaveType.None; pass.tcModTransform[0] = pass.tcModTransform[1] = 0.0f; pass.tcModTurbOn = false; pass.tcModTurb[0] = pass.tcModTurb[1] = pass.tcModTurb[2] = pass.tcModTurb[3] = 0.0f; pass.texGen = ShaderTextureGen.Base; pass.addressMode = TextureAddressing.Wrap; pass.customBlend = false; pass.alphaVal = 0; pass.alphaFunc = CompareFunction.AlwaysPass; shader.Pass.Add(pass); while((line = stream.ReadLine()) != null) { line = line.Trim(); // Ignore comments & blanks if((line != String.Empty) && !line.StartsWith("//")) { if(line == "}") return; else ParseShaderPassAttrib(line, shader, pass); } } }