/// <summary>
		/// Retrieves the value of a builtin shader variable using the index retrieved by <see cref="GetIndex"/>.
		/// </summary>
		/// <param name="currentDevice"></param>
		/// <param name="index"></param>
		/// <param name="value"></param>
		/// <returns></returns>
		public static bool TryGetValue(IDrawDevice currentDevice, int index, ref float[] value)
		{
			int size = 1;
			switch (index)
			{
				case InvalidIndex: return false;
				default: size = 1; break;
				case 4:  size = 3; break;
			}

			value = (value != null && value.Length == size) ? value : new float[size];
			switch (index)
			{
				case 0: value[0] = (float)Time.MainTimer.TotalSeconds; return true;
				case 1: value[0] = (float)Time.GameTimer.TotalSeconds; return true;
				case 2: value[0] = (float)Time.FrameCount;             return true;
				case 3: value[0] = currentDevice.FocusDist;            return true;
				case 4: value[0] = currentDevice.RefCoord.X;
				        value[1] = currentDevice.RefCoord.Y;
				        value[2] = currentDevice.RefCoord.Z;           return true;
				case 5: value[0] = currentDevice.Perspective == PerspectiveMode.Parallax ? 1.0f : 0.0f; return true;
			}

			return false;
		}
 public IEnumerable<ICmpRenderer> QueryVisibleRenderers(IDrawDevice device)
 {
     if (this.renderers == null)
         return Enumerable.Empty<ICmpRenderer>();
     else
         return this.renderers.Where(r => (r as Component).Active && r.IsVisible(device));
 }
		bool ICmpRenderer.IsVisible(IDrawDevice device)
		{
			// Only render when in screen overlay mode and the visibility mask is non-empty.
			return 
				(device.VisibilityMask & VisibilityFlag.AllGroups) != VisibilityFlag.None &&
				(device.VisibilityMask & VisibilityFlag.ScreenOverlay) != VisibilityFlag.None;
		}
Exemple #4
0
		public override void Draw(IDrawDevice device)
		{
			// Perform Camera space transformation
			Vector3 posBefore = this.GameObj.Transform.Pos;
			Vector3 posTemp = posBefore;
			float scaleTemp = 1.0f;
			device.PreprocessCoords(this, ref posTemp, ref scaleTemp);

			// Draw debug text
			VertexC1P3T2[] textVertices;
			textVertices = null;
			Font.GenericMonospace10.Res.EmitTextVertices(
				string.Format("Position (world): {0:0}, {1:0}, {2:0}", posBefore.X, posBefore.Y, posBefore.Z),
				ref textVertices, posTemp.X, posTemp.Y, posTemp.Z);
			device.AddVertices(Font.GenericMonospace10.Res.Material, BeginMode.Quads, textVertices);

			textVertices = null;
			Font.GenericMonospace10.Res.EmitTextVertices(
				string.Format("Position (cam): {0:0}, {1:0}, {2:0}", posTemp.X, posTemp.Y, posTemp.Z),
				ref textVertices, posTemp.X, posTemp.Y + 10, posTemp.Z);
			device.AddVertices(Font.GenericMonospace10.Res.Material, BeginMode.Quads, textVertices);

			textVertices = null;
			Font.GenericMonospace10.Res.EmitTextVertices(
				string.Format("Scale: {0:F}", scaleTemp),
				ref textVertices, posTemp.X, posTemp.Y + 20, posTemp.Z);
			device.AddVertices(Font.GenericMonospace10.Res.Material, BeginMode.Quads, textVertices);

			// Draw position indicator
			device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.Red.WithAlpha(0.25f)), BeginMode.Quads, new VertexP3[] {
				new VertexP3(posTemp.X - 50.0f * scaleTemp, posTemp.Y - 50.0f * scaleTemp, posTemp.Z),
				new VertexP3(posTemp.X + 50.0f * scaleTemp, posTemp.Y - 50.0f * scaleTemp, posTemp.Z),
				new VertexP3(posTemp.X + 50.0f * scaleTemp, posTemp.Y + 50.0f * scaleTemp, posTemp.Z),
				new VertexP3(posTemp.X - 50.0f * scaleTemp, posTemp.Y + 50.0f * scaleTemp, posTemp.Z) });
		}
        public override void Draw(IDrawDevice device)
        {
            Texture mainTex = this.RetrieveMainTex();
            ColorRgba mainClr = this.RetrieveMainColor();
            DrawTechnique tech = this.RetrieveDrawTechnique();

            Rect uvRect;
            if (mainTex != null)
            {
                if (this.rectMode == UVMode.WrapBoth)
                    uvRect = new Rect(mainTex.UVRatio.X * this.rect.W / mainTex.PixelWidth, mainTex.UVRatio.Y * this.rect.H / mainTex.PixelHeight);
                else if (this.rectMode == UVMode.WrapHorizontal)
                    uvRect = new Rect(mainTex.UVRatio.X * this.rect.W / mainTex.PixelWidth, mainTex.UVRatio.Y);
                else if (this.rectMode == UVMode.WrapVertical)
                    uvRect = new Rect(mainTex.UVRatio.X, mainTex.UVRatio.Y * this.rect.H / mainTex.PixelHeight);
                else
                    uvRect = new Rect(mainTex.UVRatio.X, mainTex.UVRatio.Y);
            }
            else
                uvRect = new Rect(1.0f, 1.0f);

            this.PrepareVerticesLight(ref this.verticesLight, device, mainClr, uvRect, tech);

            if (this.customMat != null)	device.AddVertices(this.customMat, VertexMode.Quads, this.verticesLight);
            else						device.AddVertices(this.sharedMat, VertexMode.Quads, this.verticesLight);
        }
		public void QueryVisibleRenderers(IDrawDevice device, RawList<ICmpRenderer> targetList)
		{
			// Empty the cached list of visible renderers
			targetList.Count = 0;
			targetList.Reserve(this.totalRendererCount);

			// Copy references to all renderers that are visible to the target device
			int visibleCount = 0;
			ICmpRenderer[] targetData = targetList.Data;
			foreach (var pair in this.renderersByType)
			{
				ICmpRenderer[] data = pair.Value.Data;
				for (int i = 0; i < data.Length; i++)
				{
					if (i >= pair.Value.Count) break;

					if ((data[i] as Component).Active && data[i].IsVisible(device))
					{
						targetData[visibleCount] = data[i];
						visibleCount++;
					}
				}
			}
			targetList.Count = visibleCount;
		}
        public override void Draw(IDrawDevice device)
        {
            var mainClr = RetrieveMainColor();

            PrepareVertices(device, mainClr);
            device.AddVertices(sharedMat, VertexMode.Quads, _vertices);
        }
Exemple #8
0
 public bool IsVisible(IDrawDevice device)
 {
     return
     // Make sure the ScreenOverlay flag is set
     (device.VisibilityMask & VisibilityFlag.ScreenOverlay) != VisibilityFlag.None &&
     // Make sure some other flag is also set.
     (device.VisibilityMask & ~VisibilityFlag.ScreenOverlay) != VisibilityFlag.None;
 }
		protected override void PrepareRendering(IDrawDevice device, BatchInfo material)
		{
			base.PrepareRendering(device, material);

			material.SetTexture("mainTex", TextureOne);
			material.SetTexture("samp1", TextureTwo);
			material.SetTexture("samp2", TextureThree);
		}
Exemple #10
0
        void ICmpRenderer.Draw(IDrawDevice device)
        {
            if (device.VisibilityMask.HasFlag(VisibilityFlag.ScreenOverlay))
            {
                Canvas target = new Canvas(device, this.vertexBufferScreen);
                target.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White));
                foreach (VisualLog log in VisualLog.All)
                {
                    if (!log.Visible) continue;
                    if (log.BaseColor.A == 0) continue;
                    if ((log.VisibilityGroup & device.VisibilityMask & VisibilityFlag.AllGroups) == VisibilityFlag.None) continue;

                    target.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, log.BaseColor));
                    foreach (VisualLogEntry logEntry in log.Entries)
                    {
                        if (logEntry.Anchor != VisualLogAnchor.Screen) continue;
                        target.PushState();
                        if (logEntry.LifetimeAsAlpha)
                            target.State.ColorTint = new ColorRgba(1.0f, logEntry.LifetimeRatio);
                        else
                            target.State.ColorTint = ColorRgba.White;
                        logEntry.Draw(target);
                        target.PopState();
                    }
                }
            }
            else
            {
                Canvas target = new Canvas(device, this.vertexBufferWorld);
                target.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White));
                target.State.ZOffset = -1;
                foreach (VisualLog log in VisualLog.All)
                {
                    if (!log.Visible) continue;
                    if (log.BaseColor.A == 0) continue;
                    if ((log.VisibilityGroup & device.VisibilityMask & VisibilityFlag.AllGroups) == VisibilityFlag.None) continue;

                    target.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, log.BaseColor));
                    foreach (VisualLogEntry logEntry in log.Entries)
                    {
                        if (logEntry.Anchor == VisualLogAnchor.Screen) continue;
                        target.PushState();
                        target.State.ZOffset += logEntry.DepthOffset;
                        target.State.ColorTint = new ColorRgba(1.0f, logEntry.LifetimeRatio);
                        if (logEntry.Anchor == VisualLogAnchor.Object && logEntry.AnchorObj != null && logEntry.AnchorObj.Transform != null)
                        {
                            Transform anchorTransform = logEntry.AnchorObj.Transform;
                            logEntry.Draw(target, anchorTransform.Pos, anchorTransform.Angle, anchorTransform.Scale);
                        }
                        else
                        {
                            logEntry.Draw(target);
                        }
                        target.PopState();
                    }
                }
            }
        }
Exemple #11
0
 public void Draw(IDrawDevice device)
 {
     Canvas canvas = new Canvas(device);
     if(baseControl.NeedsLayout)
     {
         baseControl.Layout();
     }
     baseControl.Draw(canvas);
 }
		public static Bitmap GrabScreenshot(IDrawDevice device)
		{
			if (GraphicsContext.CurrentContext == null)
				throw new GraphicsContextMissingException();

			var bmp = new Bitmap((int) device.TargetSize.X, (int)device.TargetSize.Y);
			var data = bmp.LockBits(new Rectangle(0, 0, (int) device.TargetSize.X, (int) device.TargetSize.Y), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
			GL.ReadPixels(0, 0, (int) device.TargetSize.X, (int) device.TargetSize.Y, PixelFormat.Bgr, PixelType.UnsignedByte, data.Scan0);
			bmp.UnlockBits(data);

//			bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
			return bmp;
		}
Exemple #13
0
        public override void PrepareRendering(IDrawDevice device, BatchInfo material)
        {
            base.PrepareRendering(device, material);

            Vector3 camPos = device.RefCoord;
            float camRefDist = MathF.Abs(device.FocusDist);

            // Don't pass RefDist, see note in Light.cs
            material.SetUniform("_camRefDist", camRefDist);
            material.SetUniform("_camWorldPos", camPos.X, camPos.Y, camPos.Z);

            DynamicLighting.Light.SetupLighting(device, material);
        }
		void ICmpRenderer.Draw(IDrawDevice device)
		{
			Canvas canvas = new Canvas(device);

			// Draw the mouse cursor when available
			if (DualityApp.Mouse.IsAvailable)
			{
				canvas.State.ColorTint = ColorRgba.White;
				canvas.FillCircle(
					DualityApp.Mouse.X, 
					DualityApp.Mouse.Y, 
					2);
			}
		}
        public void Draw(IDrawDevice device)
        {
            var triangles = env.Triangles;
            var triangleSideLength = env.TriangleSideLength;
            Canvas canvas = new Canvas(device);

            Vector2[][] vectors = new Vector2[4][];

            vectors[0] = new Vector2[3];
            vectors[0][0] = new Vector2(-(triangleSideLength / 2), -(triangleSideLength / 2));
            vectors[0][1] = new Vector2((triangleSideLength / 2), -(triangleSideLength / 2));
            vectors[0][2] = new Vector2(0, 0);

            vectors[1] = new Vector2[3];
            vectors[1][0] = new Vector2((triangleSideLength / 2), -(triangleSideLength / 2));
            vectors[1][1] = new Vector2((triangleSideLength / 2), (triangleSideLength / 2));
            vectors[1][2] = new Vector2(0, 0);

            vectors[2] = new Vector2[3];
            vectors[2][0] = new Vector2((triangleSideLength / 2), (triangleSideLength / 2));
            vectors[2][1] = new Vector2(-(triangleSideLength / 2), (triangleSideLength / 2));
            vectors[2][2] = new Vector2(0, 0);

            vectors[3] = new Vector2[3];
            vectors[3][0] = new Vector2(-(triangleSideLength / 2), (triangleSideLength / 2));
            vectors[3][1] = new Vector2(-(triangleSideLength / 2), -(triangleSideLength / 2));
            vectors[3][2] = new Vector2(0, 0);

            BatchInfo[] infos = new BatchInfo[4];
            infos[0] = new BatchInfo(DrawTechnique.Alpha, ColorRgba.Red, null);
            infos[1] = new BatchInfo(DrawTechnique.Alpha, ColorRgba.Blue, null);
            infos[2] = new BatchInfo(DrawTechnique.Alpha, ColorRgba.White, null);
            infos[3] = new BatchInfo(DrawTechnique.Alpha, ColorRgba.Green, null);
            for (int x = 0; x < triangles.GetLength(0); x++)
            {
                for (int y = 0; y < triangles.GetLength(1); y++)
                {
                    for (int i = 0; i < triangles.GetLength(2); i++)
                    {
                        canvas.State.SetMaterial(infos[i]);
                        if(true/*triangles[x,y,i] != null*/)
                        {
                            canvas.FillPolygon(vectors[i], triangleSideLength / 2 + triangleSideLength * x,
                            triangleSideLength / 2 + triangleSideLength * y);
                        }
                    }
                }
            }
        }
 public bool IsVisible(IDrawDevice device)
 {
     // Differing ScreenOverlay flag? Don't render!
     if ((device.VisibilityMask & VisibilityFlag.ScreenOverlay) != (this.visibilityGroup & VisibilityFlag.ScreenOverlay))
     {
         return false;
     }
     // No match in any VisibilityGroup? Don't render!
     if ((this.visibilityGroup & device.VisibilityMask & VisibilityFlag.AllGroups) == VisibilityFlag.None)
     {
         return false;
     }
     // (Culling:) Not located near the screen? Don't render!
     return true;
 }
Exemple #17
0
		void ICmpRenderer.Draw(IDrawDevice device)
		{
			Canvas canvas = new Canvas(device);
			
			// Update input stats texts for drawing
			this.WriteInputStats(ref this.mouseStatsText, DualityApp.Mouse);
			this.WriteInputStats(ref this.keyboardStatsText, DualityApp.Keyboard);
			this.WriteInputStats(ref this.joystickStatsText, DualityApp.Joysticks);
			this.WriteInputStats(ref this.gamepadStatsText, DualityApp.Gamepads);

			// Draw input stats texts
			{
				int y = 10;

				canvas.DrawText(this.mouseStatsText, 10, y, 0, null, Alignment.TopLeft, true);
				y += 20 + (int)this.mouseStatsText.TextMetrics.Size.Y;

				canvas.DrawText(this.keyboardStatsText, 10, y, 0, null, Alignment.TopLeft, true);
				y += 20 + (int)this.keyboardStatsText.TextMetrics.Size.Y;

				canvas.DrawText(this.joystickStatsText, 10, y, 0, null, Alignment.TopLeft, true);
				y += 20 + (int)this.joystickStatsText.TextMetrics.Size.Y;

				canvas.DrawText(this.gamepadStatsText, 10, y, 0, null, Alignment.TopLeft, true);
				y += 20 + (int)this.gamepadStatsText.TextMetrics.Size.Y;
			}

			// Draw the mouse cursor's movement trail
			if (DualityApp.Mouse.IsAvailable)
			{
				canvas.State.ColorTint = new ColorRgba(128, 192, 255, 128);
				canvas.FillThickLine(
					DualityApp.Mouse.X - DualityApp.Mouse.XSpeed, 
					DualityApp.Mouse.Y - DualityApp.Mouse.YSpeed, 
					DualityApp.Mouse.X, 
					DualityApp.Mouse.Y, 
					2);
				// Draw the mouse cursor at its local window coordiates
				canvas.State.ColorTint = ColorRgba.White;
				canvas.FillCircle(
					DualityApp.Mouse.X, 
					DualityApp.Mouse.Y, 
					2);
			}
		}
		void ICmpRenderer.Draw(IDrawDevice device)
		{
			Canvas canvas = new Canvas(device);

			if (device.IsScreenOverlay)
			{
				// Testbed text
				Vector2 nameSize = this.name.Measure().Size;
				Vector2 descSize = this.desc.Measure().Size;
				Vector2 ctrlSize = this.controls.Measure().Size;
				Vector2 statsSize = this.stats.Measure().Size;
				canvas.PushState();
				// Text background
				canvas.CurrentState.SetMaterial(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White));
				canvas.CurrentState.ColorTint = ColorRgba.Black.WithAlpha(0.5f);
				canvas.FillRect(10, 10, MathF.Max(nameSize.X, descSize.X, ctrlSize.X) + 20, nameSize.Y + descSize.Y + 10 + ctrlSize.Y + 10);
				canvas.FillRect(10, DualityApp.TargetResolution.Y - 20 - statsSize.Y, statsSize.X + 20, statsSize.Y + 10);
				// Caption / Name
				canvas.CurrentState.ColorTint = ColorRgba.White.WithAlpha(0.85f);
				canvas.DrawText(this.name, 20, 15);
				// Description, Controls, Stats
				canvas.CurrentState.ColorTint = ColorRgba.White.WithAlpha(0.65f);
				canvas.DrawText(this.desc, 20, 15 + nameSize.Y);
				canvas.DrawText(this.controls, 20, 15 + nameSize.Y + descSize.Y + 10);
				canvas.DrawText(this.stats, 20, DualityApp.TargetResolution.Y - 15 - statsSize.Y);
				canvas.PopState();

				// Mouse cursor
				canvas.DrawCross(DualityApp.Mouse.X, DualityApp.Mouse.Y, 5.0f);
			}
			else
			{
				// Mouse joint, if existing
				if (this.mouseJoint != null)
				{
					Vector3 jointBegin = this.mouseJoint.BodyA.GameObj.Transform.GetWorldPoint(new Vector3(this.mouseJoint.LocalAnchor, -0.01f));
					Vector3 jointEnd = new Vector3(this.mouseJoint.WorldAnchor, -0.01f);
					canvas.CurrentState.ColorTint = ColorRgba.Red.WithAlpha(0.5f);
					canvas.DrawLine(jointBegin.X, jointBegin.Y, jointBegin.Z, jointEnd.X, jointEnd.Y, jointEnd.Z);
				}
			}
		}
        public override void Draw(IDrawDevice device)
        {
            Texture mainTex = this.RetrieveMainTex();
            ColorRgba mainClr = this.RetrieveMainColor();
            DrawTechnique tech = this.RetrieveDrawTechnique();

            Rect uvRect;
            Rect uvRectNext;
            bool smoothShaderInput = tech != null && tech.PreferredVertexFormat == VertexC1P3T4A4A1.Declaration;
            this.GetAnimData(mainTex, tech, smoothShaderInput, out uvRect, out uvRectNext);

            if (!smoothShaderInput)
            {
                this.PrepareVerticesLight(ref this.verticesLight, device, mainClr, uvRect, tech);
                if (this.customMat != null)	device.AddVertices(this.customMat, VertexMode.Quads, this.verticesLight);
                else						device.AddVertices(this.sharedMat, VertexMode.Quads, this.verticesLight);
            }
            else
            {
                this.PrepareVerticesLightSmooth(ref this.verticesLightSmooth, device, this.CurrentFrameProgress, mainClr, uvRect, uvRectNext, tech);
                if (this.customMat != null)	device.AddVertices(this.customMat, VertexMode.Quads, this.verticesLightSmooth);
                else						device.AddVertices(this.sharedMat, VertexMode.Quads, this.verticesLightSmooth);
            }
        }
