Beispiel #1
0
        protected override void OnCopyTo(Resource r, Duality.Cloning.CloneProvider provider)
        {
            base.OnCopyTo(r, provider);
            DrawTechnique c = r as DrawTechnique;

            c.blendType = this.blendType;
        }
Beispiel #2
0
        protected override void OnCopyDataTo(object target, ICloneOperation operation)
        {
            base.OnCopyDataTo(target, operation);
            DrawTechnique targetTechnique = target as DrawTechnique;

            if (this.compiled)
            {
                targetTechnique.Compile();
            }
        }
		protected void PrepareVerticesLightSmooth(ref VertexC1P3T4A4A1[] vertices, IDrawDevice device, float curAnimFrameFade, ColorRgba mainClr, Rect uvRect, Rect uvRectNext, DrawTechnique tech)
		{
			bool perPixel = tech is LightingTechnique;

			Vector3 pos = this.GameObj.Transform.Pos;
			Vector3 posTemp = pos;
			float scaleTemp = 1.0f;
			device.PreprocessCoords(ref posTemp, ref scaleTemp);

			Vector2 xDot, yDot;
			float rotation = this.GameObj.Transform.Angle;
			MathF.GetTransformDotVec(rotation, out xDot, out yDot);

			Rect rectTemp = this.rect.Transformed(this.GameObj.Transform.Scale, this.GameObj.Transform.Scale);
			Vector2 edge1 = rectTemp.TopLeft;
			Vector2 edge2 = rectTemp.BottomLeft;
			Vector2 edge3 = rectTemp.BottomRight;
			Vector2 edge4 = rectTemp.TopRight;

			MathF.TransformDotVec(ref edge1, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge2, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge3, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge4, ref xDot, ref yDot);

			// Using Per-Vertex Lighting? Calculate vertex light values
			Vector4[] vertexLight = null;
			if (!perPixel)
			{
				vertexLight = new Vector4[4];
				Light.GetLightAtWorldPos(pos + new Vector3(edge1), out vertexLight[0], this.vertexTranslucency);
				Light.GetLightAtWorldPos(pos + new Vector3(edge2), out vertexLight[1], this.vertexTranslucency);
				Light.GetLightAtWorldPos(pos + new Vector3(edge3), out vertexLight[2], this.vertexTranslucency);
				Light.GetLightAtWorldPos(pos + new Vector3(edge4), out vertexLight[3], this.vertexTranslucency);
			}

			Vector2.Multiply(ref edge1, scaleTemp, out edge1);
			Vector2.Multiply(ref edge2, scaleTemp, out edge2);
			Vector2.Multiply(ref edge3, scaleTemp, out edge3);
			Vector2.Multiply(ref edge4, scaleTemp, out edge4);

			// Using Per-Pixel Lighting? Pass objRotation Matrix via vertex attribute.
			Vector4 objRotMat = Vector4.Zero;
			if (perPixel)
				objRotMat = new Vector4((float)Math.Cos(-rotation), -(float)Math.Sin(-rotation), (float)Math.Sin(-rotation), (float)Math.Cos(-rotation));

			if (vertices == null || vertices.Length != 4) vertices = new VertexC1P3T4A4A1[4];
			
			// Calculate UV coordinates
			float left       = uvRect.X;
			float right      = uvRect.RightX;
			float top        = uvRect.Y;
			float bottom     = uvRect.BottomY;
			float nextLeft   = uvRectNext.X;
			float nextRight  = uvRectNext.RightX;
			float nextTop    = uvRectNext.Y;
			float nextBottom = uvRectNext.BottomY;

			if ((this.flipMode & FlipMode.Horizontal) != FlipMode.None)
			{
				MathF.Swap(ref left, ref right);
				MathF.Swap(ref nextLeft, ref nextRight);
			}
			if ((this.flipMode & FlipMode.Vertical) != FlipMode.None)
			{
				MathF.Swap(ref top, ref bottom);
				MathF.Swap(ref nextTop, ref nextBottom);
			}

			// Directly pass World Position with each vertex, see note in Light.cs
			vertices[0].Pos.X = posTemp.X + edge1.X;
			vertices[0].Pos.Y = posTemp.Y + edge1.Y;
			vertices[0].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[0].TexCoord.X = left;
			vertices[0].TexCoord.Y = top;
			vertices[0].TexCoord.Z = nextLeft;
			vertices[0].TexCoord.W = nextTop;
			vertices[0].Color = mainClr;
			vertices[0].Attrib = perPixel ? objRotMat : vertexLight[0];
			vertices[0].Attrib2 = curAnimFrameFade;

			vertices[1].Pos.X = posTemp.X + edge2.X;
			vertices[1].Pos.Y = posTemp.Y + edge2.Y;
			vertices[1].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[1].TexCoord.X = left;
			vertices[1].TexCoord.Y = bottom;
			vertices[1].TexCoord.Z = nextLeft;
			vertices[1].TexCoord.W = nextBottom;
			vertices[1].Color = mainClr;
			vertices[1].Attrib = perPixel ? objRotMat : vertexLight[1];
			vertices[1].Attrib2 = curAnimFrameFade;

			vertices[2].Pos.X = posTemp.X + edge3.X;
			vertices[2].Pos.Y = posTemp.Y + edge3.Y;
			vertices[2].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[2].TexCoord.X = right;
			vertices[2].TexCoord.Y = bottom;
			vertices[2].TexCoord.Z = nextRight;
			vertices[2].TexCoord.W = nextBottom;
			vertices[2].Color = mainClr;
			vertices[2].Attrib = perPixel ? objRotMat : vertexLight[2];
			vertices[2].Attrib2 = curAnimFrameFade;
				
			vertices[3].Pos.X = posTemp.X + edge4.X;
			vertices[3].Pos.Y = posTemp.Y + edge4.Y;
			vertices[3].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[3].TexCoord.X = right;
			vertices[3].TexCoord.Y = top;
			vertices[3].TexCoord.Z = nextRight;
			vertices[3].TexCoord.W = nextTop;
			vertices[3].Color = mainClr;
			vertices[3].Attrib = perPixel ? objRotMat : vertexLight[3];
			vertices[3].Attrib2 = curAnimFrameFade;
			
			if (this.pixelGrid)
			{
				vertices[0].Pos.X = MathF.Round(vertices[0].Pos.X);
				vertices[1].Pos.X = MathF.Round(vertices[1].Pos.X);
				vertices[2].Pos.X = MathF.Round(vertices[2].Pos.X);
				vertices[3].Pos.X = MathF.Round(vertices[3].Pos.X);

				if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2)
				{
					vertices[0].Pos.X += 0.5f;
					vertices[1].Pos.X += 0.5f;
					vertices[2].Pos.X += 0.5f;
					vertices[3].Pos.X += 0.5f;
				}

				vertices[0].Pos.Y = MathF.Round(vertices[0].Pos.Y);
				vertices[1].Pos.Y = MathF.Round(vertices[1].Pos.Y);
				vertices[2].Pos.Y = MathF.Round(vertices[2].Pos.Y);
				vertices[3].Pos.Y = MathF.Round(vertices[3].Pos.Y);

				if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2)
				{
					vertices[0].Pos.Y += 0.5f;
					vertices[1].Pos.Y += 0.5f;
					vertices[2].Pos.Y += 0.5f;
					vertices[3].Pos.Y += 0.5f;
				}
			}
		}
		protected void PrepareVerticesLight(ref VertexC1P3T2A4[] vertices, IDrawDevice device, ColorRgba mainClr, Rect uvRect, DrawTechnique tech)
		{
			bool perPixel = tech is LightingTechnique;

			Vector3 pos = this.GameObj.Transform.Pos;
			Vector3 posTemp = pos;
			float scaleTemp = 1.0f;
			device.PreprocessCoords(ref posTemp, ref scaleTemp);

			Vector2 xDot, yDot;
			float rotation = this.GameObj.Transform.Angle;
			MathF.GetTransformDotVec(rotation, out xDot, out yDot);

			Rect rectTemp = this.rect.Transform(this.GameObj.Transform.Scale, this.GameObj.Transform.Scale);
			Vector2 edge1 = rectTemp.TopLeft;
			Vector2 edge2 = rectTemp.BottomLeft;
			Vector2 edge3 = rectTemp.BottomRight;
			Vector2 edge4 = rectTemp.TopRight;

			MathF.TransformDotVec(ref edge1, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge2, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge3, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge4, ref xDot, ref yDot);

			// Using Per-Vertex Lighting? Calculate vertex light values
			Vector4[] vertexLight = null;
			if (!perPixel)
			{
				vertexLight = new Vector4[4];
				Light.GetLightAtWorldPos(pos + new Vector3(edge1), out vertexLight[0], this.vertexTranslucency);
				Light.GetLightAtWorldPos(pos + new Vector3(edge2), out vertexLight[1], this.vertexTranslucency);
				Light.GetLightAtWorldPos(pos + new Vector3(edge3), out vertexLight[2], this.vertexTranslucency);
				Light.GetLightAtWorldPos(pos + new Vector3(edge4), out vertexLight[3], this.vertexTranslucency);
			}

			Vector2.Multiply(ref edge1, scaleTemp, out edge1);
			Vector2.Multiply(ref edge2, scaleTemp, out edge2);
			Vector2.Multiply(ref edge3, scaleTemp, out edge3);
			Vector2.Multiply(ref edge4, scaleTemp, out edge4);

			// Using Per-Pixel Lighting? Pass objRotation Matrix via vertex attribute.
			Vector4 objRotMat = Vector4.Zero;
			if (perPixel)
				objRotMat = new Vector4((float)Math.Cos(-rotation), -(float)Math.Sin(-rotation), (float)Math.Sin(-rotation), (float)Math.Cos(-rotation));

			if (vertices == null || vertices.Length != 4) vertices = new VertexC1P3T2A4[4];

			vertices[0].Pos.X = posTemp.X + edge1.X;
			vertices[0].Pos.Y = posTemp.Y + edge1.Y;
			vertices[0].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[0].TexCoord.X = uvRect.X;
			vertices[0].TexCoord.Y = uvRect.Y;
			vertices[0].Color = mainClr;
			vertices[0].Attrib = perPixel ? objRotMat : vertexLight[0];

			vertices[1].Pos.X = posTemp.X + edge2.X;
			vertices[1].Pos.Y = posTemp.Y + edge2.Y;
			vertices[1].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[1].TexCoord.X = uvRect.X;
			vertices[1].TexCoord.Y = uvRect.MaximumY;
			vertices[1].Color = mainClr;
			vertices[1].Attrib = perPixel ? objRotMat : vertexLight[1];

			vertices[2].Pos.X = posTemp.X + edge3.X;
			vertices[2].Pos.Y = posTemp.Y + edge3.Y;
			vertices[2].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[2].TexCoord.X = uvRect.MaximumX;
			vertices[2].TexCoord.Y = uvRect.MaximumY;
			vertices[2].Color = mainClr;
			vertices[2].Attrib = perPixel ? objRotMat : vertexLight[2];
				
			vertices[3].Pos.X = posTemp.X + edge4.X;
			vertices[3].Pos.Y = posTemp.Y + edge4.Y;
			vertices[3].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[3].TexCoord.X = uvRect.MaximumX;
			vertices[3].TexCoord.Y = uvRect.Y;
			vertices[3].Color = mainClr;
			vertices[3].Attrib = perPixel ? objRotMat : vertexLight[3];
		}
