Example #1
0
        //private bool first = true;

        /// <summary>
        /// Ejecuta el shader original de formato propio de Quake 3 convertido a una version similar de HLSL en DirectX.
        /// Estado experimental. Desabilitado por el momento.
        /// </summary>
        private void renderShaderMesh(TgcMesh mesh, QShaderData shader)
        {
            // if ((shader.Stages[0].HasBlendFunc) ^ (pass == 1))
            // {
            //tiene es opaco se tiene que renderizar en la primer pasada
            //tiene alpha blending se tiene que renderizar en la segunda pasada
            //    return;
            //}

            Device d3dDevice = GuiController.Instance.D3dDevice;


            Effect fx = shader.Fx;

            fx.Technique = "tec0";
            fx.SetValue("g_mWorld", Matrix.Identity);
            fx.SetValue("g_mViewProj", mViewProj);
            fx.SetValue("g_time", time);

            TgcTexture originalTexture = null;

            if (mesh.DiffuseMaps != null)
            {
                originalTexture = mesh.DiffuseMaps[0];
            }

            fx.Begin(FX.None);


            for (int j = 0; j < shader.Stages.Count; j++)
            {
                fx.BeginPass(j);
                if (shader.Stages[j].Textures.Count > 0)
                {
                    mesh.DiffuseMaps[0] = shader.Stages[j].Textures[0];
                }

                //mesh.render();
                d3dDevice.SetTexture(0, mesh.DiffuseMaps[0].D3dTexture);
                if (mesh.LightMap != null)
                {
                    d3dDevice.SetTexture(1, mesh.LightMap.D3dTexture);
                }
                else
                {
                    d3dDevice.SetTexture(1, null);
                }

                mesh.D3dMesh.DrawSubset(0);

                fx.EndPass();
            }

            fx.End();

            if (mesh.DiffuseMaps != null)
            {
                mesh.DiffuseMaps[0] = originalTexture;
            }
        }
Example #2
0
        private static List <string> BuildEffectState(QShaderData shader, QShaderStage qstage)
        {
            List <string> 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);
        }
Example #3
0
        public static string BuildShaderSource(QShaderData shader)
        {
            //devuelve el codigo del Fx
            ShaderCode shaderCode = new ShaderCode();


            shaderCode.AuxFuntions.Add(CreateSquareFunction());
            shaderCode.AuxFuntions.Add(CreateTriangleFunction());

            shaderCode.VsStruct.Add("float4 Pos : POSITION;");
            shaderCode.VsStruct.Add("float3 Normal : NORMAL;");
            shaderCode.VsStruct.Add("float4 Color : COLOR;");
            shaderCode.VsStruct.Add("float2 Tex0 : TEXCOORD0;");
            shaderCode.VsStruct.Add("float2 Tex1 : TEXCOORD1;");


            shaderCode.PsStruct.Add("float4 Pos : POSITION;");
            shaderCode.PsStruct.Add("float3 Normal : NORMAL;");
            shaderCode.PsStruct.Add("float4 Color : COLOR;");
            shaderCode.PsStruct.Add("float2 Tex0 : TEXCOORD0;");
            shaderCode.PsStruct.Add("float2 Tex1 : TEXCOORD1;");


            shaderCode.Globals.Add("float4x4 g_mWorld;// : WORLD;");
            shaderCode.Globals.Add("float4x4 g_mViewProj;// : VIEWPROJECTION;");
            shaderCode.Globals.Add("float g_time;// : TIME;");
            shaderCode.Globals.Add("sampler2D texture0 : register(s0);");
            shaderCode.Globals.Add("sampler2D texture1 : register(s1);");



            foreach (QShaderStage qstage in shader.Stages)
            {
                StageCode stageCode = shaderCode.NewStage();
                stageCode.VertexLines = BuildVertexShader(shader, qstage);
                stageCode.PixelLines  = BuildPixelShader(shader, qstage);
                stageCode.StatesLines = BuildEffectState(shader, qstage);
            }

            return(shaderCode.Build());
        }
