private static List <string> BuildEffectState(QShaderData shader, QShaderStage qstage)
        {
            var StateLines = new List <string>();

            StateLines.Add("AlphaBlendEnable = " + qstage.HasBlendFunc.ToString().ToLower() + ";");
            StateLines.Add("SrcBlend = " + GLtoDXBlend(qstage.BlendSrc) + ";");
            StateLines.Add("DestBlend = " + GLtoDXBlend(qstage.BlendDest) + ";");
            //StateLines.Add("ZWriteEnable = " + (!qstage.HasBlendFunc).ToString().ToLower() + ";");
            if (!shader.Cull.Equals(""))
            {
                if (shader.Cull.ToLower().Equals("disable"))
                {
                    shader.Cull = "None";
                }
                StateLines.Add("CullMode = " + shader.Cull + ";");
            }

            return(StateLines);
        }
        private static QShaderStage ParseStage(QShaderTokenizer tokenizer)
        {
            var stage = new QShaderStage();

            // Parse a Stage
            while (!tokenizer.EOF)
            {
                var token = tokenizer.GetNext();
                if (token.Equals("}"))
                {
                    break;
                }

                switch (token.ToLower())
                {
                case "clampmap":
                    stage.Clamp = true;
                    goto case "map";

                case "map":
                    stage.Map = tokenizer.GetNext();     //.replace()/(\.jpg|\.tga)/, '.png');
                    break;

                case "animmap":
                    stage.Map      = "anim";
                    stage.AnimFreq = ParserTools.ToFloat(tokenizer.GetNext());
                    var nextMap = tokenizer.GetNext();
                    var match   = Regex.Match(nextMap, @"(\.jpg|\.tga)");
                    while (match.Success)
                    {
                        stage.AnimMaps.Add(nextMap);
                        nextMap = tokenizer.GetNext();
                        match   = Regex.Match(nextMap, @"(\.jpg|\.tga)");
                    }
                    tokenizer.MovePrev();
                    break;

                case "rgbgen":
                    stage.RgbGen = tokenizer.GetNext().ToLower();
                    switch (stage.RgbGen)
                    {
                    case "wave":
                        stage.RgbWaveform = ParseWaveform(tokenizer);
                        if (stage.RgbWaveform == null)
                        {
                            stage.RgbGen = "identity";
                        }
                        break;
                    }
                    ;
                    break;

                case "alphagen":
                    stage.AlphaGen = tokenizer.GetNext().ToLower();
                    switch (stage.AlphaGen)
                    {
                    case "wave":
                        stage.AlphaWaveform = ParseWaveform(tokenizer);
                        if (stage.AlphaWaveform == null)
                        {
                            stage.AlphaGen = "1.0";
                        }
                        break;

                    default:
                        break;
                    }
                    break;

                case "alphafunc":
                    stage.AlphaFunc = tokenizer.GetNext().ToUpper();
                    break;

                case "blendfunc":
                    stage.BlendSrc     = tokenizer.GetNext();
                    stage.HasBlendFunc = true;
                    if (stage.DepthWriteOverride)
                    {
                        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 = tokenizer.GetNext();
                        break;
                    }
                    break;

                case "depthfunc":
                    stage.DepthFunc = tokenizer.GetNext().ToLower();
                    break;

                case "depthwrite":
                    stage.DepthWrite         = true;
                    stage.DepthWriteOverride = true;
                    break;

                case "tcmod":
                    var tcMod = new QTcMod
                    {
                        Type = tokenizer.GetNext().ToLower()
                    };

                    switch (tcMod.Type)
                    {
                    case "rotate":
                        tcMod.Angle = Geometry.DegreeToRadian(ParserTools.ToFloat(tokenizer.GetNext()));
                        break;

                    case "scale":
                        tcMod.ScaleX = ParserTools.ToFloat(tokenizer.GetNext());
                        tcMod.ScaleY = ParserTools.ToFloat(tokenizer.GetNext());
                        break;

                    case "scroll":
                        tcMod.SSpeed = ParserTools.ToFloat(tokenizer.GetNext());
                        tcMod.TSpeed = ParserTools.ToFloat(tokenizer.GetNext());
                        break;

                    case "stretch":
                        tcMod.WaveForm = ParseWaveform(tokenizer);
                        if (tcMod.WaveForm == null)
                        {
                            tcMod.Type = "";
                        }
                        break;

                    case "turb":
                        tcMod.Turbulance = new QWaveForm
                        {
                            Name = char.IsLetter(tokenizer.GetToken()[0])
                                        ? tokenizer.GetNext()
                                        : "",
                            Bas   = ParserTools.ToFloat(tokenizer.GetNext()),
                            Amp   = ParserTools.ToFloat(tokenizer.GetNext()),
                            Phase = ParserTools.ToFloat(tokenizer.GetNext()),
                            Freq  = ParserTools.ToFloat(tokenizer.GetNext())
                        };
                        break;

                    default:
                        tcMod.Type = "";
                        break;
                    }
                    if (!tcMod.Type.Equals(""))
                    {
                        stage.TcMods.Add(tcMod);
                    }
                    break;

                case "tcgen":
                    stage.TcGen = tokenizer.GetNext();
                    break;

                default:
                    break;
                }
            }

            if (stage.BlendSrc.Equals("GL_ONE") && stage.BlendDest.Equals("GL_ZERO"))
            {
                stage.HasBlendFunc = false;
                stage.DepthWrite   = true;
            }

            return(stage);
        }
        private static List <string> BuildVertexShader(QShaderData shader, QShaderStage stage)
        {
            var VertexLines = new List <string>();

            VertexLines.Add("PSInput Out = In;");
            VertexLines.Add("float4 defPosition = In.Pos;");

            for (var i = 0; i < shader.VertexDeforms.Count; ++i)
            {
                var deform = shader.VertexDeforms[i];

                switch (deform.Type)
                {
                case "wave":
                {
                    var name    = "deform" + i;
                    var offName = "deformOff" + i;

                    VertexLines.Add(
                        "float " + offName + " = (In.Pos.x + In.Pos.y + In.Pos.z) * " +
                        ParserTools.ToString(deform.Spread) + ";");

                    /*float phase = deform.WaveForm.Phase;
                     *          //deform.WaveForm.Phase = phase.toFixed(4) + ' + ' + offName; <-----MIRAR ESTA LINEA
                     *          VertexLines.Add(CreateWaveForm(name, deform.WaveForm, "g_time"));
                     *          deform.WaveForm.Phase = phase;*/

                    //Parche temporal solo funciona con la funcion seno
                    VertexLines.Add("float " + name + " = " + ParserTools.ToString(deform.WaveForm.Bas) + " + sin((" +
                                    ParserTools.ToString(deform.WaveForm.Phase) + " + " +
                                    "g_time" + " * " + ParserTools.ToString(deform.WaveForm.Freq) + " + " + offName +
                                    ") * 6.283) * " + ParserTools.ToString(deform.WaveForm.Amp) + ";");
                    //FIN parche

                    VertexLines.Add("defPosition += float4(In.Normal * " + name + ",0);");
                }
                break;

                case "bulge":
                {
                    //float alpha = In.Tex0.x*bulgeWidth + g_time;
                    //float deform = sin(alpha)*bulgeHeight;
                    //defPosition += float4(In.Normal * deform0, 0);

                    var deformi = "deform" + i;
                    var alphai  = "alpha" + i;

                    VertexLines.Add("float " + alphai + " = In.Tex0.x*" + deform.BulgeWidth + " + g_time*" +
                                    deform.BulgeSpeed + ";");
                    VertexLines.Add("float " + deformi + " = sin(" + alphai + ")*" + deform.BulgeHeight + ";");
                    VertexLines.Add("defPosition += float4(In.Normal * " + deformi + ",0);");
                }
                break;

                default:
                    break;
                }
            }

            VertexLines.Add("float4 worldPosition = mul( defPosition, g_mWorld );");
            VertexLines.Add("Out.Color = In.Color;");

            if (stage.TcGen.Equals("environment"))
            {
                VertexLines.Add("float3 viewer = normalize(-worldPosition.xyz);");
                VertexLines.Add("float d = dot(In.Normal, viewer);");
                VertexLines.Add("float3 reflected = In.Normal*2.0*d - viewer;");
                VertexLines.Add("Out.Tex0 = float2(0.5, 0.5) + reflected.xy * 0.5;");
            }
            else
            {
                // Standard texturing
                VertexLines.Add("Out.Tex0 = In.Tex0;");
            }

            // tcMods
            for (var i = 0; i < stage.TcMods.Count; ++i)
            {
                var tcMod = stage.TcMods[i];

                switch (tcMod.Type)
                {
                case "rotate":
                    VertexLines.Add("float r = " + ParserTools.ToString(tcMod.Angle) + " * g_time;");
                    VertexLines.Add("Out.Tex0 -= float2(0.5, 0.5);");
                    VertexLines.Add(
                        "Out.Tex0 = float2(Out.Tex0.x * cos(r) - Out.Tex0.y * sin(r), Out.Tex0.y * cos(r) + Out.Tex0.x * sin(r));");
                    VertexLines.Add("Out.Tex0 += float2(0.5, 0.5);");
                    break;

                case "scroll":
                    VertexLines.Add(
                        "Out.Tex0 += float2(" + ParserTools.ToString(tcMod.SSpeed) + " * g_time, " +
                        ParserTools.ToString(tcMod.TSpeed) +
                        " * g_time);");
                    break;

                case "scale":
                    VertexLines.Add(
                        "Out.Tex0 *= float2(" + ParserTools.ToString(tcMod.ScaleX) + ", " +
                        ParserTools.ToString(tcMod.ScaleY) + ");"
                        );
                    break;

                case "stretch":
                    VertexLines.Add(CreateWaveForm("stretchWave", tcMod.WaveForm, ""));
                    VertexLines.Add("stretchWave = 1.0 / stretchWave;");
                    VertexLines.Add("Out.Tex0 *= stretchWave;");
                    VertexLines.Add("Out.Tex0 += float2(0.5 - (0.5 * stretchWave), 0.5 - (0.5 * stretchWave));");
                    break;

                case "turb":
                    var tName = "turbTime" + i;
                    VertexLines.Add("float " + tName + " = " + ParserTools.ToString(tcMod.Turbulance.Phase) +
                                    " + g_time * " +
                                    ParserTools.ToString(tcMod.Turbulance.Freq) + ";");
                    VertexLines.Add("Out.Tex0.x += sin( ( ( In.Pos.x + In.Pos.z )* 1.0/128.0 * 0.125 + " + tName +
                                    " ) * 6.283) * " + ParserTools.ToString(tcMod.Turbulance.Amp) + ";");
                    VertexLines.Add("Out.Tex0.y += sin( ( In.Pos.y * 1.0/128.0 * 0.125 + " + tName +
                                    " ) * 6.283) * " +
                                    ParserTools.ToString(tcMod.Turbulance.Amp) + ";");
                    break;

                default:
                    break;
                }
            }

            switch (stage.AlphaGen)
            {
            case "lightingspecular":
                VertexLines.Add("Out.Tex1 = In.Tex1;");
                break;

            default:
                break;
            }

            VertexLines.Add("Out.Pos = mul(worldPosition, g_mViewProj);");
            VertexLines.Add("return Out;");

            return(VertexLines);
        }
        private static List <string> BuildPixelShader(QShaderData shader, QShaderStage stage)
        {
            var PixelLines = new List <string>();

            PixelLines.Add("float4 texColor = tex2D(texture0, In.Tex0);");

            switch (stage.RgbGen)
            {
            case "vertex":
                PixelLines.Add("float3 rgb = texColor.rgb * In.Color.rgb;");
                break;

            case "wave":
                PixelLines.Add(CreateWaveForm("rgbWave", stage.RgbWaveform, ""));
                PixelLines.Add("float3 rgb = texColor.rgb * rgbWave;");
                break;

            default:
                PixelLines.Add("float3 rgb = texColor.rgb;");
                break;
            }

            switch (stage.AlphaGen)
            {
            case "wave":
                PixelLines.Add(CreateWaveForm("alpha", stage.AlphaWaveform, ""));
                //PixelLines.Add("alpha = sin(g_time);");
                break;

            case "lightingspecular":
                // For now this is VERY special cased. May not work well with all instances of lightingSpecular
                PixelLines.Add("float4 light = tex2D(texture1, In.Tex1);");
                PixelLines.Add("rgb *= light.rgb;");
                PixelLines.Add("rgb += light.rgb * texColor.a * 0.6;");
                // This was giving me problems, so I'm ignorning an actual specular calculation for now
                PixelLines.Add("float alpha = 1.0;");
                break;

            default:
                PixelLines.Add("float alpha = texColor.a;");
                if (!stage.AlphaGen.Equals("1.0"))
                {
                    PixelLines.Add("alpha = sin(g_time);");
                }
                //PixelLines.Add("float alpha = sin(g_time);");
                break;
            }

            if (stage.AlphaFunc != null)
            {
                switch (stage.AlphaFunc)
                {
                case "GT0":
                    PixelLines.Add("if(alpha == 0.0) { discard; }");
                    break;

                case "LT128":
                    PixelLines.Add("if(alpha >= 0.5) { discard; }");
                    break;

                case "GE128":
                    PixelLines.Add("if(alpha < 0.5) { discard; }");
                    break;

                default:
                    break;
                }
            }

            //PixelLines.Add("if(rgb.r < 0.1 && rgb.g < 0.1 && rgb.b < 0.1)");
            //PixelLines.Add("alpha = 0;");
            //PixelLines.Add("discard;");

            PixelLines.Add("return float4(rgb, alpha);");

            return(PixelLines);
        }