Beispiel #5
0
        /// <summary>
        /// Sets up the appropriate OpenGL rendering state for this DrawTechnique.
        /// </summary>
        /// <param name="lastTechnique">The last DrawTechnique that has been set up. This parameter is optional, but
        /// specifying it will increase performance by reducing redundant state changes.</param>
        /// <param name="textures">A set of <see cref="Duality.Resources.Texture">Textures</see> to use.</param>
        /// <param name="uniforms">A set of <see cref="Duality.Resources.ShaderVarInfo">uniform values</see> to apply.</param>
        public void SetupForRendering(IDrawDevice device, BatchInfo material, DrawTechnique lastTechnique)
        {
            // Prepare Rendering
            if (this.NeedsPreparation)
            {
                // Clone the material, if not done yet due to vertex preprocessing
                if (!this.NeedsPreprocess)
                {
                    material = new BatchInfo(material);
                }
                this.PrepareRendering(device, material);
            }

            // Setup BlendType
            if (lastTechnique == null || this.blendType != lastTechnique.blendType)
            {
                this.SetupBlendType(this.blendType, device.DepthWrite);
            }

            // Bind Shader
            ContentRef <ShaderProgram> selShader = this.SelectShader();

            if (lastTechnique == null || selShader.Res != lastTechnique.shader.Res)
            {
                ShaderProgram.Bind(selShader);
            }

            // Setup shader data
            if (selShader.IsAvailable)
            {
                ShaderVarInfo[] varInfo = selShader.Res.VarInfo;

                // Setup sampler bindings automatically
                int curSamplerIndex = 0;
                if (material.Textures != null)
                {
                    for (int i = 0; i < varInfo.Length; i++)
                    {
                        if (varInfo[i].glVarLoc == -1)
                        {
                            continue;
                        }
                        if (varInfo[i].type != ShaderVarType.Sampler2D)
                        {
                            continue;
                        }

                        // Bind Texture
                        ContentRef <Texture> texRef = material.GetTexture(varInfo[i].name);
                        Texture.Bind(texRef, curSamplerIndex);
                        GL.Uniform1(varInfo[i].glVarLoc, curSamplerIndex);

                        curSamplerIndex++;
                    }
                }
                Texture.ResetBinding(curSamplerIndex);

                // Transfer uniform data from material to actual shader
                if (material.Uniforms != null)
                {
                    for (int i = 0; i < varInfo.Length; i++)
                    {
                        if (varInfo[i].glVarLoc == -1)
                        {
                            continue;
                        }
                        float[] data = material.GetUniform(varInfo[i].name);
                        if (data == null)
                        {
                            continue;
                        }
                        varInfo[i].SetupUniform(data);
                    }
                }
            }
            // Setup fixed function data
            else
            {
                // Fixed function texture binding
                if (material.Textures != null)
                {
                    int samplerIndex = 0;
                    foreach (var pair in material.Textures)
                    {
                        Texture.Bind(pair.Value, samplerIndex);
                        samplerIndex++;
                    }
                    Texture.ResetBinding(samplerIndex);
                }
                else
                {
                    Texture.ResetBinding();
                }
            }
        }
 protected void GetAnimData(Texture mainTex, DrawTechnique tech, bool smoothShaderInput, out Rect uvRect, out Rect uvRectNext)
 {
     this.UpdateVisibleFrames();
     if (mainTex != null)
     {
         mainTex.LookupAtlas(this.curAnimFrame, out uvRect);
         if (smoothShaderInput)
             mainTex.LookupAtlas(this.nextAnimFrame, out uvRectNext);
         else
             uvRectNext = uvRect;
     }
     else if (mainTex != null)
         uvRect = uvRectNext = new Rect(mainTex.UVRatio.X, mainTex.UVRatio.Y);
     else
         uvRect = uvRectNext = new Rect(1.0f, 1.0f);
 }