Example #4
0
        /// <summary>
        /// Parsear shader
        /// </summary>
        private static QShaderData ParseShader(QShaderTokenizer tokenizer)
        {
            QShaderData qsd = new QShaderData();

            qsd.Name = tokenizer.GetNext();

            string token = tokenizer.GetNext();

            if (!token.Equals("{"))
            {
                return(null);
            }

            // Parse a shader
            while (!tokenizer.EOF)
            {
                token = tokenizer.GetNext().ToLower();

                if (token.Equals("}"))
                {
                    break;
                }

                switch (token)
                {
                case "{":
                    QShaderStage stage = ParseStage(tokenizer);

                    // 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() && (stage.HasBlendFunc))
                    {
                        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.Equals("lightingspecular"))
                    {
                        stage.BlendSrc     = "GL_ONE";
                        stage.BlendDest    = "GL_ZERO";
                        stage.HasBlendFunc = false;
                        stage.DepthWrite   = true;
                    }

                    if (stage.HasBlendFunc)
                    {
                        qsd.Blend = true;
                    }
                    else
                    {
                        qsd.Opaque = true;
                    }

                    qsd.Stages.Add(stage);
                    break;

                case "cull":
                    qsd.Cull = tokenizer.GetNext();
                    break;

                case "deformvertexes":
                    QShaderDeform deform = new QShaderDeform()
                    {
                        Type = tokenizer.GetNext().ToLower()
                    };

                    switch (deform.Type)
                    {
                    case "wave":
                        deform.Spread   = 1.0f / ParserTools.ToFloat(tokenizer.GetNext());
                        deform.WaveForm = ParseWaveform(tokenizer);
                        break;

                    case "bulge":
                        deform.BulgeWidth  = ParserTools.ToFloat(tokenizer.GetNext());
                        deform.BulgeHeight = ParserTools.ToFloat(tokenizer.GetNext());
                        deform.BulgeSpeed  = ParserTools.ToFloat(tokenizer.GetNext());
                        break;

                    default: deform = null; break;
                    }

                    if (deform != null)
                    {
                        qsd.VertexDeforms.Add(deform);
                    }
                    break;

                case "sort":
                    var sort = tokenizer.GetNext().ToLower();
                    switch (sort)
                    {
                    case "portal": qsd.Sort = 1; break;

                    case "sky": qsd.Sort = 2; break;

                    case "opaque": qsd.Sort = 3; break;

                    case "banner": qsd.Sort = 6; break;

                    case "underwater": qsd.Sort = 8; break;

                    case "additive": qsd.Sort = 9; break;

                    case "nearest": qsd.Sort = 16; break;

                    default: qsd.Sort = int.Parse(sort); break;
                    }
                    ;
                    break;

                case "surfaceparm":
                    var param = tokenizer.GetNext().ToLower();

                    switch (param)
                    {
                    case "sky":
                        qsd.Sky = true;
                        break;

                    default: break;
                    }
                    break;

                default: break;
                }
            }

            if (qsd.Sort > 0)
            {
                qsd.Sort = (qsd.Opaque ? 3 : 9);
            }

            return(qsd);
        }
Example #5
0
        private static List <string> BuildVertexShader(QShaderData shader, QShaderStage stage)
        {
            List <string> VertexLines = new List <string>();

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

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

                switch (deform.Type)
                {
                case "wave":
                {
                    string name    = "deform" + i;
                    string 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);

                    string deformi = "deform" + i;
                    string 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 (int i = 0; i < stage.TcMods.Count; ++i)
            {
                QTcMod 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);
        }
Example #6
0
        private static List <string> BuildPixelShader(QShaderData shader, QShaderStage stage)
        {
            List <string> 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);
        }
Example #7
0
        /// <summary>
        /// Renderizar escenario BSP utilizando matriz PVS para descartar clusters no visibles
        /// </summary>
        /// <param name="camPos">Posición actual de la camara</param>
        public void render(Vector3 camPos)
        {
            Device device = GuiController.Instance.D3dDevice;

            float elapsedTime = GuiController.Instance.ElapsedTime;

            time += elapsedTime;

            //Obtener leaf actual
            int actualLeaf = FindLeaf(camPos);

            //Obtener clusters visibles segun PVS
            int actualCluster = data.leafs[actualLeaf].cluster;

            if (actualCluster != antCluster)
            {
                antCluster = actualCluster;
                clusterVis.Clear();
                for (int i = 0; i < data.leafs.Length; i++)
                {
                    if (isClusterVisible(actualCluster, data.leafs[i].cluster))
                    {
                        clusterVis.Add(i);
                    }
                }
            }

            //Actualizar volumen del Frustum con nuevos valores de camara
            TgcFrustum frustum = GuiController.Instance.Frustum;

            frustum.updateVolume(device.Transform.View, device.Transform.Projection);

            foreach (int nleaf in clusterVis)
            {
                //Frustum Culling con el AABB del cluster
                TgcCollisionUtils.FrustumResult result = TgcCollisionUtils.classifyFrustumAABB(frustum, data.leafs[nleaf].boundingBox);
                if (result == TgcCollisionUtils.FrustumResult.OUTSIDE)
                {
                    continue;
                }

                //Habilitar meshes de este leaf
                QLeaf currentLeaf = data.leafs[nleaf];
                for (int i = currentLeaf.firstLeafSurface; i < currentLeaf.firstLeafSurface + currentLeaf.numLeafSurfaces; i++)
                {
                    int     iMesh = data.leafSurfaces[i];
                    TgcMesh mesh  = meshes[iMesh];
                    if (mesh != null)
                    {
                        meshes[iMesh].Enabled = true;
                    }
                }
            }

            //Renderizar meshes visibles
            mViewProj = device.Transform.View * device.Transform.Projection;
            for (int i = 0; i < meshes.Count; i++)
            {
                //Ignonar si no está habilitada
                TgcMesh mesh = meshes[i];
                if (mesh == null || !mesh.Enabled)
                {
                    continue;
                }


                QShaderData shader = data.shaderXSurface[i];

                //Renderizado con shaders
                //TODO: Mejorar el renderizado de shaders. Por ahora esta deshabilitado
                if (shader != null && shader.Stages.Count > 0)
                {
                    renderShaderMesh(mesh, shader);
                }
                //Renderizado normal
                else
                {
                    //render
                    mesh.render();

                    //deshabilitar para la proxima vuelta
                    mesh.Enabled = false;
                }
            }
        }