Exemple #20
0
        private void PrepareVertices(ref VertexC1P3T2[] vertices, IDrawDevice device, ColorRgba mainClr, Rect uvRect)
        {
            Transform transform = this.GameObj.Transform;
            Vector3   posTemp   = transform.Pos;
            float     scaleTemp = transform.Scale;

            Vector2 xDot, yDot;

            MathF.GetTransformDotVec(transform.Angle, scaleTemp, out xDot, out yDot);

            Vector2 edge1 = this.rect.TopLeft;
            Vector2 edge2 = this.rect.BottomLeft;
            Vector2 edge3 = this.rect.BottomRight;
            Vector2 edge4 = this.rect.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);

            float uvLeft   = uvRect.X;
            float uvRight  = uvRect.RightX;
            float uvTop    = uvRect.Y;
            float uvBottom = uvRect.BottomY;

            if (vertices == null || vertices.Length != 4)
            {
                vertices = new VertexC1P3T2[4];
            }

            vertices[0].Pos.X      = posTemp.X + edge1.X;
            vertices[0].Pos.Y      = posTemp.Y + edge1.Y - this.height;
            vertices[0].Pos.Z      = posTemp.Z;
            vertices[0].TexCoord.X = uvLeft;
            vertices[0].TexCoord.Y = uvTop;
            vertices[0].Color      = mainClr;

            vertices[1].Pos.X      = posTemp.X + edge2.X;
            vertices[1].Pos.Y      = posTemp.Y + edge2.Y - this.height;
            vertices[1].Pos.Z      = posTemp.Z;
            vertices[1].TexCoord.X = uvLeft;
            vertices[1].TexCoord.Y = uvBottom;
            vertices[1].Color      = mainClr;

            vertices[2].Pos.X      = posTemp.X + edge3.X;
            vertices[2].Pos.Y      = posTemp.Y + edge3.Y - this.height;
            vertices[2].Pos.Z      = posTemp.Z;
            vertices[2].TexCoord.X = uvRight;
            vertices[2].TexCoord.Y = uvBottom;
            vertices[2].Color      = mainClr;

            vertices[3].Pos.X      = posTemp.X + edge4.X;
            vertices[3].Pos.Y      = posTemp.Y + edge4.Y - this.height;
            vertices[3].Pos.Z      = posTemp.Z;
            vertices[3].TexCoord.X = uvRight;
            vertices[3].TexCoord.Y = uvTop;
            vertices[3].Color      = mainClr;

            // Apply depth offsets
            float depthPerUnit = -this.depthScale;

            if (this.isVertical)
            {
                // Vertical actors share the same depth offset on all four vertices
                float baseDepthOffset = this.offset + transform.Pos.Y * depthPerUnit;
                vertices[0].DepthOffset = baseDepthOffset;
                vertices[1].DepthOffset = baseDepthOffset;
                vertices[2].DepthOffset = baseDepthOffset;
                vertices[3].DepthOffset = baseDepthOffset;
            }
            else
            {
                // Flat actors need to apply depth individually per vertex
                float worldBaseY = transform.Pos.Y;
                vertices[0].DepthOffset = this.offset + (worldBaseY + edge1.Y * transform.Scale / scaleTemp + this.height) * depthPerUnit;
                vertices[1].DepthOffset = this.offset + (worldBaseY + edge2.Y * transform.Scale / scaleTemp + this.height) * depthPerUnit;
                vertices[2].DepthOffset = this.offset + (worldBaseY + edge3.Y * transform.Scale / scaleTemp + this.height) * depthPerUnit;
                vertices[3].DepthOffset = this.offset + (worldBaseY + edge4.Y * transform.Scale / scaleTemp + this.height) * depthPerUnit;
            }
        }
		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];
		}
        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;
                }
            }
        }
Exemple #23
0
        void ICmpRenderer.Draw(IDrawDevice device)
        {
            // Create a buffer to cache and re-use vertices. Not required, but will boost performance.
            if (this.buffer == null)
            {
                this.buffer = new CanvasBuffer();
            }

            // Create a Canvas to auto-generate vertices from high-level drawing commands.
            Canvas canvas = new Canvas(device, this.buffer);

            canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White));
            canvas.State.TextFont = this.font;

            // Retrieve players
            if (this.playerOne == null)
            {
                this.playerOne = Scene.Current.FindComponents <Player>().Where(p => p.Id == PlayerId.PlayerOne).FirstOrDefault();
            }
            if (this.playerTwo == null)
            {
                this.playerTwo = Scene.Current.FindComponents <Player>().Where(p => p.Id == PlayerId.PlayerTwo).FirstOrDefault();
            }

            // Is someone playing using mouse / keyboard? Display a mouse cursor then
            if (Player.AlivePlayers.Any(p => p.InputMethod == InputMethod.MouseAndKeyboard))
            {
                canvas.FillCircle(DualityApp.Mouse.X, DualityApp.Mouse.Y, 2.0f);
            }

            // Is any player alive? Keep that value in mind, won't change here anyway.
            bool isAnyPlayerAlive = Player.IsAnyPlayerAlive;

            // Draw health and info of player one
            if (this.IsPlayerActive(this.playerOne))
            {
                Ship playerShip = this.playerOne.ControlObject;

                if (playerShip.Active)
                {
                    // Draw a health bar when alive
                    float health = playerShip.Hitpoints;

                    canvas.State.ColorTint = ColorRgba.Black.WithAlpha(0.5f);
                    canvas.FillRect(12 - 1, device.TargetSize.Y - 10 - 198 - 1, 16 + 2, 196 + 2);

                    canvas.State.ColorTint = this.playerOne.Color;
                    canvas.DrawRect(10, device.TargetSize.Y - 10 - 200, 20, 200);
                    canvas.FillRect(12, device.TargetSize.Y - 10 - health * 198.0f, 16, health * 196.0f);
                }
                else if (isAnyPlayerAlive && !this.playerOne.HasReachedGoal)
                {
                    // Draw a respawn timer when dead
                    float   respawnPercentage = this.playerOne.RespawnTime / Player.RespawnDelay;
                    string  respawnText       = string.Format("Respawn in {0:F1}", (Player.RespawnDelay - this.playerOne.RespawnTime) / 1000.0f);
                    Vector2 textSize          = canvas.MeasureText(string.Format("Respawn in {0:F1}", 0.0f));

                    canvas.State.ColorTint = ColorRgba.Black.WithAlpha(0.5f);
                    canvas.FillRect(10 - 1, device.TargetSize.Y - 10 - textSize.Y - 2, textSize.X + 5, textSize.Y + 8);

                    canvas.State.ColorTint = this.playerOne.Color;
                    canvas.DrawText(respawnText, 10, device.TargetSize.Y - 10, 0.0f, Alignment.BottomLeft);
                    canvas.FillRect(10, device.TargetSize.Y - 10 - textSize.Y, textSize.X * respawnPercentage, 3);
                    canvas.FillRect(10, device.TargetSize.Y - 10, textSize.X * respawnPercentage, 3);
                }
            }

            // Draw health and info of player two
            if (this.IsPlayerActive(this.playerTwo))
            {
                Ship playerShip = this.playerTwo.ControlObject;

                if (playerShip.Active)
                {
                    // Draw a health bar when alive
                    float health = playerShip.Hitpoints;

                    canvas.State.ColorTint = ColorRgba.Black.WithAlpha(0.5f);
                    canvas.FillRect(device.TargetSize.X - 12 - 16 - 1, device.TargetSize.Y - 10 - 198 - 1, 16 + 2, 196 + 2);

                    canvas.State.ColorTint = this.playerTwo.Color;
                    canvas.DrawRect(device.TargetSize.X - 10 - 20, device.TargetSize.Y - 10 - 200, 20, 200);
                    canvas.FillRect(device.TargetSize.X - 12 - 16, device.TargetSize.Y - 10 - health * 198.0f, 16, health * 196.0f);
                }
                else if (isAnyPlayerAlive && !this.playerTwo.HasReachedGoal)
                {
                    // Draw a respawn timer when dead
                    float   respawnPercentage = this.playerTwo.RespawnTime / Player.RespawnDelay;
                    string  respawnText       = string.Format("{0:F1} to Respawn", (Player.RespawnDelay - this.playerTwo.RespawnTime) / 1000.0f);
                    Vector2 textSize          = canvas.MeasureText(string.Format("{0:F1} to Respawn", 0.0f));

                    canvas.State.ColorTint = ColorRgba.Black.WithAlpha(0.5f);
                    canvas.FillRect(device.TargetSize.X - 10 - textSize.X - 3, device.TargetSize.Y - 10 - textSize.Y - 2, textSize.X + 2, textSize.Y + 10);

                    canvas.State.ColorTint = this.playerTwo.Color;
                    canvas.DrawText(respawnText, device.TargetSize.X - 10, device.TargetSize.Y - 10, 0.0f, Alignment.BottomRight);
                    canvas.FillRect(device.TargetSize.X - 10 - textSize.X * respawnPercentage, device.TargetSize.Y - 10 - textSize.Y, textSize.X * respawnPercentage, 3);
                    canvas.FillRect(device.TargetSize.X - 10 - textSize.X * respawnPercentage, device.TargetSize.Y - 10, textSize.X * respawnPercentage, 3);
                }
            }
        }
Exemple #24
0
 /// <summary>
 /// Performs a preprocessing operation for an incoming batch. Does nothing by default but may be overloaded, if needed.
 /// </summary>
 /// <typeparam name="T">The incoming vertex type</typeparam>
 /// <param name="device"></param>
 /// <param name="material"><see cref="Duality.Resources.Material"/> information for the current batch.</param>
 public virtual void PreprocessBatch(IDrawDevice device, IDrawBatch drawBatch)
 {
 }
 void ICmpRenderer.Draw(IDrawDevice device)
 {
     RenderSpriteGlow(device, GameObj.GetComponent <SpriteRenderer>(), GlowType, ScaleAmount, OffsetAmount, Color, DrawTechnique.Res);
 }
Exemple #26
0
        public override void Draw(IDrawDevice device)
        {
            Vector3 posTemp   = this.gameobj.Transform.Pos;
            float   scaleTemp = 1.0f;

            device.PreprocessCoords(ref posTemp, ref scaleTemp);

            Vector2 xDot, yDot;

            MathF.GetTransformDotVec(this.GameObj.Transform.Angle, this.gameobj.Transform.Scale * scaleTemp, out xDot, out yDot);

            // Apply block alignment
            Vector2 textOffset = Vector2.Zero;
            Vector2 textSize   = this.text.Size;

            if (this.text.MaxWidth > 0)
            {
                textSize.X = this.text.MaxWidth;
            }
            this.blockAlign.ApplyTo(ref textOffset, textSize);
            MathF.TransformDotVec(ref textOffset, ref xDot, ref yDot);
            posTemp.X += textOffset.X;
            posTemp.Y += textOffset.Y;
            if (this.text.Fonts != null && this.text.Fonts.Any(r => r.IsAvailable && r.Res.IsPixelGridAligned))
            {
                posTemp.X = MathF.Round(posTemp.X);
                posTemp.Y = MathF.Round(posTemp.Y);
                if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2)
                {
                    posTemp.X += 0.5f;
                }
                if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2)
                {
                    posTemp.Y += 0.5f;
                }
            }

            // Draw design time metrics data
            if (DualityApp.ExecContext == DualityApp.ExecutionContext.Editor)
            {
                bool    showLimits    = true;
                bool    showLines     = false;
                bool    showElements  = false;
                Vector3 metricsOffset = new Vector3(0.0f, 0.0f, 0.01f);
                Vector3 lineOffset    = new Vector3(0.5f, 0.5f, 0.0f);
                Vector3 tUnitX        = Vector3.UnitX;
                Vector3 tUnitY        = Vector3.UnitY;
                MathF.TransformDotVec(ref tUnitX, ref xDot, ref yDot);
                MathF.TransformDotVec(ref tUnitY, ref xDot, ref yDot);

                // Actual text size and maximum text size
                if (showLimits)
                {
                    Vector3 textWidth     = tUnitX * this.text.Size.X;
                    Vector3 textHeight    = tUnitY * this.text.Size.Y;
                    Vector3 textMaxWidth  = tUnitX * this.text.MaxWidth;
                    Vector3 textMaxHeight = tUnitY * MathF.Max(this.text.MaxHeight, this.text.Size.Y);

                    ColorRgba clrSize    = ColorRgba.Green.WithAlpha(128);
                    ColorRgba clrMaxSize = ColorRgba.Red.WithAlpha(128);
                    device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.LineLoop,
                                       new VertexC1P3(metricsOffset + lineOffset + posTemp, clrSize),
                                       new VertexC1P3(metricsOffset + lineOffset + posTemp + textWidth, clrSize),
                                       new VertexC1P3(metricsOffset + lineOffset + posTemp + textWidth + textHeight, clrSize),
                                       new VertexC1P3(metricsOffset + lineOffset + posTemp + textHeight, clrSize));
                    device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.LineLoop,
                                       new VertexC1P3(metricsOffset + lineOffset + posTemp, clrMaxSize),
                                       new VertexC1P3(metricsOffset + lineOffset + posTemp + textMaxWidth, clrMaxSize),
                                       new VertexC1P3(metricsOffset + lineOffset + posTemp + textMaxWidth + textMaxHeight, clrMaxSize),
                                       new VertexC1P3(metricsOffset + lineOffset + posTemp + textMaxHeight, clrMaxSize));
                }

                // Individual line sizes
                if (showLines)
                {
                    ColorRgba clrLineBg = (ColorRgba.Blue + ColorRgba.Red).WithAlpha(64);
                    for (int i = 0; i < this.text.TextMetrics.LineBounds.Count; i++)
                    {
                        Rect lineRect = this.text.TextMetrics.LineBounds[i];
                        device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.Quads,
                                           new VertexC1P3(metricsOffset + posTemp + lineRect.TopLeft.X * tUnitX + lineRect.TopLeft.Y * tUnitY, clrLineBg),
                                           new VertexC1P3(metricsOffset + posTemp + lineRect.BottomLeft.X * tUnitX + lineRect.BottomLeft.Y * tUnitY, clrLineBg),
                                           new VertexC1P3(metricsOffset + posTemp + lineRect.BottomRight.X * tUnitX + lineRect.BottomRight.Y * tUnitY, clrLineBg),
                                           new VertexC1P3(metricsOffset + posTemp + lineRect.TopRight.X * tUnitX + lineRect.TopRight.Y * tUnitY, clrLineBg));
                    }
                }

                // Individual line sizes
                if (showElements)
                {
                    ColorRgba clrElementBg = (ColorRgba.Blue + ColorRgba.Green).WithAlpha(128);
                    for (int i = 0; i < this.text.TextMetrics.ElementBounds.Count; i++)
                    {
                        Rect elemRect = this.text.TextMetrics.ElementBounds[i];
                        device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.LineLoop,
                                           new VertexC1P3(metricsOffset + lineOffset + posTemp + elemRect.TopLeft.X * tUnitX + elemRect.TopLeft.Y * tUnitY, clrElementBg),
                                           new VertexC1P3(metricsOffset + lineOffset + posTemp + elemRect.BottomLeft.X * tUnitX + elemRect.BottomLeft.Y * tUnitY, clrElementBg),
                                           new VertexC1P3(metricsOffset + lineOffset + posTemp + elemRect.BottomRight.X * tUnitX + elemRect.BottomRight.Y * tUnitY, clrElementBg),
                                           new VertexC1P3(metricsOffset + lineOffset + posTemp + elemRect.TopRight.X * tUnitX + elemRect.TopRight.Y * tUnitY, clrElementBg));
                    }
                }
            }

            ColorRgba matColor = this.customMat != null ? this.customMat.MainColor : ColorRgba.White;

            int[] vertLen = this.text.EmitVertices(ref this.vertFont, ref this.vertIcon, posTemp.X, posTemp.Y, posTemp.Z + this.VertexZOffset, this.colorTint * matColor, xDot, yDot);
            if (this.text.Fonts != null)
            {
                for (int i = 0; i < this.text.Fonts.Length; i++)
                {
                    if (this.text.Fonts[i] != null && this.text.Fonts[i].IsAvailable)
                    {
                        if (this.customMat == null)
                        {
                            device.AddVertices(this.text.Fonts[i].Res.Material, VertexMode.Quads, this.vertFont[i], vertLen[i + 1]);
                        }
                        else
                        {
                            BatchInfo cm = new BatchInfo(this.customMat);
                            cm.Textures = this.text.Fonts[i].Res.Material.Textures;
                            device.AddVertices(cm, VertexMode.Quads, this.vertFont[i], vertLen[i + 1]);
                        }
                    }
                }
            }
            if (this.text.Icons != null && this.iconMat.IsAvailable)
            {
                device.AddVertices(this.iconMat, VertexMode.Quads, this.vertIcon, vertLen[0]);
            }
        }
