Пример #1
0
        public static vertex_shader_src_t buildVertexShader(shader_t stageShader, stage_t stage)
        {
            ShaderBuilder shader;
            Dictionary <string, string> attribs, varyings, uniforms;
            List <string> statements;

            shader     = new ShaderBuilder();
            attribs    = new Dictionary <string, string>();
            varyings   = new Dictionary <string, string>();
            uniforms   = new Dictionary <string, string>();
            statements = new List <string>();

            shader.addAttribs("position", "vec3");
            shader.addAttribs("normal", "vec3");
            shader.addAttribs("color", "vec4");

            shader.addVaryings("vTexCoord", "vec2");
            shader.addVaryings("vColor", "vec4");

            shader.addUniforms("modelViewMat", "mat4");
            shader.addUniforms("projectionMat", "mat4");
            shader.addUniforms("time", "float");

            if (stage.isLightmap == true)
            {
                shader.addAttribs("lightCoord", "vec2");
            }
            else
            {
                shader.addAttribs("texCoord", "vec2");
            }

            shader.addLines("vec3 defPosition = position;");

            //shader.addAttribs(attribs);
            //shader.addVaryings(varyings);
            //shader.addUniforms(uniforms);
            //shader.addLines(statements);

            for (int i = 0; i < stageShader.vertexDeforms.Count; ++i)
            {
                deform_t deform = stageShader.vertexDeforms[i];

                switch (deform.type)
                {
                case "wave":
                    String name    = "deform" + i.ToString();
                    String offName = "deformOff" + i.ToString();

                    shader.addLine("float " + offName + " = (position.x + position.y + position.z) * " + ShaderBuilder.toStringAsFixed(deform.spread, 4) + ";");

                    var phase = deform.waveform.phase;
                    deform.waveform.phase = ShaderBuilder.toStringAsFixed((double)phase, 4) + " + " + offName;
                    shader.addWaveform(name, deform.waveform, null);
                    deform.waveform.phase = phase;

                    shader.addLine("defPosition += normal * " + name + ";");
                    break;

                default: break;
                }
            }

            shader.addLine("vec4 worldPosition = modelViewMat * vec4(defPosition, 1.0);");
            shader.addLine("vColor = color;");

            if (stage.tcGen == "environment")
            {
                shader.addLines(
                    "vec3 viewer = normalize(-worldPosition.xyz);",
                    "float d = dot(normal, viewer);",
                    "vec3 reflected = normal*2.0*d - viewer;",
                    "vTexCoord = vec2(0.5, 0.5) + reflected.xy * 0.5;"
                    );
            }
            else
            {
                // Standard texturing
                if (stage.isLightmap == true)
                {
                    shader.addLines("vTexCoord = lightCoord;");
                }
                else
                {
                    shader.addLines("vTexCoord = texCoord;");
                }
            }

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

                switch (tcMod.type)
                {
                case "rotate":
                    shader.addLines(
                        string.Format("float r = {0} * time;", ShaderBuilder.toStringAsFixed(tcMod.angle, 4)),
                        "vTexCoord -= vec2(0.5, 0.5);",
                        "vTexCoord = vec2(vTexCoord.s * cos(r) - vTexCoord.t * sin(r), vTexCoord.t * cos(r) + vTexCoord.s * sin(r));",
                        "vTexCoord += vec2(0.5, 0.5);"
                        );
                    break;

                case "scroll":
                    double sSpeed = tcMod.sSpeed;     // was tcMod['sSpeed'].toFixed(4)
                    double tSpeed = tcMod.tSpeed;

                    shader.addLines(string.Format("vTexCoord += vec2({0} * time, {1} * time); ", ShaderBuilder.toStringAsFixed(sSpeed, 4), ShaderBuilder.toStringAsFixed(tSpeed, 4)));
                    break;

                case "scale":
                    double scaleX = tcMod.scaleX;
                    double scaleY = tcMod.scaleY;

                    shader.addLines("vTexCoord *= vec2(" + ShaderBuilder.toStringAsFixed(scaleX, 4) + ", " + ShaderBuilder.toStringAsFixed(scaleY, 4) + ");");
                    break;

                case "stretch":
                    shader.addWaveform("stretchWave", tcMod.waveform, null);
                    shader.addLines(
                        "stretchWave = 1.0 / stretchWave;",
                        "vTexCoord *= stretchWave;",
                        "vTexCoord += vec2(0.5 - (0.5 * stretchWave), 0.5 - (0.5 * stretchWave));"
                        );
                    break;

                case "turb":
                    String tName = "turbTime" + i.ToString();
                    shader.addLines(
                        "float " + tName + " = " + ShaderBuilder.toStringAsFixed(tcMod.turbulance.phase, 4) + " + time * " + ShaderBuilder.toStringAsFixed(tcMod.turbulance.freq, 4) + ";",
                        "vTexCoord.s += sin( ( ( position.x + position.z )* 1.0/128.0 * 0.125 + " + tName + " ) * 6.283) * " + ShaderBuilder.toStringAsFixed(tcMod.turbulance.amp, 4) + ';',
                        "vTexCoord.t += sin( ( position.y * 1.0/128.0 * 0.125 + " + tName + " ) * 6.283) * " + ShaderBuilder.toStringAsFixed(tcMod.turbulance.amp, 4) + ";"
                        );
                    break;

                default: break;
                }
            }

            switch (stage.alphaGen)
            {
            case "lightingspecular":
                shader.addAttribs("lightCoord", "vec2");
                shader.addVaryings("vLightCoord", "vec2");
                shader.addLines("vLightCoord = lightCoord;");
                break;

            default:
                break;
            }

            shader.addLines("gl_Position = projectionMat * worldPosition;");


            vertex_shader_src_t vertex_shader = new vertex_shader_src_t();

            vertex_shader.source_code = shader.getSource();
            return(vertex_shader);
        }
Пример #2
0
        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);
        }