Example #8
0
        /// <summary>
        /// Parsear shader
        /// </summary>
        private static QShaderData ParseShader(QShaderTokenizer tokenizer)
        {
            QShaderData qsd = new QShaderData();

            qsd.Name = tokenizer.GetNext();

            string token = tokenizer.GetNext();

            if (!token.Equals("{"))
            {
                return null;
            }

            // Parse a shader
	        while(!tokenizer.EOF) {
		        token = tokenizer.GetNext().ToLower();

		        if(token.Equals("}")) { break; }
        		
		        switch (token) {
			        case "{":
				        QShaderStage stage = ParseStage(tokenizer);
        				
				        // 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() && (stage.HasBlendFunc))
                        {
					        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.Equals("lightingspecular"))
                        {
					        stage.BlendSrc = "GL_ONE";
					        stage.BlendDest = "GL_ZERO";
					        stage.HasBlendFunc = false;
					        stage.DepthWrite = true;
				        }
        				
				        if(stage.HasBlendFunc)
				        {
				            qsd.Blend = true;
				        }
                        else
				        {
				            qsd.Opaque = true;
				        }
        				
				        qsd.Stages.Add(stage);
			            break;
        			
			        case "cull":
		                qsd.Cull = tokenizer.GetNext();
				        break;
        				
			        case "deformvertexes":
		                QShaderDeform deform = new QShaderDeform() {Type = tokenizer.GetNext().ToLower()};
        				
				        switch(deform.Type) {
					        case "wave":
						        deform.Spread = 1.0f / ParserTools.ToFloat(tokenizer.GetNext());
						        deform.WaveForm = ParseWaveform(tokenizer);
						        break;
								 case "bulge":
                     deform.BulgeWidth = ParserTools.ToFloat(tokenizer.GetNext());
                     deform.BulgeHeight = ParserTools.ToFloat(tokenizer.GetNext());
                     deform.BulgeSpeed = ParserTools.ToFloat(tokenizer.GetNext());
                     break;
					        default: deform = null; break;
				        }
        				
				        if(deform != null) { qsd.VertexDeforms.Add(deform); }
				        break;
        				
			        case "sort":
				        var sort = tokenizer.GetNext().ToLower();
				        switch(sort) {
					        case "portal": qsd.Sort = 1; break;
					        case "sky": qsd.Sort = 2; break;
					        case "opaque": qsd.Sort = 3; break;
					        case "banner": qsd.Sort = 6; break;
					        case "underwater": qsd.Sort = 8; break;
					        case "additive": qsd.Sort = 9; break;
					        case "nearest": qsd.Sort = 16; break;
					        default: qsd.Sort = int.Parse(sort); break; 
				        };
				        break;
        				
			        case "surfaceparm":
				        var param = tokenizer.GetNext().ToLower();
        				
				        switch(param) {
					        case "sky":
						        qsd.Sky = true;
						        break;
					        default: break;
				        }
				        break;
        				
			        default: break;
		        }
	        }

            if (qsd.Sort > 0)
            {
                qsd.Sort = (qsd.Opaque ? 3 : 9);
            }

            return qsd;
	
        }