Exemple #27
0
        void IGraphicsBackend.BeginRendering(IDrawDevice device, RenderOptions options, RenderStats stats)
        {
            DebugCheckOpenGLErrors();
            this.CheckRenderingCapabilities();

            this.currentDevice = device;
            this.renderOptions = options;
            this.renderStats   = stats;

            // Prepare a shared index buffer object, in case we don't have one yet
            if (this.sharedBatchIBO == null)
            {
                this.sharedBatchIBO = new NativeGraphicsBuffer(GraphicsBufferType.Index);
            }

            // Prepare the target surface for rendering
            NativeRenderTarget.Bind(options.Target as NativeRenderTarget);

            // Determine whether masked blending should use alpha-to-coverage mode
            if (this.msaaIsDriverDisabled)
            {
                this.useAlphaToCoverageBlend = false;
            }
            else if (NativeRenderTarget.BoundRT != null)
            {
                this.useAlphaToCoverageBlend = NativeRenderTarget.BoundRT.Samples > 0;
            }
            else if (this.activeWindow != null)
            {
                this.useAlphaToCoverageBlend = this.activeWindow.IsMultisampled;
            }
            else
            {
                this.useAlphaToCoverageBlend = this.defaultGraphicsMode.Samples > 0;
            }

            // Determine the available size on the active rendering surface
            Point2 availableSize;

            if (NativeRenderTarget.BoundRT != null)
            {
                availableSize = new Point2(NativeRenderTarget.BoundRT.Width, NativeRenderTarget.BoundRT.Height);
            }
            else if (this.activeWindow != null)
            {
                availableSize = new Point2(this.activeWindow.Width, this.activeWindow.Height);
            }
            else
            {
                availableSize = this.externalBackbufferSize;
            }

            // Translate viewport coordinates to OpenGL screen coordinates (borrom-left, rising), unless rendering
            // to a texture, which is laid out Duality-like (top-left, descending)
            Rect openGLViewport = options.Viewport;

            if (NativeRenderTarget.BoundRT == null)
            {
                openGLViewport.Y = (availableSize.Y - openGLViewport.H) - openGLViewport.Y;
            }

            // Setup viewport and scissor rects
            GL.Viewport((int)openGLViewport.X, (int)openGLViewport.Y, (int)MathF.Ceiling(openGLViewport.W), (int)MathF.Ceiling(openGLViewport.H));
            GL.Scissor((int)openGLViewport.X, (int)openGLViewport.Y, (int)MathF.Ceiling(openGLViewport.W), (int)MathF.Ceiling(openGLViewport.H));

            // Clear buffers
            ClearBufferMask glClearMask = 0;
            ColorRgba       clearColor  = options.ClearColor;

            if ((options.ClearFlags & ClearFlag.Color) != ClearFlag.None)
            {
                glClearMask |= ClearBufferMask.ColorBufferBit;
            }
            if ((options.ClearFlags & ClearFlag.Depth) != ClearFlag.None)
            {
                glClearMask |= ClearBufferMask.DepthBufferBit;
            }
            GL.ClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f, clearColor.A / 255.0f);
            GL.ClearDepth((double)options.ClearDepth);             // The "float version" is from OpenGL 4.1..
            GL.Clear(glClearMask);

            // Configure Rendering params
            GL.Enable(EnableCap.ScissorTest);
            GL.Enable(EnableCap.DepthTest);
            if (options.DepthTest)
            {
                GL.DepthFunc(DepthFunction.Lequal);
            }
            else
            {
                GL.DepthFunc(DepthFunction.Always);
            }

            // Prepare shared matrix stack for rendering
            Matrix4 viewMatrix       = options.ViewMatrix;
            Matrix4 projectionMatrix = options.ProjectionMatrix;

            if (NativeRenderTarget.BoundRT != null)
            {
                Matrix4 flipOutput = Matrix4.CreateScale(1.0f, -1.0f, 1.0f);
                projectionMatrix = projectionMatrix * flipOutput;
            }

            this.renderOptions.ShaderParameters.Set(
                BuiltinShaderFields.ViewMatrix,
                viewMatrix);
            this.renderOptions.ShaderParameters.Set(
                BuiltinShaderFields.ProjectionMatrix,
                projectionMatrix);
            this.renderOptions.ShaderParameters.Set(
                BuiltinShaderFields.ViewProjectionMatrix,
                viewMatrix * projectionMatrix);
        }
Exemple #28
0
 /// <summary>
 /// Prepares rendering using this DrawTechnique.
 /// </summary>
 /// <param name="device"></param>
 /// <param name="material"></param>
 protected virtual void PrepareRendering(IDrawDevice device, BatchInfo material)
 {
 }
Exemple #29
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();
                }
            }
        }
Exemple #30
0
 /// <summary>
 /// Performs a preprocessing operation for incoming vertices. Does nothing by default but may be overloaded, if needed.
 /// </summary>
 /// <typeparam name="T">The incoming vertex type</typeparam>
 /// <param name="device"></param>
 /// <param name="material"><see cref="Duality.Resources.Material"/> information for the current batch.</param>
 /// <param name="vertexMode">The mode of incoming vertex data.</param>
 /// <param name="vertexBuffer">A buffer storing incoming vertex data.</param>
 /// <param name="vertexCount">The number of vertices to preprocess, beginning at the start of the specified buffer.</param>
 public virtual void PreprocessBatch <T>(IDrawDevice device, BatchInfo material, ref VertexMode vertexMode, ref T[] vertexBuffer, ref int vertexCount)
 {
 }
        public override void OnPaint(Canvas canvas, Rect view)
        {
            IDrawDevice device = canvas.DrawDevice;

            Vector2 center = device.TargetSize * 0.5f;

            center.Y *= 0.8f;

            string selectedDifficultyImage = GetDifficultyImage(selectedPlayerType);

            api.DrawMaterial("MenuDim", center.X * 0.36f, center.Y * 1.4f, Alignment.Center, ColorRgba.White, 24f, 36f);

            api.DrawMaterial(selectedDifficultyImage, selectedDifficulty, center.X * 0.36f, center.Y * 1.4f + 3f, Alignment.Center, new ColorRgba(0f, 0.2f * imageTransition), 0.88f, 0.88f);

            if (imageTransition < 1f)
            {
                string lastDifficultyImage = GetDifficultyImage(lastPlayerType);
                api.DrawMaterial(lastDifficultyImage, lastDifficulty, center.X * 0.36f, center.Y * 1.4f, Alignment.Center, new ColorRgba(1f, 1f - imageTransition), 0.88f, 0.88f);
            }

            api.DrawMaterial(selectedDifficultyImage, selectedDifficulty, center.X * 0.36f, center.Y * 1.4f, Alignment.Center, new ColorRgba(1f, imageTransition), 0.88f, 0.88f);

            int charOffset = 0;

            for (int i = 0; i < items.Length; i++)
            {
                if (selectedIndex == i)
                {
                    float size = 0.5f + Ease.OutElastic(animation) * 0.6f;

                    api.DrawMaterial("MenuGlow", center.X, center.Y, Alignment.Center, ColorRgba.White.WithAlpha(0.4f * size), (items[i].Length + 3) * 0.5f * size, 4f * size);

                    api.DrawStringShadow(ref charOffset, items[i], center.X, center.Y,
                                         Alignment.Center, null, size, 0.7f, 1.1f, 1.1f, charSpacing: 0.9f);
                }
                else
                {
                    api.DrawString(ref charOffset, items[i], center.X, center.Y, Alignment.Center,
                                   ColorRgba.TransparentBlack, 0.9f);
                }

                if (i == 0)
                {
                    string[]    playerTypes  = { "Jazz", "Spaz", "Lori" };
                    ColorRgba[] playerColors =
                    {
                        new ColorRgba(0.2f,  0.45f,  0.2f, 0.5f),
                        new ColorRgba(0.45f, 0.27f, 0.22f, 0.5f),
                        new ColorRgba(0.5f,  0.45f, 0.22f, 0.5f)
                    };

                    float offset, spacing;
                    if (availableCharacters == 1)
                    {
                        offset  = 0f;
                        spacing = 0f;
                    }
                    else if (availableCharacters == 2)
                    {
                        offset  = 50f;
                        spacing = 100f;
                    }
                    else
                    {
                        offset  = 100f;
                        spacing = 300f / availableCharacters;
                    }

                    for (int j = 0; j < availableCharacters; j++)
                    {
                        float x = center.X - offset + j * spacing;
                        if (selectedPlayerType == j)
                        {
                            api.DrawMaterial("MenuGlow", x, center.Y + 28f, Alignment.Center, ColorRgba.White.WithAlpha(0.2f), (playerTypes[j].Length + 3) * 0.4f, 2.2f);

                            api.DrawStringShadow(ref charOffset, playerTypes[j], x, center.Y + 28f, Alignment.Center,
                                                 playerColors[j], 0.9f, 0.4f, 0.55f, 0.55f, 8f, 0.9f);
                        }
                        else
                        {
                            api.DrawString(ref charOffset, playerTypes[j], x, center.Y + 28f, Alignment.Center,
                                           ColorRgba.TransparentBlack, 0.8f, charSpacing: 0.9f);
                        }
                    }

                    api.DrawStringShadow(ref charOffset, "<", center.X - (100f + 40f), center.Y + 28f, Alignment.Center,
                                         ColorRgba.TransparentBlack, 0.7f);
                    api.DrawStringShadow(ref charOffset, ">", center.X + (100f + 40f), center.Y + 28f, Alignment.Center,
                                         ColorRgba.TransparentBlack, 0.7f);
                }
                else if (i == 1)
                {
                    for (int j = 0; j < difficultyTypes.Length; j++)
                    {
                        if (selectedDifficulty == j)
                        {
                            api.DrawMaterial("MenuGlow", center.X + (j - 1) * 100f, center.Y + 28f, Alignment.Center, ColorRgba.White.WithAlpha(0.2f), (difficultyTypes[j].Length + 3) * 0.4f, 2.2f);

                            api.DrawStringShadow(ref charOffset, difficultyTypes[j], center.X + (j - 1) * 100f, center.Y + 28f, Alignment.Center,
                                                 null, 0.9f, 0.4f, 0.55f, 0.55f, 8f, 0.9f);
                        }
                        else
                        {
                            api.DrawString(ref charOffset, difficultyTypes[j], center.X + (j - 1) * 100f, center.Y + 28f, Alignment.Center,
                                           ColorRgba.TransparentBlack, 0.8f, charSpacing: 0.9f);
                        }
                    }

                    api.DrawStringShadow(ref charOffset, "<", center.X - (100f + 40f), center.Y + 28f, Alignment.Center,
                                         ColorRgba.TransparentBlack, 0.7f);
                    api.DrawStringShadow(ref charOffset, ">", center.X + (100f + 40f), center.Y + 28f, Alignment.Center,
                                         ColorRgba.TransparentBlack, 0.7f);
                }

                center.Y += 70f;
            }

            if (imageTransition < 1f)
            {
                imageTransition += Time.TimeMult * 0.1f;

                if (imageTransition > 1f)
                {
                    imageTransition = 1f;
                }
            }
        }
