Ejemplo n.º 1
0
        public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required, string memo)
        {
            if (!vertexShader.Available || !fragmentShader.Available)
            {
                string errors = string.Format("Vertex Shader:\r\n {0} \r\n-------\r\nFragment Shader:\r\n{1}", vertexShader.Errors, fragmentShader.Errors);
                if (required)
                {
                    throw new InvalidOperationException("Couldn't build required GL pipeline:\r\n" + errors);
                }
                var pipeline = new Pipeline(this, null, false, null, null, null);
                pipeline.Errors = errors;
                return(pipeline);
            }

            VertexElement[] ves    = new VertexElement[vertexLayout.Items.Count];
            int             stride = 0;

            foreach (var kvp in vertexLayout.Items)
            {
                var item = kvp.Value;
                d3d9.DeclarationType decltype = DeclarationType.Float1;
                switch (item.AttribType)
                {
                case gl.VertexAttribPointerType.Float:
                    if (item.Components == 1)
                    {
                        decltype = DeclarationType.Float1;
                    }
                    else if (item.Components == 2)
                    {
                        decltype = DeclarationType.Float2;
                    }
                    else if (item.Components == 3)
                    {
                        decltype = DeclarationType.Float3;
                    }
                    else if (item.Components == 4)
                    {
                        decltype = DeclarationType.Float4;
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                    stride += 4 * item.Components;
                    break;

                default:
                    throw new NotSupportedException();
                }

                d3d9.DeclarationUsage usage = DeclarationUsage.Position;
                byte usageIndex             = 0;
                switch (item.Usage)
                {
                case AttributeUsage.Position:
                    usage = DeclarationUsage.Position;
                    break;

                case AttributeUsage.Texcoord0:
                    usage = DeclarationUsage.TextureCoordinate;
                    break;

                case AttributeUsage.Texcoord1:
                    usage      = DeclarationUsage.TextureCoordinate;
                    usageIndex = 1;
                    break;

                case AttributeUsage.Color0:
                    usage = DeclarationUsage.Color;
                    break;

                default:
                    throw new NotSupportedException();
                }

                ves[kvp.Key] = new VertexElement(0, (short)item.Offset, decltype, DeclarationMethod.Default, usage, usageIndex);
            }


            var pw = new PipelineWrapper()
            {
                VertexDeclaration = new VertexDeclaration(dev, ves),
                VertexShader      = vertexShader.Opaque as ShaderWrapper,
                FragmentShader    = fragmentShader.Opaque as ShaderWrapper,
                VertexStride      = stride,
            };

            //scan uniforms from constant tables
            //handles must be disposed later (with the pipeline probably)
            var uniforms = new List <UniformInfo>();
            var fs       = pw.FragmentShader;
            var vs       = pw.VertexShader;
            var fsct     = fs.bytecode.ConstantTable;
            var vsct     = vs.bytecode.ConstantTable;

            foreach (var ct in new[] { fsct, vsct })
            {
                Queue <Tuple <string, EffectHandle> > todo = new Queue <Tuple <string, EffectHandle> >();
                int n = ct.Description.Constants;
                for (int i = 0; i < n; i++)
                {
                    var handle = ct.GetConstant(null, i);
                    todo.Enqueue(Tuple.Create("", handle));
                }

                while (todo.Count != 0)
                {
                    var tuple  = todo.Dequeue();
                    var prefix = tuple.Item1;
                    var handle = tuple.Item2;
                    var descr  = ct.GetConstantDescription(handle);

                    //Console.WriteLine("D3D UNIFORM: " + descr.Name);

                    if (descr.StructMembers != 0)
                    {
                        string newprefix = prefix + descr.Name + ".";
                        for (int j = 0; j < descr.StructMembers; j++)
                        {
                            var subhandle = ct.GetConstant(handle, j);
                            todo.Enqueue(Tuple.Create(newprefix, subhandle));
                        }
                        continue;
                    }

                    UniformInfo    ui = new UniformInfo();
                    UniformWrapper uw = new UniformWrapper();

                    ui.Opaque = uw;
                    string name = prefix + descr.Name;

                    //mehhh not happy about this stuff
                    if (fs.MapCodeToNative != null || vs.MapCodeToNative != null)
                    {
                        string key = name.TrimStart('$');
                        if (descr.Rows != 1)
                        {
                            key = key + "[0]";
                        }
                        if (fs.MapCodeToNative != null && ct == fsct)
                        {
                            if (fs.MapCodeToNative.ContainsKey(key))
                            {
                                name = fs.MapCodeToNative[key];
                            }
                        }
                        if (vs.MapCodeToNative != null && ct == vsct)
                        {
                            if (vs.MapCodeToNative.ContainsKey(key))
                            {
                                name = vs.MapCodeToNative[key];
                            }
                        }
                    }

                    ui.Name         = name;
                    uw.Description  = descr;
                    uw.EffectHandle = handle;
                    uw.FS           = (ct == fsct);
                    uw.CT           = ct;
                    if (descr.Type == ParameterType.Sampler2D)
                    {
                        ui.IsSampler    = true;
                        ui.SamplerIndex = descr.RegisterIndex;
                        uw.SamplerIndex = descr.RegisterIndex;
                    }
                    uniforms.Add(ui);
                }
            }

            pw.fsct = fsct;
            pw.vsct = vsct;

            return(new Pipeline(this, pw, true, vertexLayout, uniforms, memo));
        }
Ejemplo n.º 2
0
		public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required, string memo)
		{
			if (!vertexShader.Available || !fragmentShader.Available)
			{
				string errors = string.Format("Vertex Shader:\r\n {0} \r\n-------\r\nFragment Shader:\r\n{1}", vertexShader.Errors, fragmentShader.Errors);
				if (required)
					throw new InvalidOperationException("Couldn't build required GL pipeline:\r\n" + errors);
				var pipeline = new Pipeline(this, null, false, null, null, null);
				pipeline.Errors = errors;
				return pipeline;
			}

			VertexElement[] ves = new VertexElement[vertexLayout.Items.Count];
			int stride = 0;
			foreach (var kvp in vertexLayout.Items)
			{
				var item = kvp.Value;
				d3d9.DeclarationType decltype = DeclarationType.Float1;
				switch (item.AttribType)
				{
					case gl.VertexAttribPointerType.Float:
						if (item.Components == 1) decltype = DeclarationType.Float1;
						else if (item.Components == 2) decltype = DeclarationType.Float2;
						else if (item.Components == 3) decltype = DeclarationType.Float3;
						else if (item.Components == 4) decltype = DeclarationType.Float4;
						else throw new NotSupportedException();
						stride += 4 * item.Components;
						break;
					default:
						throw new NotSupportedException();
				}

				d3d9.DeclarationUsage usage = DeclarationUsage.Position;
				byte usageIndex = 0;
				switch(item.Usage)
				{
					case AttributeUsage.Position: 
						usage = DeclarationUsage.Position; 
						break;
					case AttributeUsage.Texcoord0: 
						usage = DeclarationUsage.TextureCoordinate;
						break;
					case AttributeUsage.Texcoord1: 
						usage = DeclarationUsage.TextureCoordinate;
						usageIndex = 1;
						break;
					case AttributeUsage.Color0:
						usage = DeclarationUsage.Color;
						break;
					default:
						throw new NotSupportedException();
				}

				ves[kvp.Key] = new VertexElement(0, (short)item.Offset, decltype, DeclarationMethod.Default, usage, usageIndex);
			}


			var pw = new PipelineWrapper()
			{
				VertexDeclaration = new VertexDeclaration(dev, ves),
				VertexShader = vertexShader.Opaque as ShaderWrapper,
				FragmentShader = fragmentShader.Opaque as ShaderWrapper,
				VertexStride = stride,
			};

			//scan uniforms from constant tables
			//handles must be disposed later (with the pipeline probably)
			var uniforms = new List<UniformInfo>();
			var fs = pw.FragmentShader;
			var vs = pw.VertexShader;
			var fsct = fs.bytecode.ConstantTable;
			var vsct = vs.bytecode.ConstantTable;
			foreach(var ct in new[]{fsct,vsct})
			{
				Queue<Tuple<string,EffectHandle>> todo = new Queue<Tuple<string,EffectHandle>>();
				int n = ct.Description.Constants;
				for (int i = 0; i < n; i++)
				{
					var handle = ct.GetConstant(null, i);
					todo.Enqueue(Tuple.Create("", handle));
				}

				while(todo.Count != 0)
				{
					var tuple = todo.Dequeue();
					var prefix = tuple.Item1;
					var handle = tuple.Item2;
					var descr = ct.GetConstantDescription(handle);

					//Console.WriteLine("D3D UNIFORM: " + descr.Name);

					if (descr.StructMembers != 0)
					{
						string newprefix = prefix + descr.Name + ".";
						for (int j = 0; j < descr.StructMembers; j++)
						{
							var subhandle = ct.GetConstant(handle, j);
							todo.Enqueue(Tuple.Create(newprefix, subhandle));
						}
						continue;
					}

					UniformInfo ui = new UniformInfo();
					UniformWrapper uw = new UniformWrapper();

					ui.Opaque = uw;
					string name = prefix + descr.Name;

					//mehhh not happy about this stuff
					if (fs.MapCodeToNative != null || vs.MapCodeToNative != null)
					{
						string key = name.TrimStart('$');
						if (descr.Rows != 1)
							key = key + "[0]";
						if (fs.MapCodeToNative != null && ct == fsct) if (fs.MapCodeToNative.ContainsKey(key)) name = fs.MapCodeToNative[key];
						if (vs.MapCodeToNative != null && ct == vsct) if (vs.MapCodeToNative.ContainsKey(key)) name = vs.MapCodeToNative[key];
					}
					
					ui.Name = name;
					uw.Description = descr;
					uw.EffectHandle = handle;
					uw.FS = (ct == fsct);
					uw.CT = ct;
					if (descr.Type == ParameterType.Sampler2D)
					{
						ui.IsSampler = true;
						ui.SamplerIndex = descr.RegisterIndex;
						uw.SamplerIndex = descr.RegisterIndex;
					}
					uniforms.Add(ui);
				}
			}

			pw.fsct = fsct;
			pw.vsct = vsct;

			return new Pipeline(this, pw, true, vertexLayout, uniforms,memo);
		}