Example #9
0
        private static List<string> BuildVertexShader(QShaderData shader, QShaderStage stage)
        {
            List<string> VertexLines = new List<string>();
            
            VertexLines.Add("PSInput Out = In;");
	        VertexLines.Add("float4 defPosition = In.Pos;");
        	
	        for(int i = 0; i < shader.VertexDeforms.Count; ++i) {

		        QShaderDeform deform = shader.VertexDeforms[i];
        		
		        switch(deform.Type)
		        {
                    case "wave":
		                {
		                    string name = "deform" + i;
		                    string 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);

                            string deformi = "deform" + i;
		                    string 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(int i = 0; i < stage.TcMods.Count; ++i)
            {
		        QTcMod 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;
        }
Example #10
0
        private static List<string> BuildPixelShader(QShaderData shader, QShaderStage stage)
        {
            List<string> 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;

        }
Example #11
0
        private static List<string> BuildEffectState(QShaderData shader, QShaderStage qstage)
        {
            List<string> 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;
        }
Example #12
0
        public static string BuildShaderSource(QShaderData shader)
        {
            //devuelve el codigo del Fx
            ShaderCode shaderCode = new ShaderCode();


            shaderCode.AuxFuntions.Add(CreateSquareFunction());
            shaderCode.AuxFuntions.Add(CreateTriangleFunction());

            shaderCode.VsStruct.Add("float4 Pos : POSITION;");
            shaderCode.VsStruct.Add("float3 Normal : NORMAL;");
            shaderCode.VsStruct.Add("float4 Color : COLOR;");
            shaderCode.VsStruct.Add("float2 Tex0 : TEXCOORD0;");
            shaderCode.VsStruct.Add("float2 Tex1 : TEXCOORD1;");


            shaderCode.PsStruct.Add("float4 Pos : POSITION;");
            shaderCode.PsStruct.Add("float3 Normal : NORMAL;");
            shaderCode.PsStruct.Add("float4 Color : COLOR;");
            shaderCode.PsStruct.Add("float2 Tex0 : TEXCOORD0;");
            shaderCode.PsStruct.Add("float2 Tex1 : TEXCOORD1;");


            shaderCode.Globals.Add("float4x4 g_mWorld;// : WORLD;");
            shaderCode.Globals.Add("float4x4 g_mViewProj;// : VIEWPROJECTION;");
            shaderCode.Globals.Add("float g_time;// : TIME;");
            shaderCode.Globals.Add("sampler2D texture0 : register(s0);");
            shaderCode.Globals.Add("sampler2D texture1 : register(s1);");



            foreach (QShaderStage qstage in shader.Stages)
            {
                StageCode stageCode = shaderCode.NewStage();
                stageCode.VertexLines = BuildVertexShader(shader, qstage);
                stageCode.PixelLines = BuildPixelShader(shader, qstage);
                stageCode.StatesLines = BuildEffectState(shader, qstage);
            }

            return shaderCode.Build();
        }
Example #13
0
        //private bool first = true;

        /// <summary>
        /// Ejecuta el shader original de formato propio de Quake 3 convertido a una version similar de HLSL en DirectX.
        /// Estado experimental. Desabilitado por el momento.
        /// </summary>
        private void renderShaderMesh(TgcMesh mesh, QShaderData shader)
        {
           // if ((shader.Stages[0].HasBlendFunc) ^ (pass == 1))
           // {
                //tiene es opaco se tiene que renderizar en la primer pasada
                //tiene alpha blending se tiene que renderizar en la segunda pasada
            //    return;
            //}

            Device d3dDevice = GuiController.Instance.D3dDevice;


            Effect fx = shader.Fx;
            fx.Technique = "tec0";
            fx.SetValue("g_mWorld", Matrix.Identity);
            fx.SetValue("g_mViewProj", mViewProj);
            fx.SetValue("g_time", time);

            TgcTexture originalTexture = null;

            if (mesh.DiffuseMaps != null)
                originalTexture = mesh.DiffuseMaps[0];

            fx.Begin(FX.None);


            for (int j = 0; j < shader.Stages.Count; j++)
            {
                fx.BeginPass(j);
                if (shader.Stages[j].Textures.Count > 0)
                {
                    mesh.DiffuseMaps[0] = shader.Stages[j].Textures[0];
                }

                //mesh.render();
                d3dDevice.SetTexture(0, mesh.DiffuseMaps[0].D3dTexture);
                if (mesh.LightMap != null)
                    d3dDevice.SetTexture(1, mesh.LightMap.D3dTexture);
                else
                    d3dDevice.SetTexture(1, null);
                
                mesh.D3dMesh.DrawSubset(0);

                fx.EndPass();
            }

            fx.End();

            if (mesh.DiffuseMaps != null)
                mesh.DiffuseMaps[0] = originalTexture;
        }