Exemple #32
0
        public override void Draw(IDrawDevice device)
        {
            // Determine basic working data
            Tilemap tilemap   = this.ActiveTilemap;
            Tileset tileset   = tilemap != null ? tilemap.Tileset.Res : null;
            Point2  tileCount = tilemap != null ? tilemap.Size : new Point2(1, 1);
            Vector2 tileSize  = tileset != null ? tileset.TileSize : Tileset.DefaultTileSize;

            // Early-out, if insufficient
            if (tilemap == null)
            {
                return;
            }
            if (tileset == null)
            {
                return;
            }

            // Determine the total size and origin of the rendered Tilemap
            Vector2 renderTotalSize = tileCount * tileSize;
            Vector2 renderOrigin    = Vector2.Zero;

            this.origin.ApplyTo(ref renderOrigin, ref renderTotalSize);
            MathF.TransformCoord(ref renderOrigin.X, ref renderOrigin.Y, this.GameObj.Transform.Angle, this.GameObj.Transform.Scale);

            // Determine Tile visibility
            TilemapCulling.TileInput cullingIn = new TilemapCulling.TileInput
            {
                // Remember: All these transform values are in world space
                TilemapPos   = this.GameObj.Transform.Pos + new Vector3(renderOrigin),
                TilemapScale = this.GameObj.Transform.Scale,
                TilemapAngle = this.GameObj.Transform.Angle,
                TileCount    = tileCount,
                TileSize     = tileSize
            };
            TilemapCulling.TileOutput cullingOut = TilemapCulling.GetVisibleTileRect(device, cullingIn);
            int renderedTileCount = cullingOut.VisibleTileCount.X * cullingOut.VisibleTileCount.Y;

            // Determine rendering parameters
            Material  material  = (tileset != null ? tileset.RenderMaterial : null) ?? Material.Checkerboard.Res;
            ColorRgba mainColor = material.MainColor * this.colorTint;

            // Reserve the required space for vertex data in our locally cached buffer
            if (this.vertices == null)
            {
                this.vertices = new RawList <VertexC1P3T2>();
            }
            this.vertices.Count = renderedTileCount * 4;
            VertexC1P3T2[] vertexData = this.vertices.Data;

            // Determine and adjust data for Z offset generation
            float depthPerTile = -cullingIn.TileSize.Y * cullingIn.TilemapScale * this.tileDepthScale;

            if (this.tileDepthMode == TileDepthOffsetMode.Flat)
            {
                depthPerTile = 0.0f;
            }

            float originDepthOffset = Rect.Align(this.origin, 0, 0, 0, tileCount.Y * depthPerTile).Y;

            if (this.tileDepthMode == TileDepthOffsetMode.World)
            {
                originDepthOffset += (this.GameObj.Transform.Pos.Y / (float)tileSize.Y) * depthPerTile;
            }

            cullingOut.RenderOriginView.Z += this.offset + this.tileDepthOffset * depthPerTile + originDepthOffset;

            // Prepare vertex generation data
            Vector2 tileXStep   = cullingOut.XAxisView * cullingIn.TileSize.X;
            Vector2 tileYStep   = cullingOut.YAxisView * cullingIn.TileSize.Y;
            Vector3 renderPos   = cullingOut.RenderOriginView;
            Point2  tileGridPos = cullingOut.VisibleTileStart;

            // Prepare vertex data array for batch-submitting
            IReadOnlyGrid <Tile> tiles = tilemap.Tiles;

            TileInfo[] tileData           = tileset.TileData.Data;
            int        submittedTileCount = 0;
            int        vertexBaseIndex    = 0;

            for (int tileIndex = 0; tileIndex < renderedTileCount; tileIndex++)
            {
                Tile tile = tiles[tileGridPos.X, tileGridPos.Y];
                if (tile.Index < tileData.Length)
                {
                    Rect  uvRect           = tileData[tile.Index].TexCoord0;
                    bool  visualEmpty      = tileData[tile.Index].IsVisuallyEmpty;
                    int   tileBaseOffset   = tileData[tile.Index].DepthOffset;
                    float localDepthOffset = (tile.DepthOffset + tileBaseOffset) * depthPerTile;

                    if (!visualEmpty)
                    {
                        vertexData[vertexBaseIndex + 0].Pos.X      = renderPos.X;
                        vertexData[vertexBaseIndex + 0].Pos.Y      = renderPos.Y;
                        vertexData[vertexBaseIndex + 0].Pos.Z      = renderPos.Z + localDepthOffset;
                        vertexData[vertexBaseIndex + 0].TexCoord.X = uvRect.X;
                        vertexData[vertexBaseIndex + 0].TexCoord.Y = uvRect.Y;
                        vertexData[vertexBaseIndex + 0].Color      = mainColor;

                        vertexData[vertexBaseIndex + 1].Pos.X      = renderPos.X + tileYStep.X;
                        vertexData[vertexBaseIndex + 1].Pos.Y      = renderPos.Y + tileYStep.Y;
                        vertexData[vertexBaseIndex + 1].Pos.Z      = renderPos.Z + localDepthOffset + depthPerTile;
                        vertexData[vertexBaseIndex + 1].TexCoord.X = uvRect.X;
                        vertexData[vertexBaseIndex + 1].TexCoord.Y = uvRect.Y + uvRect.H;
                        vertexData[vertexBaseIndex + 1].Color      = mainColor;

                        vertexData[vertexBaseIndex + 2].Pos.X      = renderPos.X + tileXStep.X + tileYStep.X;
                        vertexData[vertexBaseIndex + 2].Pos.Y      = renderPos.Y + tileXStep.Y + tileYStep.Y;
                        vertexData[vertexBaseIndex + 2].Pos.Z      = renderPos.Z + localDepthOffset + depthPerTile;
                        vertexData[vertexBaseIndex + 2].TexCoord.X = uvRect.X + uvRect.W;
                        vertexData[vertexBaseIndex + 2].TexCoord.Y = uvRect.Y + uvRect.H;
                        vertexData[vertexBaseIndex + 2].Color      = mainColor;

                        vertexData[vertexBaseIndex + 3].Pos.X      = renderPos.X + tileXStep.X;
                        vertexData[vertexBaseIndex + 3].Pos.Y      = renderPos.Y + tileXStep.Y;
                        vertexData[vertexBaseIndex + 3].Pos.Z      = renderPos.Z + localDepthOffset;
                        vertexData[vertexBaseIndex + 3].TexCoord.X = uvRect.X + uvRect.W;
                        vertexData[vertexBaseIndex + 3].TexCoord.Y = uvRect.Y;
                        vertexData[vertexBaseIndex + 3].Color      = mainColor;

                        bool vertical = tileData[tile.Index].IsVertical;
                        if (vertical)
                        {
                            vertexData[vertexBaseIndex + 0].Pos.Z += depthPerTile;
                            vertexData[vertexBaseIndex + 3].Pos.Z += depthPerTile;
                        }

                        submittedTileCount++;
                        vertexBaseIndex += 4;
                    }
                }

                tileGridPos.X++;
                renderPos.X += tileXStep.X;
                renderPos.Y += tileXStep.Y;
                if ((tileGridPos.X - cullingOut.VisibleTileStart.X) >= cullingOut.VisibleTileCount.X)
                {
                    tileGridPos.X = cullingOut.VisibleTileStart.X;
                    tileGridPos.Y++;
                    renderPos    = cullingOut.RenderOriginView;
                    renderPos.X += tileYStep.X * (tileGridPos.Y - cullingOut.VisibleTileStart.Y);
                    renderPos.Y += tileYStep.Y * (tileGridPos.Y - cullingOut.VisibleTileStart.Y);
                    renderPos.Z += tileGridPos.Y * depthPerTile;
                }
            }

            // Submit all the vertices as one draw batch
            device.AddVertices(
                material,
                VertexMode.Quads,
                vertexData,
                submittedTileCount * 4);

            Profile.AddToStat(@"Duality\Stats\Render\Tilemaps\NumTiles", renderedTileCount);
            Profile.AddToStat(@"Duality\Stats\Render\Tilemaps\NumVertices", submittedTileCount * 4);
        }
Exemple #33
0
        protected void PrepareVerticesSmooth(ref VertexC1P3T4A1[] vertices, IDrawDevice device, float curAnimFrameFade, ColorRgba mainClr, Rect uvRect, Rect uvRectNext)
        {
            Vector3 posTemp   = this.gameobj.Transform.Pos;
            float   scaleTemp = 1.0f;

            device.PreprocessCoords(ref posTemp, ref scaleTemp);

            Vector2 xDot, yDot;

            MathF.GetTransformDotVec(this.GameObj.Transform.Angle, scaleTemp, 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);

            if (vertices == null || vertices.Length != 4)
            {
                vertices = new VertexC1P3T4A1[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].TexCoord.Z = uvRectNext.X;
            vertices[0].TexCoord.W = uvRectNext.Y;
            vertices[0].Color      = mainClr;
            vertices[0].Attrib     = 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 = uvRect.X;
            vertices[1].TexCoord.Y = uvRect.MaximumY;
            vertices[1].TexCoord.Z = uvRectNext.X;
            vertices[1].TexCoord.W = uvRectNext.MaximumY;
            vertices[1].Color      = mainClr;
            vertices[1].Attrib     = 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 = uvRect.MaximumX;
            vertices[2].TexCoord.Y = uvRect.MaximumY;
            vertices[2].TexCoord.Z = uvRectNext.MaximumX;
            vertices[2].TexCoord.W = uvRectNext.MaximumY;
            vertices[2].Color      = mainClr;
            vertices[2].Attrib     = 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 = uvRect.MaximumX;
            vertices[3].TexCoord.Y = uvRect.Y;
            vertices[3].TexCoord.Z = uvRectNext.MaximumX;
            vertices[3].TexCoord.W = uvRectNext.Y;
            vertices[3].Color      = mainClr;
            vertices[3].Attrib     = 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;
                }
            }
        }
Exemple #34
0
        public override void Draw(IDrawDevice device)
        {
            // Determine basic working data
            Tilemap tilemap = this.ActiveTilemap;
            Tileset tileset = tilemap != null ? tilemap.Tileset.Res : null;
            Point2 tileCount = tilemap != null ? tilemap.Size : new Point2(1, 1);
            Vector2 tileSize = tileset != null ? tileset.TileSize : Tileset.DefaultTileSize;

            // Early-out, if insufficient
            if (tilemap == null) return;
            if (tileset == null) return;

            // Determine the total size and origin of the rendered Tilemap
            Vector2 renderTotalSize = tileCount * tileSize;
            Vector2 renderOrigin = Vector2.Zero;
            this.origin.ApplyTo(ref renderOrigin, ref renderTotalSize);
            MathF.TransformCoord(ref renderOrigin.X, ref renderOrigin.Y, this.GameObj.Transform.Angle, this.GameObj.Transform.Scale);

            // Determine Tile visibility
            TilemapCulling.TileInput cullingIn = new TilemapCulling.TileInput
            {
                // Remember: All these transform values are in world space
                TilemapPos = this.GameObj.Transform.Pos + new Vector3(renderOrigin),
                TilemapScale = this.GameObj.Transform.Scale,
                TilemapAngle = this.GameObj.Transform.Angle,
                TileCount = tileCount,
                TileSize = tileSize
            };
            TilemapCulling.TileOutput cullingOut = TilemapCulling.GetVisibleTileRect(device, cullingIn);
            int renderedTileCount = cullingOut.VisibleTileCount.X * cullingOut.VisibleTileCount.Y;

            // Determine rendering parameters
            Material material = (tileset != null ? tileset.RenderMaterial : null) ?? Material.Checkerboard.Res;
            ColorRgba mainColor = material.MainColor * this.colorTint;

            // Reserve the required space for vertex data in our locally cached buffer
            if (this.vertices == null) this.vertices = new RawList<VertexC1P3T2>();
            this.vertices.Count = renderedTileCount * 4;
            VertexC1P3T2[] vertexData = this.vertices.Data;

            // Determine and adjust data for Z offset generation
            float depthPerTile = -cullingIn.TileSize.Y * cullingIn.TilemapScale * this.tileDepthScale;

            if (this.tileDepthMode == TileDepthOffsetMode.Flat)
                depthPerTile = 0.0f;

            float originDepthOffset = Rect.Align(this.origin, 0, 0, 0, tileCount.Y * depthPerTile).Y;

            if (this.tileDepthMode == TileDepthOffsetMode.World)
                originDepthOffset += (this.GameObj.Transform.Pos.Y / (float)tileSize.Y) * depthPerTile;

            cullingOut.RenderOriginView.Z += this.offset + this.tileDepthOffset * depthPerTile + originDepthOffset;

            // Prepare vertex generation data
            Vector2 tileXStep = cullingOut.XAxisView * cullingIn.TileSize.X;
            Vector2 tileYStep = cullingOut.YAxisView * cullingIn.TileSize.Y;
            Vector3 renderPos = cullingOut.RenderOriginView;
            Point2 tileGridPos = cullingOut.VisibleTileStart;

            // Prepare vertex data array for batch-submitting
            IReadOnlyGrid<Tile> tiles = tilemap.Tiles;
            TileInfo[] tileData = tileset.TileData.Data;
            int submittedTileCount = 0;
            int vertexBaseIndex = 0;
            for (int tileIndex = 0; tileIndex < renderedTileCount; tileIndex++)
            {
                Tile tile = tiles[tileGridPos.X, tileGridPos.Y];
                if (tile.Index < tileData.Length)
                {
                    Rect uvRect = tileData[tile.Index].TexCoord0;
                    bool visualEmpty = tileData[tile.Index].IsVisuallyEmpty;
                    int tileBaseOffset = tileData[tile.Index].DepthOffset;
                    float localDepthOffset = (tile.DepthOffset + tileBaseOffset) * depthPerTile;

                    if (!visualEmpty)
                    {
                        vertexData[vertexBaseIndex + 0].Pos.X = renderPos.X;
                        vertexData[vertexBaseIndex + 0].Pos.Y = renderPos.Y;
                        vertexData[vertexBaseIndex + 0].Pos.Z = renderPos.Z + localDepthOffset;
                        vertexData[vertexBaseIndex + 0].TexCoord.X = uvRect.X;
                        vertexData[vertexBaseIndex + 0].TexCoord.Y = uvRect.Y;
                        vertexData[vertexBaseIndex + 0].Color = mainColor;

                        vertexData[vertexBaseIndex + 1].Pos.X = renderPos.X + tileYStep.X;
                        vertexData[vertexBaseIndex + 1].Pos.Y = renderPos.Y + tileYStep.Y;
                        vertexData[vertexBaseIndex + 1].Pos.Z = renderPos.Z + localDepthOffset + depthPerTile;
                        vertexData[vertexBaseIndex + 1].TexCoord.X = uvRect.X;
                        vertexData[vertexBaseIndex + 1].TexCoord.Y = uvRect.Y + uvRect.H;
                        vertexData[vertexBaseIndex + 1].Color = mainColor;

                        vertexData[vertexBaseIndex + 2].Pos.X = renderPos.X + tileXStep.X + tileYStep.X;
                        vertexData[vertexBaseIndex + 2].Pos.Y = renderPos.Y + tileXStep.Y + tileYStep.Y;
                        vertexData[vertexBaseIndex + 2].Pos.Z = renderPos.Z + localDepthOffset + depthPerTile;
                        vertexData[vertexBaseIndex + 2].TexCoord.X = uvRect.X + uvRect.W;
                        vertexData[vertexBaseIndex + 2].TexCoord.Y = uvRect.Y + uvRect.H;
                        vertexData[vertexBaseIndex + 2].Color = mainColor;

                        vertexData[vertexBaseIndex + 3].Pos.X = renderPos.X + tileXStep.X;
                        vertexData[vertexBaseIndex + 3].Pos.Y = renderPos.Y + tileXStep.Y;
                        vertexData[vertexBaseIndex + 3].Pos.Z = renderPos.Z + localDepthOffset;
                        vertexData[vertexBaseIndex + 3].TexCoord.X = uvRect.X + uvRect.W;
                        vertexData[vertexBaseIndex + 3].TexCoord.Y = uvRect.Y;
                        vertexData[vertexBaseIndex + 3].Color = mainColor;

                        bool vertical = tileData[tile.Index].IsVertical;
                        if (vertical)
                        {
                            vertexData[vertexBaseIndex + 0].Pos.Z += depthPerTile;
                            vertexData[vertexBaseIndex + 3].Pos.Z += depthPerTile;
                        }

                        submittedTileCount++;
                        vertexBaseIndex += 4;
                    }
                }

                tileGridPos.X++;
                renderPos.X += tileXStep.X;
                renderPos.Y += tileXStep.Y;
                if ((tileGridPos.X - cullingOut.VisibleTileStart.X) >= cullingOut.VisibleTileCount.X)
                {
                    tileGridPos.X = cullingOut.VisibleTileStart.X;
                    tileGridPos.Y++;
                    renderPos = cullingOut.RenderOriginView;
                    renderPos.X += tileYStep.X * (tileGridPos.Y - cullingOut.VisibleTileStart.Y);
                    renderPos.Y += tileYStep.Y * (tileGridPos.Y - cullingOut.VisibleTileStart.Y);
                    renderPos.Z += tileGridPos.Y * depthPerTile;
                }
            }

            // Submit all the vertices as one draw batch
            device.AddVertices(
                material,
                VertexMode.Quads,
                vertexData,
                submittedTileCount * 4);

            Profile.AddToStat(@"Duality\Stats\Render\Tilemaps\NumTiles", renderedTileCount);
            Profile.AddToStat(@"Duality\Stats\Render\Tilemaps\NumVertices", submittedTileCount * 4);
        }
