예제 #1
0
        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);
        }
예제 #2
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);
        }