Exemple #35
0
		void ICmpRenderer.Draw(IDrawDevice device)
		{
			Profile.BeginMeasure(@"ProfileRenderer");
			Canvas canvas = new Canvas(device);
			canvas.CurrentState.SetMaterial(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White, null));
			
			bool anyTextReport = this.textReportPerf || this.textReportStat;
			bool anyGraph = this.drawGraphs && this.counterGraphs.Count > 0;

			// Determine geometry
			int areaWidth = (int)device.TargetSize.X - 20;
			if (anyGraph && anyTextReport)
				areaWidth = (areaWidth - 10) / 2;
			Rect textReportRect = new Rect(
				10, 
				10, 
				anyTextReport ? areaWidth : 0, 
				(int)device.TargetSize.Y - 20);
			Rect graphRect = new Rect(
				anyTextReport ? (textReportRect.MaximumX + 10) : 10, 
				10, 
				anyGraph ? areaWidth : 0, 
				(int)device.TargetSize.Y - 20);

			// Text Reports
			if (anyTextReport)
			{
				// Update Report
				IEnumerable<ProfileCounter> counters = Profile.GetUsedCounters();
				if (!this.textReportPerf) counters = counters.Where(c => !(c is TimeCounter));
				if (!this.textReportStat) counters = counters.Where(c => !(c is StatCounter));
				if (this.textReport == null || (Time.MainTimer - this.textReportLast).TotalMilliseconds > this.updateInterval)
				{
					string report = Profile.GetTextReport(counters, this.textReportOptions | ReportOptions.FormattedText);

					if (this.textReport == null)
					{
						this.textReport = new FormattedText();
						this.textReport.Fonts = new[] { Font.GenericMonospace8 };
					}
					this.textReport.MaxWidth = (int)textReportRect.W;
					this.textReport.SourceText = report;
					this.textReportLast = Time.MainTimer;
				}

				// Draw Report
				canvas.DrawTextBackground(textReport, textReportRect.X, textReportRect.Y);
				canvas.DrawText(textReport, ref textReportTextVert, ref textReportIconVert, textReportRect.X, textReportRect.Y);
			}

			// Counter Graphs
			if (anyGraph)
			{
				// Mark graph cache as unused
				foreach (GraphCacheEntry entry in this.graphCache.Values)
				{
					entry.WasUsed = false;
				}

				int space = 5;
				int graphY = (int)graphRect.Y;
				int graphH = MathF.Min((int)(graphRect.H / this.counterGraphs.Count) - space, (int)graphRect.W / 2);
				foreach (string counterName in this.counterGraphs)
				{
					ProfileCounter counter = Profile.GetCounter<ProfileCounter>(counterName);
					if (counter == null) return;

					// Create or retrieve graph cache entry
					GraphCacheEntry cache = null;
					if (!this.graphCache.TryGetValue(counterName, out cache))
					{
						cache = new GraphCacheEntry();
						cache.GraphValues = new float[ProfileCounter.ValueHistoryLen];
						cache.GraphColors = new ColorRgba[ProfileCounter.ValueHistoryLen];
						this.graphCache[counterName] = cache;
					}
					cache.WasUsed = true;

					float cursorRatio = 0.0f;
					if (counter is TimeCounter)
					{
						TimeCounter timeCounter = counter as TimeCounter;
						for (int i = 0; i < ProfileCounter.ValueHistoryLen; i++)
						{
							float factor = timeCounter.ValueGraph[i] / Time.MsPFMult;
							cache.GraphValues[i] = factor * 0.75f;
							cache.GraphColors[i] = ColorRgba.Lerp(ColorRgba.White, ColorRgba.Red, factor);
						}
						canvas.CurrentState.ColorTint = ColorRgba.Black.WithAlpha(0.5f);
						canvas.FillRect(graphRect.X, graphY, graphRect.W, graphH);
						canvas.CurrentState.ColorTint = ColorRgba.White;
						canvas.DrawHorizontalGraph(cache.GraphValues, cache.GraphColors, ref cache.VertGraph, graphRect.X, graphY, graphRect.W, graphH);
						cursorRatio = (float)timeCounter.ValueGraphCursor / (float)ProfileCounter.ValueHistoryLen;
					}
					else if (counter is StatCounter)
					{
						StatCounter statCounter = counter as StatCounter;
						for (int i = 0; i < ProfileCounter.ValueHistoryLen; i++)
						{
							cache.GraphValues[i] = (float)(statCounter.ValueGraph[i] - statCounter.MinValue) / statCounter.MaxValue;
							cache.GraphColors[i] = ColorRgba.White;
						}
						canvas.CurrentState.ColorTint = ColorRgba.Black.WithAlpha(0.5f);
						canvas.FillRect(graphRect.X, graphY, graphRect.W, graphH);
						canvas.CurrentState.ColorTint = ColorRgba.White;
						canvas.DrawHorizontalGraph(cache.GraphValues, cache.GraphColors, ref cache.VertGraph, graphRect.X, graphY, graphRect.W, graphH);
						cursorRatio = (float)statCounter.ValueGraphCursor / (float)ProfileCounter.ValueHistoryLen;
					}
					
					canvas.DrawText(new string[] { counter.FullName }, ref cache.VertText, graphRect.X, graphY);
					canvas.DrawLine(graphRect.X + graphRect.W * cursorRatio, graphY, graphRect.X + graphRect.W * cursorRatio, graphY + graphH);

					graphY += graphH + space;
				}

				// Remove unused graph cache entries
				foreach (var pair in this.graphCache.ToArray())
				{
					if (!pair.Value.WasUsed)
					{
						pair.Value.GraphColors = null;
						pair.Value.GraphValues = null;
						pair.Value.VertGraph = null;
						pair.Value.VertText = null;
						this.graphCache.Remove(pair.Key);
					}
				}
			}

			Profile.EndMeasure(@"ProfileRenderer");
		}
Exemple #36
0
        void IGraphicsBackend.BeginRendering(IDrawDevice device, RenderOptions options, RenderStats stats)
        {
            this.currentDevice = device;
            this.renderStats   = stats;

            // Prepare the target surface for rendering
            NativeRenderTarget.Bind(options.Target as NativeRenderTarget);

            if (this.primaryVBO == 0)
            {
                GL.GenBuffers(1, out this.primaryVBO);
            }
            GL.BindBuffer(BufferTarget.ArrayBuffer, this.primaryVBO);

            // Setup viewport
            Rect viewportRect = options.Viewport;

            GL.Viewport((int)viewportRect.X, (int)viewportRect.Y, (int)viewportRect.W, (int)viewportRect.H);
            GL.Scissor((int)viewportRect.X, (int)viewportRect.Y, (int)viewportRect.W, (int)viewportRect.H);

            // Clear buffers
            ClearBufferMask glClearMask = 0;
            ColorRgba       clearColor  = options.ClearColor;

            if ((options.ClearFlags & ClearFlag.Color) != ClearFlag.None)
            {
                glClearMask |= ClearBufferMask.ColorBufferBit;
            }
            if ((options.ClearFlags & ClearFlag.Depth) != ClearFlag.None)
            {
                glClearMask |= ClearBufferMask.DepthBufferBit;
            }
            GL.ClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f, clearColor.A / 255.0f);
            GL.ClearDepth((double)options.ClearDepth);             // The "float version" is from OpenGL 4.1..
            GL.Clear(glClearMask);

            // Configure Rendering params
            if (options.RenderMode == RenderMatrix.OrthoScreen)
            {
                GL.Enable(EnableCap.ScissorTest);
                GL.Enable(EnableCap.DepthTest);
                GL.DepthFunc(DepthFunction.Always);
            }
            else
            {
                GL.Enable(EnableCap.ScissorTest);
                GL.Enable(EnableCap.DepthTest);
                GL.DepthFunc(DepthFunction.Lequal);
            }

            OpenTK.Matrix4 openTkModelView;
            Matrix4        modelView = options.ModelViewMatrix;

            GetOpenTKMatrix(ref modelView, out openTkModelView);

            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref openTkModelView);

            OpenTK.Matrix4 openTkProjection;
            Matrix4        projection = options.ProjectionMatrix;

            GetOpenTKMatrix(ref projection, out openTkProjection);

            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref openTkProjection);

            if (NativeRenderTarget.BoundRT != null)
            {
                if (options.RenderMode == RenderMatrix.OrthoScreen)
                {
                    GL.Translate(0.0f, NativeRenderTarget.BoundRT.Height * 0.5f, 0.0f);
                }
                GL.Scale(1.0f, -1.0f, 1.0f);
                if (options.RenderMode == RenderMatrix.OrthoScreen)
                {
                    GL.Translate(0.0f, -NativeRenderTarget.BoundRT.Height * 0.5f, 0.0f);
                }
            }
        }
Exemple #37
0
 /// <summary>
 /// Transforms world space coordinates to screen space coordinates.
 /// </summary>
 /// <param name="spacePos"></param>
 /// <param name="device"></param>
 /// <returns></returns>
 public static Vector3 GetScreenCoord(this IDrawDevice device, Vector2 spacePos)
 {
     return(device.GetScreenCoord(new Vector3(spacePos)));
 }
Exemple #38
0
        void IGraphicsBackend.EndRendering()
        {
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            this.currentDevice = null;
        }
Exemple #39
0
        void ICmpRenderer.Draw(IDrawDevice device)
        {
            Player player     = this.GameObj.ParentScene.FindComponent <Player>();
            Ship   playerShip = player.ControlTarget;

            Canvas canvas = new Canvas(device);

            canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White));

            ColorRgba baseColor    = ColorRgba.White.WithAlpha(this.displayedTeamColor.W);
            ColorRgba defaultColor = this.displayedTeamColor.ToColor().WithAlpha(1.0f) * baseColor;

            if (this.gameOverFade > 0.0f)
            {
                canvas.State.ColorTint = ColorRgba.Black.WithAlpha(this.gameOverFade);
                canvas.FillRect(0.0f, 0.0f, canvas.Width, canvas.Height);
            }

            if (baseColor.A == 0)
            {
                return;
            }
            canvas.State.ColorTint = defaultColor;

            // Health bar
            float healthBarHeight = 150;

            canvas.State.ColorTint = defaultColor * ColorRgba.Black.WithAlpha(0.25f);
            canvas.FillRect(
                10,
                canvas.Height - 10 - healthBarHeight,
                30,
                healthBarHeight);
            canvas.State.ColorTint = defaultColor;
            canvas.DrawRect(
                10,
                canvas.Height - 10 - healthBarHeight,
                30,
                healthBarHeight);
            canvas.FillRect(
                12,
                canvas.Height - 12 - (healthBarHeight - 4) * playerShip.Health,
                26,
                (healthBarHeight - 4) * playerShip.Health);

            // Energy bar
            float energyBarHeight = 150;

            canvas.FillRect(
                10 + 30 + 2,
                canvas.Height - 10 - energyBarHeight * playerShip.WeaponEnergy,
                5,
                energyBarHeight * playerShip.WeaponEnergy);

            // Radar
            float radarDisplayRadius = 100.0f;
            Rect  radarArea          = Rect.Align(
                Alignment.BottomRight,
                canvas.Width - 10,
                canvas.Height - 10,
                radarDisplayRadius * 2.0f,
                radarDisplayRadius * 2.0f);
            float radarRange = 2500.0f;

            canvas.State.ColorTint = defaultColor * ColorRgba.Black.WithAlpha(0.25f);
            canvas.FillOval(
                radarArea.X,
                radarArea.Y,
                radarArea.W,
                radarArea.H);
            foreach (SpawnPoint spawnpoint in player.GameObj.ParentScene.FindComponents <SpawnPoint>())
            {
                Vector3 relativePos   = spawnpoint.GameObj.Transform.Pos - playerShip.GameObj.Transform.Pos;
                Vector3 normalizedPos = relativePos / radarRange;
                if ((normalizedPos * radarDisplayRadius).Xy.Length > radarDisplayRadius - 6.0f)
                {
                    continue;
                }

                Vector2 posOnRadar = radarArea.Center + (normalizedPos * radarDisplayRadius).Xy;

                canvas.State.ColorTint = baseColor * spawnpoint.TeamColor * ColorRgba.Grey;
                canvas.FillCircle(posOnRadar.X, posOnRadar.Y, 6.0f);
            }
            foreach (Ship ship in player.GameObj.ParentScene.FindComponents <Ship>())
            {
                Vector3 relativePos   = ship.GameObj.Transform.Pos - playerShip.GameObj.Transform.Pos;
                Vector3 normalizedPos = relativePos / radarRange;
                if ((normalizedPos * radarDisplayRadius).Xy.Length > radarDisplayRadius - 3.0f)
                {
                    continue;
                }

                Vector2 posOnRadar = radarArea.Center + (normalizedPos * radarDisplayRadius).Xy;

                canvas.State.ColorTint = baseColor * ship.TeamColor;
                canvas.FillCircle(posOnRadar.X, posOnRadar.Y, 3.0f);
            }
            foreach (Laser laser in player.GameObj.ParentScene.FindComponents <Laser>())
            {
                Vector3 relativePos   = laser.GameObj.Transform.Pos - playerShip.GameObj.Transform.Pos;
                Vector3 normalizedPos = relativePos / radarRange;
                if (normalizedPos.Length > 1.0f)
                {
                    continue;
                }

                Vector2 posOnRadar = radarArea.Center + (normalizedPos * radarDisplayRadius).Xy;

                canvas.State.ColorTint = baseColor * laser.TeamColor;
                canvas.FillRect(posOnRadar.X, posOnRadar.Y, 1.0f, 1.0f);
            }
            canvas.State.ColorTint = defaultColor;
            canvas.DrawOval(
                radarArea.X,
                radarArea.Y,
                radarArea.W,
                radarArea.H);

            Vector2 diffToCenter          = -playerShip.GameObj.Transform.Pos.Xy;
            Vector2 dirToCenter           = diffToCenter.Normalized;
            float   centerIndicatorLength = MathF.Min(10.0f, 10.0f * diffToCenter.Length / 2000.0f);

            canvas.State.ColorTint = defaultColor * ColorRgba.White.WithAlpha(0.5f);
            canvas.DrawLine(
                radarArea.CenterX,
                radarArea.CenterY,
                radarArea.CenterX + dirToCenter.X * centerIndicatorLength,
                radarArea.CenterY + dirToCenter.Y * centerIndicatorLength);

            canvas.State.ColorTint = defaultColor;
            canvas.FillCircle(radarArea.CenterX, radarArea.CenterY, 3.0f);
        }
        public override void OnPaint(Canvas canvas, Rect view)
        {
            IDrawDevice device = canvas.DrawDevice;

            Vector2 center = device.TargetSize * 0.5f;

            const float topLine    = 131f;
            float       bottomLine = device.TargetSize.Y - 42;

            api.DrawMaterial("MenuDim", center.X, (topLine + bottomLine) * 0.5f, Alignment.Center, ColorRgba.White, 55f, (bottomLine - topLine) * 0.063f, new Rect(0f, 0.3f, 1f, 0.4f));

            api.DrawMaterial("MenuLine", 0, center.X, topLine, Alignment.Center, ColorRgba.White, 1.6f);
            api.DrawMaterial("MenuLine", 1, center.X, bottomLine, Alignment.Center, ColorRgba.White, 1.6f);

            int charOffset = 0;

            api.DrawStringShadow(ref charOffset, "menu/play story/title".T(), center.X, 110f,
                                 Alignment.Center, new ColorRgba(0.5f, 0.5f), 0.9f, 0.4f, 0.6f, 0.6f, 8f, charSpacing: 0.88f);

            if (episodes.Count > 0)
            {
                float topItem       = topLine - 5f;
                float bottomItem    = bottomLine + 5f;
                float contentHeight = bottomItem - topItem;
                float itemSpacing   = contentHeight / (episodes.Count + 1);

                topItem += itemSpacing;
                float topItemSelected = 0f;

                for (int i = 0; i < episodes.Count; i++)
                {
                    if (selectedIndex == i)
                    {
                        topItemSelected = topItem;
                    }
                    else
                    {
                        if (episodes[i].IsAvailable)
                        {
                            api.DrawString(ref charOffset, episodes[i].Episode.Name, center.X, topItem,
                                           Alignment.Center, ColorRgba.TransparentBlack, 0.9f);
                        }
                        else
                        {
                            api.DrawString(ref charOffset, episodes[i].Episode.Name, center.X, topItem,
                                           Alignment.Center, new ColorRgba(0.4f, 0.4f), 0.9f);
                        }
                    }

                    topItem += itemSpacing;
                }

                // Selected item last
                float expandedAnimation2 = Math.Min(expandedAnimation * 6f, 1f);
                float expandedAnimation3 = (expandedAnimation2 * expandedAnimation2 * (3.0f - 2.0f * expandedAnimation2));

                float size = 0.5f + Ease.OutElastic(selectAnimation) * 0.5f + (1f - expandedAnimation3) * 0.2f;

                if (episodes[selectedIndex].IsAvailable)
                {
                    if (episodes[selectedIndex].Logo.IsAvailable)
                    {
                        api.DrawString(ref charOffset, episodes[selectedIndex].Episode.Name, center.X, topItemSelected,
                                       Alignment.Center, new ColorRgba(0.44f, 0.5f * MathF.Max(0f, 1f - selectAnimation * 2f)), 0.9f - selectAnimation * 0.5f);

                        ContentRef <Material> logo = episodes[selectedIndex].Logo;
                        Texture texture            = logo.Res.MainTexture.Res;

                        Vector2 originPos = new Vector2(center.X, topItemSelected);
                        Vector2 logoSize  = new Vector2(texture.InternalWidth * size, texture.InternalHeight * size);
                        Alignment.Center.ApplyTo(ref originPos, logoSize);

                        ColorRgba logoColor = ColorRgba.White.WithAlpha(1f - expandedAnimation3 * 0.5f);

                        canvas.State.SetMaterial(logo);
                        canvas.State.ColorTint = logoColor;
                        canvas.FillRect(originPos.X, originPos.Y, texture.InternalWidth * size, texture.InternalHeight * size);

                        if (episodes[selectedIndex].IsComplete)
                        {
                            api.DrawMaterial("EpisodeComplete", originPos.X + logoSize.X * 0.7f, originPos.Y + logoSize.Y * 0.4f, Alignment.TopLeft, logoColor, size, size);
                        }

                        if (episodes[selectedIndex].CanContinue)
                        {
                            float moveX = expandedAnimation3 * -24f;

                            api.DrawString(ref charOffset, ">", center.X + 80f + moveX, topItemSelected,
                                           Alignment.Right, new ColorRgba(0.5f, 0.5f * MathF.Min(1f, 0.4f + selectAnimation)), 0.8f, charSpacing: 0.9f);

                            if (expanded)
                            {
                                float expandedAnimation4 = Ease.OutElastic(expandedAnimation) * 0.8f;

                                api.DrawStringShadow(ref charOffset, "menu/play story/restart".T(), center.X + 110f, topItemSelected,
                                                     Alignment.Center, new ColorRgba(0.62f, 0.44f, 0.34f, 0.5f * MathF.Min(1f, 0.4f + expandedAnimation3)), expandedAnimation4, 0.4f, 0.6f, 0.6f, 8f, charSpacing: 0.8f);
                            }
                        }
                    }
                    else
                    {
                        api.DrawStringShadow(ref charOffset, episodes[selectedIndex].Episode.Name, center.X, topItemSelected,
                                             Alignment.Center, null, size, charSpacing: 0.9f);
                    }
                }
                else
                {
                    api.DrawString(ref charOffset, episodes[selectedIndex].Episode.Name, center.X, topItemSelected,
                                   Alignment.Center, new ColorRgba(0.4f, MathF.Max(0.3f, 0.4f - selectAnimation * 0.4f)), MathF.Max(0.7f, 0.9f - selectAnimation * 0.6f));

                    int     index = episodes.IndexOfFirst(entry => entry.Episode.Token == episodes[selectedIndex].Episode.PreviousEpisode);
                    Episode previousEpisode;
                    if (index == -1)
                    {
                        previousEpisode = null;
                    }
                    else
                    {
                        previousEpisode = episodes[index].Episode;
                    }

                    string info;
                    if (previousEpisode == null)
                    {
                        info = "menu/play story/locked".T();
                    }
                    else
                    {
                        info = "menu/play story/locked prev".T(previousEpisode.Name);
                    }

                    api.DrawStringShadow(ref charOffset, info, center.X, topItemSelected,
                                         Alignment.Center, new ColorRgba(0.66f, 0.42f, 0.32f, MathF.Min(0.5f, 0.2f + 2f * selectAnimation)), 0.7f * size, charSpacing: 0.9f);
                }
            }
            else
            {
                api.DrawStringShadow(ref charOffset, "menu/play story/empty".T(), center.X, center.Y, Alignment.Center,
                                     new ColorRgba(0.62f, 0.44f, 0.34f, 0.5f), 0.9f, 0.4f, 0.6f, 0.6f, 8f, charSpacing: 0.88f);
            }
        }
Exemple #41
0
        private void DrawLayer(IDrawDevice device, ref TileMapLayer layer, int cacheIndex)
        {
            if (!layer.Visible)
            {
                return;
            }

            Vector2 viewSize   = device.TargetSize;
            Vector3 viewCenter = device.RefCoord;

            Point2  tileCount = new Point2(layer.LayoutWidth, layer.Layout.Length / layer.LayoutWidth);
            Vector2 tileSize  = new Vector2(tileset.TileSize, tileset.TileSize);

            // Update offsets for moving layers
            if (MathF.Abs(layer.AutoSpeedX) > 0)
            {
                layer.OffsetX += layer.AutoSpeedX * Time.TimeMult;
                if (layer.RepeatX)
                {
                    if (layer.AutoSpeedX > 0)
                    {
                        while (layer.OffsetX > (tileCount.X * 32))
                        {
                            layer.OffsetX -= (tileCount.X * 32);
                        }
                    }
                    else
                    {
                        while (layer.OffsetX < 0)
                        {
                            layer.OffsetX += (tileCount.X * 32);
                        }
                    }
                }
            }
            if (MathF.Abs(layer.AutoSpeedY) > 0)
            {
                layer.OffsetY += layer.AutoSpeedY * Time.TimeMult;
                if (layer.RepeatY)
                {
                    if (layer.AutoSpeedY > 0)
                    {
                        while (layer.OffsetY > (tileCount.Y * 32))
                        {
                            layer.OffsetY -= (tileCount.Y * 32);
                        }
                    }
                    else
                    {
                        while (layer.OffsetY < 0)
                        {
                            layer.OffsetY += (tileCount.Y * 32);
                        }
                    }
                }
            }

            // Get current layer offsets and speeds
            float loX = layer.OffsetX;
            float loY = layer.OffsetY - (layer.UseInherentOffset ? (viewSize.Y - 200) / 2 : 0);

            // Find out coordinates for a tile from outside the boundaries from topleft corner of the screen
            float x1 = viewCenter.X - 70 - (viewSize.X * 0.5f);
            float y1 = viewCenter.Y - 70 - (viewSize.Y * 0.5f);

            if (layer.BackgroundStyle != BackgroundStyle.Plain && tileCount.Y == 8 && tileCount.X == 8)
            {
                const float PerspectiveSpeedX = 0.4f;
                const float PerspectiveSpeedY = 0.16f;
                RenderTexturedBackground(device, ref layer, cacheIndex,
                                         (x1 * PerspectiveSpeedX + loX),
                                         (y1 * PerspectiveSpeedY + loY));
            }
            else
            {
                // Figure out the floating point offset from the calculated coordinates and the actual tile
                // corner coordinates
                float xt = TranslateCoordinate(x1, layer.SpeedX, loX, false, viewSize.Y, viewSize.X);
                float yt = TranslateCoordinate(y1, layer.SpeedY, loY, true, viewSize.Y, viewSize.X);

                float remX = xt % 32f;
                float remY = yt % 32f;

                // Calculate the index (on the layer map) of the first tile that needs to be drawn to the
                // position determined earlier
                int tileX, tileY, tileAbsX, tileAbsY;

                // Get the actual tile coords on the layer layout
                if (xt > 0)
                {
                    tileAbsX = (int)Math.Floor(xt / 32f);
                    tileX    = tileAbsX % tileCount.X;
                }
                else
                {
                    tileAbsX = (int)Math.Ceiling(xt / 32f);
                    tileX    = tileAbsX % tileCount.X;
                    while (tileX < 0)
                    {
                        tileX += tileCount.X;
                    }
                }

                if (yt > 0)
                {
                    tileAbsY = (int)Math.Floor(yt / 32f);
                    tileY    = tileAbsY % tileCount.Y;
                }
                else
                {
                    tileAbsY = (int)Math.Ceiling(yt / 32f);
                    tileY    = tileAbsY % tileCount.Y;
                    while (tileY < 0)
                    {
                        tileY += tileCount.Y;
                    }
                }

                // update x1 and y1 with the remainder so that we start at the tile boundary
                // minus 1 because indices are updated in the beginning of the loops
                x1 -= remX - 32f;
                y1 -= remY - 32f;

                // Save the tile Y at the left border so that we can roll back to it at the start of
                // every row iteration
                int tileYs = tileY;

                // Calculate the last coordinates we want to draw to
                float x3 = x1 + 100 + viewSize.X;
                float y3 = y1 + 100 + viewSize.Y;

                Material  material  = null;
                Texture   texture   = null;
                ColorRgba mainColor = ColorRgba.White;

                // Reserve the required space for vertex data in our locally cached buffer
                VertexC1P3T2[] vertexData;

                int neededVertices = (int)((((x3 - x1) / 32) + 1) * (((y3 - y1) / 32) + 1) * 4);
                if (cachedVertices[cacheIndex] == null || cachedVertices[cacheIndex].Length < neededVertices)
                {
                    cachedVertices[cacheIndex] = vertexData = new VertexC1P3T2[neededVertices];
                }
                else
                {
                    vertexData = cachedVertices[cacheIndex];
                }

                int vertexBaseIndex = 0;

                int tile_xo = -1;
                for (float x2 = x1; x2 < x3; x2 += 32)
                {
                    tileX = (tileX + 1) % tileCount.X;
                    tile_xo++;
                    if (!layer.RepeatX)
                    {
                        // If the current tile isn't in the first iteration of the layer horizontally, don't draw this column
                        if (tileAbsX + tile_xo + 1 < 0 || tileAbsX + tile_xo + 1 >= tileCount.X)
                        {
                            continue;
                        }
                    }
                    tileY = tileYs;
                    int tile_yo = -1;
                    for (float y2 = y1; y2 < y3; y2 += 32)
                    {
                        tileY = (tileY + 1) % tileCount.Y;
                        tile_yo++;

                        LayerTile tile = layer.Layout[tileX + tileY * layer.LayoutWidth];

                        if (!layer.RepeatY)
                        {
                            // If the current tile isn't in the first iteration of the layer vertically, don't draw it
                            if (tileAbsY + tile_yo + 1 < 0 || tileAbsY + tile_yo + 1 >= tileCount.Y)
                            {
                                continue;
                            }
                        }

                        Point2 offset;
                        bool   isFlippedX, isFlippedY;
                        if (tile.IsAnimated)
                        {
                            if (tile.TileID < animatedTiles.Count)
                            {
                                offset     = animatedTiles[tile.TileID].CurrentTile.MaterialOffset;
                                isFlippedX = (animatedTiles[tile.TileID].CurrentTile.IsFlippedX != tile.IsFlippedX);
                                isFlippedY = (animatedTiles[tile.TileID].CurrentTile.IsFlippedY != tile.IsFlippedY);

                                //mainColor.A = tile.MaterialAlpha;
                                mainColor.A = animatedTiles[tile.TileID].CurrentTile.MaterialAlpha;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            offset     = tile.MaterialOffset;
                            isFlippedX = tile.IsFlippedX;
                            isFlippedY = tile.IsFlippedY;

                            mainColor.A = tile.MaterialAlpha;
                        }

                        if (material != tile.Material)
                        {
                            // Submit all the vertices as one draw batch
                            device.AddVertices(
                                material,
                                VertexMode.Quads,
                                vertexData,
                                0,
                                vertexBaseIndex);

                            vertexBaseIndex = 0;

                            material = tile.Material.Res;
                            texture  = material.MainTexture.Res;
                        }

                        Rect uvRect = new Rect(
                            offset.X * texture.UVRatio.X / texture.ContentWidth,
                            offset.Y * texture.UVRatio.Y / texture.ContentHeight,
                            tileset.TileSize * texture.UVRatio.X / texture.ContentWidth,
                            tileset.TileSize * texture.UVRatio.Y / texture.ContentHeight
                            );

                        // ToDo: Flip normal map somehow
                        if (isFlippedX)
                        {
                            uvRect.X += uvRect.W;
                            uvRect.W *= -1;
                        }
                        if (isFlippedY)
                        {
                            uvRect.Y += uvRect.H;
                            uvRect.H *= -1;
                        }

                        Vector3 renderPos = new Vector3(x2, y2, layer.Depth);
                        float   scale     = 1.0f;
                        device.PreprocessCoords(ref renderPos, ref scale);

                        renderPos.X = MathF.Round(renderPos.X);
                        renderPos.Y = MathF.Round(renderPos.Y);
                        if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2)
                        {
                            renderPos.X += 0.5f;
                        }
                        if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2)
                        {
                            renderPos.Y += 0.5f;
                        }

                        vertexData[vertexBaseIndex + 0].Pos.X      = renderPos.X;
                        vertexData[vertexBaseIndex + 0].Pos.Y      = renderPos.Y;
                        vertexData[vertexBaseIndex + 0].Pos.Z      = renderPos.Z;
                        vertexData[vertexBaseIndex + 0].TexCoord.X = uvRect.X;
                        vertexData[vertexBaseIndex + 0].TexCoord.Y = uvRect.Y;
                        vertexData[vertexBaseIndex + 0].Color      = mainColor;

                        vertexData[vertexBaseIndex + 1].Pos.X      = renderPos.X;
                        vertexData[vertexBaseIndex + 1].Pos.Y      = renderPos.Y + tileSize.Y;
                        vertexData[vertexBaseIndex + 1].Pos.Z      = renderPos.Z;
                        vertexData[vertexBaseIndex + 1].TexCoord.X = uvRect.X;
                        vertexData[vertexBaseIndex + 1].TexCoord.Y = uvRect.Y + uvRect.H;
                        vertexData[vertexBaseIndex + 1].Color      = mainColor;

                        vertexData[vertexBaseIndex + 2].Pos.X      = renderPos.X + tileSize.X;
                        vertexData[vertexBaseIndex + 2].Pos.Y      = renderPos.Y + tileSize.Y;
                        vertexData[vertexBaseIndex + 2].Pos.Z      = renderPos.Z;
                        vertexData[vertexBaseIndex + 2].TexCoord.X = uvRect.X + uvRect.W;
                        vertexData[vertexBaseIndex + 2].TexCoord.Y = uvRect.Y + uvRect.H;
                        vertexData[vertexBaseIndex + 2].Color      = mainColor;

                        vertexData[vertexBaseIndex + 3].Pos.X      = renderPos.X + tileSize.X;
                        vertexData[vertexBaseIndex + 3].Pos.Y      = renderPos.Y;
                        vertexData[vertexBaseIndex + 3].Pos.Z      = renderPos.Z;
                        vertexData[vertexBaseIndex + 3].TexCoord.X = uvRect.X + uvRect.W;
                        vertexData[vertexBaseIndex + 3].TexCoord.Y = uvRect.Y;
                        vertexData[vertexBaseIndex + 3].Color      = mainColor;

                        vertexBaseIndex += 4;
                    }
                }

                // Submit all the vertices as one draw batch
                device.AddVertices(
                    material,
                    VertexMode.Quads,
                    vertexData,
                    0,
                    vertexBaseIndex);
            }
        }
Exemple #42
0
		void ICmpRenderer.Draw(IDrawDevice device)
		{
			// Create a buffer to cache and re-use vertices. Not required, but will boost performance.
			if (this.buffer == null) this.buffer = new CanvasBuffer();

			// Create a Canvas to auto-generate vertices from high-level drawing commands.
			Canvas canvas = new Canvas(device, this.buffer);
			canvas.State.TextFont = this.font;

			// If the game is over or won, display "game over" screen
			if (this.gameOver || this.gameWin)
			{
				// Various animation timing variables.
				float animOffset = this.gameWin ? 0.0f : 2500.0f;
				float animTime = this.gameWin ? 10000.0f : 4500.0f;
				float blendDurationRatio = this.gameWin ? 0.6f : 0.5f;
				float textOffsetRatio = this.gameWin ? 0.2f : 0.0f;

				float timeSinceGameOver = (float)Time.MainTimer.TotalMilliseconds - this.lastTimeAnyAlive;
				float gameOverAnimProgress = MathF.Clamp((timeSinceGameOver - animOffset) / animTime, 0.0f, 1.0f);
				float controlInfoAnimProgress = MathF.Clamp(((timeSinceGameOver - animOffset) - animTime - 2000.0f) / 2000.0f, 0.0f, 1.0f);
				float blendAnimProgress = MathF.Clamp(gameOverAnimProgress / blendDurationRatio, 0.0f, 1.0f);
				float textAnimProgress = MathF.Clamp((gameOverAnimProgress - blendDurationRatio - textOffsetRatio) / (1.0f - blendDurationRatio - textOffsetRatio), 0.0f, 1.0f);

				if (this.blendMaterial != null && blendAnimProgress > 0.0f)
				{
					canvas.PushState();

					if (this.gameOver)
					{
						// Set up our special blending Material and specify the threshold to blend to
						this.blendMaterial.SetUniform("threshold", 1.0f - blendAnimProgress);
						canvas.State.SetMaterial(this.blendMaterial);
						canvas.State.ColorTint = ColorRgba.Black;

						// Specify a texture coordinate rect so it spans the entire screen repeating itself, instead of being stretched
						if (this.blendMaterial.MainTexture != null)
						{
							Random rnd = new Random((int)this.lastTimeAnyAlive);
							Vector2 randomTranslate = rnd.NextVector2(0.0f, 0.0f, canvas.State.TextureBaseSize.X, canvas.State.TextureBaseSize.Y);
							canvas.State.TextureCoordinateRect = new Rect(
								randomTranslate.X, 
								randomTranslate.Y, 
								device.TargetSize.X / canvas.State.TextureBaseSize.X, 
								device.TargetSize.Y / canvas.State.TextureBaseSize.Y);
						}
					}
					else
					{
						// If we won, simply fade to white
						canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Add, ColorRgba.White));
						canvas.State.ColorTint = ColorRgba.White.WithAlpha(blendAnimProgress);
					}

					// Fill the screen with a rect of our Material
					canvas.FillRect(0, 0, device.TargetSize.X, device.TargetSize.Y);

					canvas.PopState();
				}

				if (this.font != null && textAnimProgress > 0.0f)
				{
					canvas.PushState();

					// Determine which text to draw to screen and where to draw it
					string gameOverText = this.gameWin ? "is it over..?" : "darkness...";
					Vector2 fullTextSize = canvas.MeasureText(gameOverText);
					Vector2 textPos = device.TargetSize * 0.5f - fullTextSize * 0.5f;
					gameOverText = gameOverText.Substring(0, MathF.RoundToInt(gameOverText.Length * textAnimProgress));

					// Make sure not to draw inbetween pixels, so the text is perfectly sharp.
					textPos.X = MathF.Round(textPos.X);
					textPos.Y = MathF.Round(textPos.Y);

					// Draw the text to screen
					canvas.State.ColorTint = this.gameWin ? ColorRgba.Black : ColorRgba.White;
					canvas.DrawText(gameOverText, textPos.X, textPos.Y);

					canvas.PopState();
				}

				if (controlInfoAnimProgress > 0.0f)
				{
					Vector2 infoBasePos = device.TargetSize * 0.5f + new Vector2(0.0f, device.TargetSize.Y * 0.25f);
					if (this.controlInfoMouseKeyboard != null)
					{
						canvas.PushState();

						Vector2 texSize = this.controlInfoMouseKeyboard.Res.MainTexture.Res.Size * 0.5f;

						canvas.State.SetMaterial(this.controlInfoMouseKeyboard);
						canvas.State.ColorTint = ColorRgba.White.WithAlpha(controlInfoAnimProgress);
						canvas.FillRect(
							infoBasePos.X - texSize.X * 0.5f,
							infoBasePos.Y - texSize.Y - 10,
							texSize.X,
							texSize.Y);

						canvas.PopState();
					}
					if (this.controlInfoGamepad != null)
					{
						canvas.PushState();

						Vector2 texSize = this.controlInfoGamepad.Res.MainTexture.Res.Size * 0.5f;

						canvas.State.SetMaterial(this.controlInfoGamepad);
						canvas.State.ColorTint = ColorRgba.White.WithAlpha(controlInfoAnimProgress);
						canvas.FillRect(
							infoBasePos.X - texSize.X * 0.5f,
							infoBasePos.Y + 10,
							texSize.X,
							texSize.Y);

						canvas.PopState();
					}
				}
			}
		}
Exemple #43
0
        public override void OnPaint(Canvas canvas)
        {
            IDrawDevice device = canvas.DrawDevice;

            Vector2 center = device.TargetSize * 0.5f;

            const float topLine    = 131f;
            float       bottomLine = device.TargetSize.Y - 42;

            api.DrawMaterial("MenuDim", center.X, (topLine + bottomLine) * 0.5f, Alignment.Center, ColorRgba.White, 55f, (bottomLine - topLine) * 0.063f, new Rect(0f, 0.3f, 1f, 0.4f));

            int charOffset = 0;

            api.DrawStringShadow(ref charOffset, "Controls for Player #1", center.X * 0.3f, 110f,
                                 Alignment.Left, new ColorRgba(0.5f, 0.5f), 0.9f, 0.4f, 0.6f, 0.6f, 8f, charSpacing: 0.88f);

            api.DrawStringShadow(ref charOffset, "Key 1", center.X * (0.9f + 0 * 0.34f), 110f,
                                 Alignment.Center, new ColorRgba(0.46f, 0.5f), 0.8f, charSpacing: 0.88f);
            api.DrawStringShadow(ref charOffset, "Key 2", center.X * (0.9f + 1 * 0.34f), 110f,
                                 Alignment.Center, new ColorRgba(0.46f, 0.5f), 0.8f, charSpacing: 0.88f);
            api.DrawStringShadow(ref charOffset, "Gamepad", center.X * (0.9f + 2 * 0.34f), 110f,
                                 Alignment.Center, new ColorRgba(0.46f, 0.5f), 0.8f, charSpacing: 0.88f);

            int n = (int)PlayerActions.Count;

            float topItem       = topLine - 5f;
            float bottomItem    = bottomLine + 5f;
            float contentHeight = bottomItem - topItem;
            float itemSpacing   = contentHeight / (n + 1);

            topItem += itemSpacing;

            for (int i = 0; i < n; i++)
            {
                string name;
                switch ((PlayerActions)i)
                {
                case PlayerActions.Left: name = "Left"; break;

                case PlayerActions.Right: name = "Right"; break;

                case PlayerActions.Up: name = "Up / Look Up"; break;

                case PlayerActions.Down: name = "Down / Crouch"; break;

                case PlayerActions.Fire: name = "Fire"; break;

                case PlayerActions.Jump: name = "Jump"; break;

                case PlayerActions.Run: name = "Run"; break;

                case PlayerActions.SwitchWeapon: name = "Switch Weapon"; break;

                default: name = ((PlayerActions)i).ToString(); break;
                }

                ref Mapping mapping = ref ControlScheme.GetCurrentMapping(0, (PlayerActions)i);

                api.DrawString(ref charOffset, name, center.X * 0.3f, topItem,
                               Alignment.Left, ColorRgba.TransparentBlack, 0.8f);

                for (int j = 0; j < possibleButtons; j++)
                {
                    string value;
                    switch (j)
                    {
                    case 0:
                        if (mapping.Key1 != Key.Unknown)
                        {
                            value = mapping.Key1.ToString();
                        }
                        else
                        {
                            value = "-";
                        }
                        break;

                    case 1:
                        if (mapping.Key2 != Key.Unknown)
                        {
                            value = mapping.Key2.ToString();
                        }
                        else
                        {
                            value = "-";
                        }
                        break;

                    case 2:
                        if (mapping.GamepadIndex != -1)
                        {
                            value = mapping.GamepadIndex + " : " + mapping.GamepadButton;
                        }
                        else
                        {
                            value = "-";
                        }
                        break;

                    default: value = null; break;
                    }

                    if (selectedIndex == i && selectedColumn == j)
                    {
                        float size = 0.5f + Ease.OutElastic(animation) * 0.5f;

                        api.DrawStringShadow(ref charOffset, value, center.X * (0.9f + j * 0.34f), topItem,
                                             Alignment.Center, waitForInput ? new ColorRgba(0.62f, 0.44f, 0.34f, 0.5f) : new ColorRgba(0.48f, 0.5f), size, 0.7f, 1.1f, 1.1f, charSpacing: 0.9f);
                    }
                    else
                    {
                        api.DrawString(ref charOffset, value, center.X * (0.9f + j * 0.34f), topItem,
                                       Alignment.Center, ColorRgba.TransparentBlack, 0.8f);
                    }
                }

                topItem += itemSpacing;
            }
Exemple #44
0
		/// <summary>
		/// Determines if the Renderer is visible to the specified <see cref="IDrawDevice"/>.
		/// This is usually the case if they share at least one mutual <see cref="VisibilityGroup">visibility group</see>.
		/// </summary>
		/// <param name="device"></param>
		/// <returns></returns>
		public virtual bool IsVisible(IDrawDevice device)
		{
			if ((device.VisibilityMask & VisibilityFlag.ScreenOverlay) != (this.visibilityGroup & VisibilityFlag.ScreenOverlay)) return false;
			if ((this.visibilityGroup & device.VisibilityMask & VisibilityFlag.AllGroups) == VisibilityFlag.None) return false;
			return device.IsCoordInView(this.gameobj.Transform.Pos, this.BoundRadius);
		}
Exemple #45
0
 bool ICmpRenderer.IsVisible(IDrawDevice device)
 {
     return((device.VisibilityMask & VisibilityFlag.ScreenOverlay) != VisibilityFlag.None);
 }
Exemple #46
0
		public override void Draw(IDrawDevice device)
		{
			Vector3 posTemp = this.gameobj.Transform.Pos;
			float scaleTemp = 1.0f;
			device.PreprocessCoords(ref posTemp, ref scaleTemp);

			Vector2 xDot, yDot;
			MathF.GetTransformDotVec(this.GameObj.Transform.Angle, this.gameobj.Transform.Scale * scaleTemp, out xDot, out yDot);

			// Apply block alignment
			Vector2 textOffset = Vector2.Zero;
			Vector2 textSize = this.text.Size;
			if (this.text.MaxWidth > 0) textSize.X = this.text.MaxWidth;
			this.blockAlign.ApplyTo(ref textOffset, textSize);
			MathF.TransformDotVec(ref textOffset, ref xDot, ref yDot);
			posTemp.X += textOffset.X;
			posTemp.Y += textOffset.Y;
			if (this.text.Fonts != null && this.text.Fonts.Any(r => r.IsAvailable && r.Res.IsPixelGridAligned))
			{
				posTemp.X = MathF.Round(posTemp.X);
				posTemp.Y = MathF.Round(posTemp.Y);
				if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2)
					posTemp.X += 0.5f;
				if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2)
					posTemp.Y += 0.5f;
			}

			// Draw design time metrics data
			if (DualityApp.ExecContext == DualityApp.ExecutionContext.Editor)
			{
				bool showLimits		= true;
				bool showLines		= false;
				bool showElements	= false;
				Vector3 metricsOffset = new Vector3(0.0f, 0.0f, 0.01f);
				Vector3 lineOffset = new Vector3(0.5f, 0.5f, 0.0f);
				Vector3 tUnitX = Vector3.UnitX;
				Vector3 tUnitY = Vector3.UnitY;
				MathF.TransformDotVec(ref tUnitX, ref xDot, ref yDot);
				MathF.TransformDotVec(ref tUnitY, ref xDot, ref yDot);

				// Actual text size and maximum text size
				if (showLimits)
				{
					Vector3 textWidth = tUnitX * this.text.Size.X;
					Vector3 textHeight = tUnitY * this.text.Size.Y;
					Vector3 textMaxWidth = tUnitX * this.text.MaxWidth;
					Vector3 textMaxHeight = tUnitY * MathF.Max(this.text.MaxHeight, this.text.Size.Y);

					ColorRgba clrSize = ColorRgba.Green.WithAlpha(128);
					ColorRgba clrMaxSize = ColorRgba.Red.WithAlpha(128);
					device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.LineLoop,
						new VertexC1P3(metricsOffset + lineOffset + posTemp, clrSize),
						new VertexC1P3(metricsOffset + lineOffset + posTemp + textWidth, clrSize),
						new VertexC1P3(metricsOffset + lineOffset + posTemp + textWidth + textHeight, clrSize),
						new VertexC1P3(metricsOffset + lineOffset + posTemp + textHeight, clrSize));
					device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.LineLoop,
						new VertexC1P3(metricsOffset + lineOffset + posTemp, clrMaxSize),
						new VertexC1P3(metricsOffset + lineOffset + posTemp + textMaxWidth, clrMaxSize),
						new VertexC1P3(metricsOffset + lineOffset + posTemp + textMaxWidth + textMaxHeight, clrMaxSize),
						new VertexC1P3(metricsOffset + lineOffset + posTemp + textMaxHeight, clrMaxSize));
				}

				// Individual line sizes
				if (showLines)
				{
					ColorRgba clrLineBg = (ColorRgba.Blue + ColorRgba.Red).WithAlpha(64);
					for (int i = 0; i < this.text.TextMetrics.LineBounds.Count; i++)
					{
						Rect lineRect = this.text.TextMetrics.LineBounds[i];
						device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.Quads,
							new VertexC1P3(metricsOffset + posTemp + lineRect.TopLeft.X * tUnitX + lineRect.TopLeft.Y * tUnitY, clrLineBg),
							new VertexC1P3(metricsOffset + posTemp + lineRect.BottomLeft.X * tUnitX + lineRect.BottomLeft.Y * tUnitY, clrLineBg),
							new VertexC1P3(metricsOffset + posTemp + lineRect.BottomRight.X * tUnitX + lineRect.BottomRight.Y * tUnitY, clrLineBg),
							new VertexC1P3(metricsOffset + posTemp + lineRect.TopRight.X * tUnitX + lineRect.TopRight.Y * tUnitY, clrLineBg));
					}
				}

				// Individual line sizes
				if (showElements)
				{
					ColorRgba clrElementBg = (ColorRgba.Blue + ColorRgba.Green).WithAlpha(128);
					for (int i = 0; i < this.text.TextMetrics.ElementBounds.Count; i++)
					{
						Rect elemRect = this.text.TextMetrics.ElementBounds[i];
						device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.LineLoop,
							new VertexC1P3(metricsOffset + lineOffset + posTemp + elemRect.TopLeft.X * tUnitX + elemRect.TopLeft.Y * tUnitY, clrElementBg),
							new VertexC1P3(metricsOffset + lineOffset + posTemp + elemRect.BottomLeft.X * tUnitX + elemRect.BottomLeft.Y * tUnitY, clrElementBg),
							new VertexC1P3(metricsOffset + lineOffset + posTemp + elemRect.BottomRight.X * tUnitX + elemRect.BottomRight.Y * tUnitY, clrElementBg),
							new VertexC1P3(metricsOffset + lineOffset + posTemp + elemRect.TopRight.X * tUnitX + elemRect.TopRight.Y * tUnitY, clrElementBg));
					}
				}
			}

			ColorRgba matColor = this.customMat != null ? this.customMat.MainColor : ColorRgba.White;
			int[] vertLen = this.text.EmitVertices(ref this.vertFont, ref this.vertIcon, posTemp.X, posTemp.Y, posTemp.Z, this.colorTint * matColor, xDot, yDot);
			if (this.text.Fonts != null)
			{
				for (int i = 0; i < this.text.Fonts.Length; i++)
				{
					if (this.text.Fonts[i] != null && this.text.Fonts[i].IsAvailable) 
					{
						if (this.customMat == null)
						{
							device.AddVertices(this.text.Fonts[i].Res.Material, VertexMode.Quads, this.vertFont[i], vertLen[i + 1]);
						}
						else
						{
							BatchInfo cm = new BatchInfo(this.customMat);
							cm.Textures = this.text.Fonts[i].Res.Material.Textures;
							device.AddVertices(cm, VertexMode.Quads, this.vertFont[i], vertLen[i + 1]);
						}
					}
				}
			}
			if (this.text.Icons != null && this.iconMat.IsAvailable)
			{
				device.AddVertices(this.iconMat, VertexMode.Quads, this.vertIcon, vertLen[0]);
			}
		}
		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;
				}
			}
		}
Exemple #48
0
        protected override void OnRender(Canvas canvas)
        {
            Size size = ClientSize;

            size.Width -= scrollBar.ClientSize.Width;

            canvas.State.ColorTint = ColorRgba.White;
            canvas.FillRect(0, 0, size.Width, size.Height);

            if (tilemap == null)
            {
                return;
            }

            IDrawDevice device = canvas.DrawDevice;

            TileSet  tileset  = tilemap.Tileset;
            Material material = tilemap.Tileset.GetDefaultTile(0).Material.Res;
            Texture  texture  = material.MainTexture.Res;

            int scrollBarOffset = scrollBar.Value;

            ColorRgba mainColor = ColorRgba.White;
            Point2    tileSize  = new Point2(tilemap.Tileset.TileSize, tilemap.Tileset.TileSize);

            VertexC1P3T2[] vertexData = new VertexC1P3T2[4];

            int tileIndex = 0;

            for (int y = 0; tileIndex < tileset.TileCount; y += tileSize.Y)
            {
                for (int x = 0; x < 10 * tileSize.X; x += tileSize.X)
                {
                    int tx = (tileIndex % tileset.TilesPerRow) * tileSize.X;
                    int ty = (tileIndex / tileset.TilesPerRow) * tileSize.Y;

                    Vector3 renderPos = new Vector3(x, y - scrollBarOffset, 0);

                    Rect uvRect = new Rect(
                        tx * texture.UVRatio.X / texture.ContentWidth,
                        ty * texture.UVRatio.Y / texture.ContentHeight,
                        tileset.TileSize * texture.UVRatio.X / texture.ContentWidth,
                        tileset.TileSize * texture.UVRatio.Y / texture.ContentHeight
                        );

                    vertexData[0].Pos.X      = renderPos.X;
                    vertexData[0].Pos.Y      = renderPos.Y;
                    vertexData[0].Pos.Z      = renderPos.Z;
                    vertexData[0].TexCoord.X = uvRect.X;
                    vertexData[0].TexCoord.Y = uvRect.Y;
                    vertexData[0].Color      = mainColor;

                    vertexData[1].Pos.X      = renderPos.X;
                    vertexData[1].Pos.Y      = renderPos.Y + tileSize.Y;
                    vertexData[1].Pos.Z      = renderPos.Z;
                    vertexData[1].TexCoord.X = uvRect.X;
                    vertexData[1].TexCoord.Y = uvRect.Y + uvRect.H;
                    vertexData[1].Color      = mainColor;

                    vertexData[2].Pos.X      = renderPos.X + tileSize.X;
                    vertexData[2].Pos.Y      = renderPos.Y + tileSize.Y;
                    vertexData[2].Pos.Z      = renderPos.Z;
                    vertexData[2].TexCoord.X = uvRect.X + uvRect.W;
                    vertexData[2].TexCoord.Y = uvRect.Y + uvRect.H;
                    vertexData[2].Color      = mainColor;

                    vertexData[3].Pos.X      = renderPos.X + tileSize.X;
                    vertexData[3].Pos.Y      = renderPos.Y;
                    vertexData[3].Pos.Z      = renderPos.Z;
                    vertexData[3].TexCoord.X = uvRect.X + uvRect.W;
                    vertexData[3].TexCoord.Y = uvRect.Y;
                    vertexData[3].Color      = mainColor;

                    device.AddVertices(material, VertexMode.Quads, vertexData);

                    tileIndex++;
                }
            }
        }
Exemple #49
0
		/// <summary>
		/// Performs the Renderers drawing operation.
		/// </summary>
		/// <param name="device"></param>
		public abstract void Draw(IDrawDevice device);
Exemple #50
0
        private void OnRender(IDrawDevice device)
        {
            Vector2 center = device.TargetSize * 0.5f;

            canvas.Begin(device);

            int charOffset       = 0;
            int charOffsetShadow = 0;

            RenderTexturedBackground(device);

            // Title
            DrawMaterial("MenuCarrot", -1, center.X - 76f, 64f + 2f, Alignment.Center, new ColorRgba(0f, 0.3f), 0.8f, 0.8f);
            DrawMaterial("MenuCarrot", -1, center.X - 76f, 64f, Alignment.Center, ColorRgba.White, 0.8f, 0.8f);

            fontMedium.DrawString(ref charOffsetShadow, "Jazz", center.X - 63f, 70f + 2f, Alignment.Left,
                                  new ColorRgba(0f, 0.32f), 0.75f, 1.63f, 3f, 3f, 0f, 0.92f);
            fontMedium.DrawString(ref charOffsetShadow, "2", center.X - 19f, 70f - 8f + 2f, Alignment.Left,
                                  new ColorRgba(0f, 0.32f), 0.5f, 0f, 0f, 0f, 0f);
            fontMedium.DrawString(ref charOffsetShadow, "Resurrection", center.X - 10f, 70f + 4f + 2.5f, Alignment.Left,
                                  new ColorRgba(0f, 0.3f), 0.5f, 0.4f, 1.2f, 1.2f, 7f, 0.8f);

            fontMedium.DrawString(ref charOffset, "Jazz", center.X - 63f, 70f, Alignment.Left,
                                  new ColorRgba(0.54f, 0.44f, 0.34f, 0.5f), 0.75f, 1.63f, 3f, 3f, 0f, 0.92f);
            fontMedium.DrawString(ref charOffset, "2", center.X - 19f, 70f - 8f, Alignment.Left,
                                  new ColorRgba(0.54f, 0.44f, 0.34f, 0.5f), 0.5f, 0f, 0f, 0f, 0f);
            fontMedium.DrawString(ref charOffset, "Resurrection", center.X - 10f, 70f + 4f, Alignment.Left,
                                  new ColorRgba(0.6f, 0.42f, 0.42f, 0.5f), 0.5f, 0.4f, 1.2f, 1.2f, 7f, 0.8f);

            // Version
            Vector2 bottomRight = device.TargetSize;

            bottomRight.X -= 24f;
            bottomRight.Y -= 10f;
            DrawStringShadow(ref charOffset, "v" + App.AssemblyVersion, bottomRight.X, bottomRight.Y, Alignment.BottomRight,
                             ColorRgba.TransparentBlack, 0.7f, 0.4f, 1.2f, 1.2f, 7f, 0.8f);

            // Copyright
            Vector2 bottomLeft = bottomRight;

            bottomLeft.X = 24f;
            DrawStringShadow(ref charOffset, "(c) 2016-" + DateTime.Now.Year + "  Dan R.", bottomLeft.X, bottomLeft.Y, Alignment.BottomLeft,
                             ColorRgba.TransparentBlack, 0.7f, 0.4f, 1.2f, 1.2f, 7f, 0.8f);

            // New Version
            if (!string.IsNullOrEmpty(newVersion))
            {
                DrawStringShadow(ref charOffset, "New version available: " + newVersion, (bottomLeft.X + bottomRight.X) * 0.5f, bottomLeft.Y, Alignment.Bottom,
                                 new ColorRgba(0.62f, 0.44f, 0.34f, 0.5f), 0.7f, 0.4f, 1.2f, 1.2f, 7f, 0.9f);
            }

            // Current section
            if (sectionStack.Count > 0)
            {
                sectionStack.Peek().OnPaint(canvas);
            }

            DrawTouch(device.TargetSize);

            canvas.End();
        }
Exemple #51
0
 void ICmpRenderer.Draw(IDrawDevice device)
 {
     mainMenu.OnRender(device);
 }
Exemple #52
0
 public abstract void Draw(IDrawDevice device);
Exemple #53
0
		protected void PrepareVertices(ref VertexC1P3T2[] vertices, IDrawDevice device, ColorRgba mainClr, Rect uvRect)
		{
			Vector3 posTemp = this.gameobj.Transform.Pos;
			float scaleTemp = 1.0f;
			device.PreprocessCoords(ref posTemp, ref scaleTemp);

			Vector2 xDot, yDot;
			MathF.GetTransformDotVec(this.GameObj.Transform.Angle, scaleTemp, 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);
            
			float left   = uvRect.X;
			float right  = uvRect.RightX;
			float top    = uvRect.Y;
			float bottom = uvRect.BottomY;

			if ((this.flipMode & FlipMode.Horizontal) != FlipMode.None)
				MathF.Swap(ref left, ref right);
			if ((this.flipMode & FlipMode.Vertical) != FlipMode.None)
				MathF.Swap(ref top, ref bottom);

			if (vertices == null || vertices.Length != 4) vertices = new VertexC1P3T2[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 = left;
			vertices[0].TexCoord.Y = top;
			vertices[0].Color = mainClr;

			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].Color = mainClr;

			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].Color = mainClr;
				
			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].Color = mainClr;

			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;
				}
			}
		}
Exemple #54
0
        public override void Draw(IDrawDevice device)
        {
            if (particles == null)
            {
                return;
            }

            Texture tex = RetrieveTexture();

            if (tex == null)
            {
                return;
            }

            Vector2 particleHalfSize = particleSize * 0.5f;
            float   objAngle         = GameObj.Transform.Angle;
            float   objScale         = GameObj.Transform.Scale;
            Vector3 objPos           = GameObj.Transform.Pos;

            Vector2 objXDot, objYDot;

            MathF.GetTransformDotVec(objAngle, objScale, out objXDot, out objYDot);

            if (vertexBuffer == null)
            {
                vertexBuffer = new RawList <VertexC1P3T2>(particles.Count * 4);
            }
            vertexBuffer.Count = vertexBuffer.Count = particles.Count * 4;

            VertexC1P3T2[] vertexData    = vertexBuffer.Data;
            Particle[]     particleData  = particles.Data;
            int            particleCount = particles.Count;

            for (int i = 0; i < particleCount; i++)
            {
                ColorRgba color = particleData[i].Color;
                float     alpha = (float)color.A / 255.0f;
                if (fadeOutAt < 1.0f)
                {
                    alpha *= MathF.Clamp((1.0f - particleData[i].AgeFactor) / fadeOutAt, 0.0f, 1.0f);
                }
                if (fadeInAt > 0.0f)
                {
                    alpha *= MathF.Clamp(particleData[i].AgeFactor / fadeInAt, 0.0f, 1.0f);
                }
                color.A = (byte)(alpha * 255.0f);

                Rect uvRect;
                tex.LookupAtlas(particleData[i].SpriteIndex, out uvRect);

                Vector3 particlePos = particleData[i].Position;
                MathF.TransformDotVec(ref particlePos, ref objXDot, ref objYDot);
                particlePos += objPos;

                float particleAngle = objAngle + particleData[i].Angle;
                float particleScale = objScale;

                device.PreprocessCoords(ref particlePos, ref particleScale);

                Vector2 xDot, yDot;
                MathF.GetTransformDotVec(particleAngle, particleScale, out xDot, out yDot);

                Vector2 edgeTopLeft     = new Vector2(-particleHalfSize.X, -particleHalfSize.Y);
                Vector2 edgeBottomLeft  = new Vector2(-particleHalfSize.X, particleHalfSize.Y);
                Vector2 edgeBottomRight = new Vector2(particleHalfSize.X, particleHalfSize.Y);
                Vector2 edgeTopRight    = new Vector2(particleHalfSize.X, -particleHalfSize.Y);

                MathF.TransformDotVec(ref edgeTopLeft, ref xDot, ref yDot);
                MathF.TransformDotVec(ref edgeBottomLeft, ref xDot, ref yDot);
                MathF.TransformDotVec(ref edgeBottomRight, ref xDot, ref yDot);
                MathF.TransformDotVec(ref edgeTopRight, ref xDot, ref yDot);

                int vertexBaseIndex = i * 4;
                vertexData[vertexBaseIndex + 0].Pos.X      = particlePos.X + edgeTopLeft.X;
                vertexData[vertexBaseIndex + 0].Pos.Y      = particlePos.Y + edgeTopLeft.Y;
                vertexData[vertexBaseIndex + 0].Pos.Z      = particlePos.Z;
                vertexData[vertexBaseIndex + 0].TexCoord.X = uvRect.X;
                vertexData[vertexBaseIndex + 0].TexCoord.Y = uvRect.Y;
                vertexData[vertexBaseIndex + 0].Color      = color;

                vertexData[vertexBaseIndex + 1].Pos.X      = particlePos.X + edgeBottomLeft.X;
                vertexData[vertexBaseIndex + 1].Pos.Y      = particlePos.Y + edgeBottomLeft.Y;
                vertexData[vertexBaseIndex + 1].Pos.Z      = particlePos.Z;
                vertexData[vertexBaseIndex + 1].TexCoord.X = uvRect.X;
                vertexData[vertexBaseIndex + 1].TexCoord.Y = uvRect.BottomY;
                vertexData[vertexBaseIndex + 1].Color      = color;

                vertexData[vertexBaseIndex + 2].Pos.X      = particlePos.X + edgeBottomRight.X;
                vertexData[vertexBaseIndex + 2].Pos.Y      = particlePos.Y + edgeBottomRight.Y;
                vertexData[vertexBaseIndex + 2].Pos.Z      = particlePos.Z;
                vertexData[vertexBaseIndex + 2].TexCoord.X = uvRect.RightX;
                vertexData[vertexBaseIndex + 2].TexCoord.Y = uvRect.BottomY;
                vertexData[vertexBaseIndex + 2].Color      = color;

                vertexData[vertexBaseIndex + 3].Pos.X      = particlePos.X + edgeTopRight.X;
                vertexData[vertexBaseIndex + 3].Pos.Y      = particlePos.Y + edgeTopRight.Y;
                vertexData[vertexBaseIndex + 3].Pos.Z      = particlePos.Z;
                vertexData[vertexBaseIndex + 3].TexCoord.X = uvRect.RightX;
                vertexData[vertexBaseIndex + 3].TexCoord.Y = uvRect.Y;
                vertexData[vertexBaseIndex + 3].Color      = color;
            }

            device.AddVertices(material, VertexMode.Quads, vertexData, vertexBuffer.Count);
        }
Exemple #55
0
			internal void NotifyCollectDrawcalls(IDrawDevice device)
			{
				Profile.TimeCollectDrawcalls.BeginMeasure();

				if (this.CollectDrawcalls != null)
					this.CollectDrawcalls(this, new CollectDrawcallEventArgs(device));

				Profile.TimeCollectDrawcalls.EndMeasure();
			}
Exemple #56
0
        void IGraphicsBackend.BeginRendering(IDrawDevice device, RenderOptions options, RenderStats stats)
        {
            DebugCheckOpenGLErrors();

            this.currentDevice = device;
            this.renderOptions = options;
            this.renderStats   = stats;

            // Prepare the target surface for rendering
            NativeRenderTarget.Bind(options.Target as NativeRenderTarget);

            // Determine the available size on the active rendering surface
            //Point2 availableSize;
            //if (NativeRenderTarget.BoundRT != null) {
            //    availableSize = new Point2(NativeRenderTarget.BoundRT.Width, NativeRenderTarget.BoundRT.Height);
            //} else {
            //    availableSize = this.externalBackbufferSize;
            //}

            Rect openGLViewport = options.Viewport;

            // Setup viewport and scissor rects
            GL.Viewport((int)openGLViewport.X, (int)openGLViewport.Y, (int)MathF.Ceiling(openGLViewport.W), (int)MathF.Ceiling(openGLViewport.H));
            GL.Scissor((int)openGLViewport.X, (int)openGLViewport.Y, (int)MathF.Ceiling(openGLViewport.W), (int)MathF.Ceiling(openGLViewport.H));

            // Clear buffers
            ClearBufferMask glClearMask = 0;
            ColorRgba       clearColor  = options.ClearColor;

            if ((options.ClearFlags & ClearFlag.Color) != ClearFlag.None)
            {
                glClearMask |= ClearBufferMask.ColorBufferBit;
            }
            if ((options.ClearFlags & ClearFlag.Depth) != ClearFlag.None)
            {
                glClearMask |= ClearBufferMask.DepthBufferBit;
            }
            GL.ClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f, clearColor.A / 255.0f);
            GL.ClearDepth(options.ClearDepth);
            GL.Clear(glClearMask);

            // Configure Rendering params
            GL.Enable(EnableCap.ScissorTest);
            GL.Enable(EnableCap.DepthTest);
            if (options.DepthTest)
            {
                GL.DepthFunc(DepthFunction.Lequal);
            }
            else
            {
                GL.DepthFunc(DepthFunction.Always);
            }

            Matrix4 view       = options.ViewMatrix;
            Matrix4 projection = options.ProjectionMatrix;

            if (NativeRenderTarget.BoundRT != null)
            {
                Matrix4 flipOutput = Matrix4.CreateScale(1.0f, -1.0f, 1.0f);
                projection = projection * flipOutput;
            }

            // Convert matrices to float arrays
            GetArrayMatrix(ref view, viewData);
            GetArrayMatrix(ref projection, projectionData);

            // All EBOs can be used again
            lastUsedEBO = 0;
        }
Exemple #57
0
		bool ICmpRenderer.IsVisible(IDrawDevice device)
		{
			return 
				DualityApp.ExecContext == DualityApp.ExecutionContext.Game &&
				(device.VisibilityMask & VisibilityFlag.ScreenOverlay) != VisibilityFlag.None &&
				(device.VisibilityMask & VisibilityFlag.AllGroups) != VisibilityFlag.None;
		}
Exemple #58
0
        public static void SetupLighting(IDrawDevice device, BatchInfo material)
        {
            DeviceLightInfo info = UpdateLighting(device);

            // Prepare shader dara
            float[] _lightPos   = new float[4 * MaxVisible];
            float[] _lightDir   = new float[4 * MaxVisible];
            float[] _lightColor = new float[3 * MaxVisible];
            int     _lightCount = MathF.Min(MaxVisible, info.PriorizedLights.Count);

            int i = 0;

            foreach (Light light in info.PriorizedLights)
            {
                if (light.Disposed)
                {
                    continue;
                }

                Vector3 dir;
                Vector3 pos;
                float   uniformScale;
                bool    directional = light.IsDirectional;
                if (directional)
                {
                    dir          = light.dir;
                    pos          = Vector3.Zero;
                    uniformScale = 1.0f;
                }
                else
                {
                    dir          = light.dir;
                    pos          = light.GameObj.Transform.Pos;
                    uniformScale = light.GameObj.Transform.Scale;

                    MathF.TransformCoord(ref dir.X, ref dir.Y, light.GameObj.Transform.Angle);
                }

                if (directional)
                {
                    _lightPos[i * 4 + 0] = (float)light.ambientColor.R * light.ambientIntensity / 255.0f;
                    _lightPos[i * 4 + 1] = (float)light.ambientColor.G * light.ambientIntensity / 255.0f;
                    _lightPos[i * 4 + 2] = (float)light.ambientColor.B * light.ambientIntensity / 255.0f;
                    _lightPos[i * 4 + 3] = 0.0f;
                }
                else
                {
                    _lightPos[i * 4 + 0] = pos.X;
                    _lightPos[i * 4 + 1] = pos.Y;
                    _lightPos[i * 4 + 2] = pos.Z;
                    _lightPos[i * 4 + 3] = light.range * uniformScale;
                }

                _lightDir[i * 4 + 0] = dir.X;
                _lightDir[i * 4 + 1] = dir.Y;
                _lightDir[i * 4 + 2] = dir.Z;
                _lightDir[i * 4 + 3] = dir == Vector3.Zero ? 0.0f : MathF.Max(light.spotFocus, 1.0f);

                _lightColor[i * 3 + 0] = (float)light.color.R * light.intensity / 255.0f;
                _lightColor[i * 3 + 1] = (float)light.color.G * light.intensity / 255.0f;
                _lightColor[i * 3 + 2] = (float)light.color.B * light.intensity / 255.0f;

                i++;
                if (i >= _lightCount)
                {
                    break;
                }
            }
            if (i + 1 < _lightCount)
            {
                _lightCount = i + 1;
            }

            material.SetUniform("_lightCount", _lightCount);
            material.SetUniform("_lightPos", _lightPos);
            material.SetUniform("_lightDir", _lightDir);
            material.SetUniform("_lightColor", _lightColor);
        }
Exemple #59
0
 /// <summary>
 /// Enumerates all <see cref="Duality.Components.Renderer">Renderers</see> that are visible to
 /// the specified <see cref="IDrawDevice"/>.
 /// </summary>
 /// <param name="device"></param>
 /// <returns></returns>
 public IEnumerable <ICmpRenderer> QueryVisibleRenderers(IDrawDevice device)
 {
     return(this.renderers.Where(r => r.Active && (r as ICmpRenderer).IsVisible(device)).OfType <ICmpRenderer>());
 }
Exemple #60
0
 public override void PrepareRendering(IDrawDevice device, BatchInfo material)
 {
     base.PrepareRendering(device, material);
     DynamicLighting.Light.SetupLighting(device, material);
 }