Beispiel #1
0
        /// <summary>
        /// Generates a single drawcall that renders a fullscreen quad using the specified material.
        /// Assumes that the <see cref="DrawDevice"/> is set up to render in screen space.
        /// </summary>
        /// <param name="material"></param>
        /// <param name="resizeMode"></param>
        public void AddFullscreenQuad(BatchInfo material, TargetResize resizeMode)
        {
            Texture tex       = material.MainTexture.Res;
            Vector2 uvRatio   = tex != null ? tex.UVRatio : Vector2.One;
            Point2  inputSize = tex != null ? tex.ContentSize : Point2.Zero;

            // Fit the input material rect to the output size according to rendering step config
            Vector2 targetSize = resizeMode.Apply(inputSize, this.TargetSize);
            Rect    targetRect = Rect.Align(
                Alignment.Center,
                this.TargetSize.X * 0.5f,
                this.TargetSize.Y * 0.5f,
                targetSize.X,
                targetSize.Y);

            // Fit the target rect to actual pixel coordinates to avoid unnecessary filtering offsets
            targetRect.X = (int)targetRect.X;
            targetRect.Y = (int)targetRect.Y;
            targetRect.W = MathF.Ceiling(targetRect.W);
            targetRect.H = MathF.Ceiling(targetRect.H);

            VertexC1P3T2[] vertices = new VertexC1P3T2[4];

            vertices[0].Pos = new Vector3(targetRect.LeftX, targetRect.TopY, 0.0f);
            vertices[1].Pos = new Vector3(targetRect.RightX, targetRect.TopY, 0.0f);
            vertices[2].Pos = new Vector3(targetRect.RightX, targetRect.BottomY, 0.0f);
            vertices[3].Pos = new Vector3(targetRect.LeftX, targetRect.BottomY, 0.0f);

            vertices[0].TexCoord = new Vector2(0.0f, 0.0f);
            vertices[1].TexCoord = new Vector2(uvRatio.X, 0.0f);
            vertices[2].TexCoord = new Vector2(uvRatio.X, uvRatio.Y);
            vertices[3].TexCoord = new Vector2(0.0f, uvRatio.Y);

            vertices[0].Color = ColorRgba.White;
            vertices[1].Color = ColorRgba.White;
            vertices[2].Color = ColorRgba.White;
            vertices[3].Color = ColorRgba.White;

            this.AddVertices(material, VertexMode.Quads, vertices);
        }
Beispiel #2
0
        private void RenderSinglePass(Rect viewportRect, Pass p)
        {
            this.drawDevice.VisibilityMask = this.visibilityMask & p.VisibilityMask;
            this.drawDevice.RenderMode = p.MatrixMode;
            this.drawDevice.Target = p.Output;
            this.drawDevice.ViewportRect = p.Output.IsAvailable ? new Rect(p.Output.Res.Width, p.Output.Res.Height) : viewportRect;

            if (p.Input == null)
            {
                // Render Scene
                this.drawDevice.PrepareForDrawcalls();
                try
                {
                    this.CollectDrawcalls();
                    p.NotifyCollectDrawcalls(this.drawDevice);
                }
                catch (Exception e)
                {
                    Log.Core.WriteError("There was an error while {0} was collecting drawcalls: {1}", this.ToString(), Log.Exception(e));
                }
                this.drawDevice.Render(p.ClearFlags, p.ClearColor, p.ClearDepth);
            }
            else
            {
                Profile.TimePostProcessing.BeginMeasure();
                this.drawDevice.PrepareForDrawcalls();

                Texture mainTex = p.Input.MainTexture.Res;
                Vector2 uvRatio = mainTex != null ? mainTex.UVRatio : Vector2.One;
                Vector2 inputSize = mainTex != null ? new Vector2(mainTex.PixelWidth, mainTex.PixelHeight) : Vector2.One;
                Rect targetRect;
                if (DualityApp.ExecEnvironment == DualityApp.ExecutionEnvironment.Editor &&
                    !this.drawDevice.Target.IsAvailable)
                    targetRect = Rect.Align(Alignment.Center, this.drawDevice.TargetSize.X * 0.5f, this.drawDevice.TargetSize.Y * 0.5f, inputSize.X, inputSize.Y);
                else
                    targetRect = new Rect(this.drawDevice.TargetSize);

                IDrawDevice device = this.drawDevice;
                {
                    VertexC1P3T2[] vertices = new VertexC1P3T2[4];

                    vertices[0].Pos = new Vector3(targetRect.LeftX, targetRect.TopY, 0.0f);
                    vertices[1].Pos = new Vector3(targetRect.RightX, targetRect.TopY, 0.0f);
                    vertices[2].Pos = new Vector3(targetRect.RightX, targetRect.BottomY, 0.0f);
                    vertices[3].Pos = new Vector3(targetRect.LeftX, targetRect.BottomY, 0.0f);

                    vertices[0].TexCoord = new Vector2(0.0f, 0.0f);
                    vertices[1].TexCoord = new Vector2(uvRatio.X, 0.0f);
                    vertices[2].TexCoord = new Vector2(uvRatio.X, uvRatio.Y);
                    vertices[3].TexCoord = new Vector2(0.0f, uvRatio.Y);

                    vertices[0].Color = ColorRgba.White;
                    vertices[1].Color = ColorRgba.White;
                    vertices[2].Color = ColorRgba.White;
                    vertices[3].Color = ColorRgba.White;

                    device.AddVertices(p.Input, VertexMode.Quads, vertices);
                }

                this.drawDevice.Render(p.ClearFlags, p.ClearColor, p.ClearDepth);
                Profile.TimePostProcessing.EndMeasure();
            }
        }
Beispiel #3
0
        /// <summary>
        /// Emits sets of vertices for glyphs and icons based on this formatted text. To render it, use each set of vertices combined with
        /// the corresponding Fonts <see cref="Material"/>.
        /// </summary>
        /// <param name="vertText">One set of vertices for each Font that is available to this FormattedText.</param>
        /// <param name="vertIcons">A set of icon vertices.</param>
        /// <returns>
        /// Returns an array of vertex counts for each emitted vertex array. 
        /// Index 0 represents the number of emitted icon vertices, Index n represents the number of vertices emitted using Font n - 1.
        /// </returns>
        public int[] EmitVertices(ref VertexC1P3T2[][] vertText, ref VertexC1P3T2[] vertIcons)
        {
            this.ValidateVertexCache();

            // Allocate memory
            if (vertIcons == null || vertIcons.Length < this.vertCountCache[0]) vertIcons = new VertexC1P3T2[this.vertCountCache[0]];
            if (vertText == null || vertText.Length != this.vertTextCache.Length) vertText = new VertexC1P3T2[this.vertTextCache.Length][];
            for (int i = 0; i < this.vertTextCache.Length; i++)
            {
                if (vertText[i] == null || vertText[i].Length < this.vertCountCache[i + 1])
                    vertText[i] = new VertexC1P3T2[this.vertCountCache[i + 1]];
            }

            // Copy actual data
            int[] vertLen = new int[this.vertCountCache.Length];
            Array.Copy(this.vertCountCache, vertLen, this.vertCountCache.Length);
            Array.Copy(this.vertIconsCache, vertIcons, vertLen[0]);
            for (int i = 0; i < this.vertTextCache.Length; i++)
                Array.Copy(this.vertTextCache[i], vertText[i], vertLen[i + 1]);

            return vertLen;
        }
Beispiel #4
0
        /// <summary>
        /// Emits sets of vertices for glyphs and icons based on this formatted text. To render it, use each set of vertices combined with
        /// the corresponding Fonts <see cref="Material"/>.
        /// </summary>
        /// <param name="vertText">One set of vertices for each Font that is available to this ForattedText.</param>
        /// <param name="vertIcons">A set of icon vertices.</param>
        /// <param name="x">An X-Offset applied to the position of each emitted vertex.</param>
        /// <param name="y">An Y-Offset applied to the position of each emitted vertex.</param>
        /// <param name="z">An Z-Offset applied to the position of each emitted vertex.</param>
        /// <param name="clr">The color value that is applied to each emitted vertex.</param>
        /// <param name="xDot">Dot product base for the transformed vertices.</param>
        /// <param name="yDot">Dot product base for the transformed vertices.</param>
        /// <returns>
        /// Returns an array of vertex counts for each emitted vertex array. 
        /// Index 0 represents the number of emitted icon vertices, Index n represents the number of vertices emitted using Font n - 1.
        /// </returns>
        public int[] EmitVertices(ref VertexC1P3T2[][] vertText, ref VertexC1P3T2[] vertIcons, float x, float y, float z, ColorRgba clr, Vector2 xDot, Vector2 yDot)
        {
            int[] vertLen = this.EmitVertices(ref vertText, ref vertIcons);

            Vector3 offset = new Vector3(x, y, z);

            if (clr == ColorRgba.White)
            {
                for (int i = 0; i < vertText.Length; i++)
                {
                    for (int j = 0; j < vertLen[i + 1]; j++)
                    {
                        MathF.TransformDotVec(ref vertText[i][j].Pos, ref xDot, ref yDot);
                        Vector3.Add(ref vertText[i][j].Pos, ref offset, out vertText[i][j].Pos);
                    }
                }
                for (int i = 0; i < vertLen[0]; i++)
                {
                    MathF.TransformDotVec(ref vertIcons[i].Pos, ref xDot, ref yDot);
                    Vector3.Add(ref vertIcons[i].Pos, ref offset, out vertIcons[i].Pos);
                }
            }
            else
            {
                for (int i = 0; i < vertText.Length; i++)
                {
                    for (int j = 0; j < vertLen[i + 1]; j++)
                    {
                        MathF.TransformDotVec(ref vertText[i][j].Pos, ref xDot, ref yDot);
                        Vector3.Add(ref vertText[i][j].Pos, ref offset, out vertText[i][j].Pos);
                        ColorRgba.Multiply(ref vertText[i][j].Color, ref clr, out vertText[i][j].Color);
                    }
                }
                for (int i = 0; i < vertLen[0]; i++)
                {
                    MathF.TransformDotVec(ref vertIcons[i].Pos, ref xDot, ref yDot);
                    Vector3.Add(ref vertIcons[i].Pos, ref offset, out vertIcons[i].Pos);
                    ColorRgba.Multiply(ref vertIcons[i].Color, ref clr, out vertIcons[i].Color);
                }
            }

            return vertLen;
        }
Beispiel #5
0
 /// <summary>
 /// Emits sets of vertices for glyphs and icons based on this formatted text. To render it, use each set of vertices combined with
 /// the corresponding Fonts <see cref="Material"/>.
 /// </summary>
 /// <param name="vertText">One set of vertices for each Font that is available to this ForattedText.</param>
 /// <param name="vertIcons">A set of icon vertices.</param>
 /// <param name="x">An X-Offset applied to the position of each emitted vertex.</param>
 /// <param name="y">An Y-Offset applied to the position of each emitted vertex.</param>
 /// <param name="z">An Z-Offset applied to the position of each emitted vertex.</param>
 /// <param name="clr">The color value that is applied to each emitted vertex.</param>
 /// <param name="angle">An angle by which the text is rotated (before applying the offset).</param>
 /// <param name="scale">A factor by which the text is scaled (before applying the offset).</param>
 /// <returns>
 /// Returns an array of vertex counts for each emitted vertex array. 
 /// Index 0 represents the number of emitted icon vertices, Index n represents the number of vertices emitted using Font n - 1.
 /// </returns>
 public int[] EmitVertices(ref VertexC1P3T2[][] vertText, ref VertexC1P3T2[] vertIcons, float x, float y, float z, ColorRgba clr, float angle = 0.0f, float scale = 1.0f)
 {
     Vector2 xDot, yDot;
     MathF.GetTransformDotVec(angle, scale, out xDot, out yDot);
     return this.EmitVertices(ref vertText, ref vertIcons, x, y, z, clr, xDot, yDot);
 }
Beispiel #6
0
 /// <summary>
 /// Emits sets of vertices for glyphs and icons based on this formatted text. To render it, use each set of vertices combined with
 /// the corresponding Fonts <see cref="Material"/>.
 /// </summary>
 /// <param name="vertText">One set of vertices for each Font that is available to this ForattedText.</param>
 /// <param name="vertIcons">A set of icon vertices.</param>
 /// <param name="x">An X-Offset applied to the position of each emitted vertex.</param>
 /// <param name="y">An Y-Offset applied to the position of each emitted vertex.</param>
 /// <param name="z">An Z-Offset applied to the position of each emitted vertex.</param>
 /// <returns>
 /// Returns an array of vertex counts for each emitted vertex array. 
 /// Index 0 represents the number of emitted icon vertices, Index n represents the number of vertices emitted using Font n - 1.
 /// </returns>
 public int[] EmitVertices(ref VertexC1P3T2[][] vertText, ref VertexC1P3T2[] vertIcons, float x, float y, float z = 0.0f)
 {
     return this.EmitVertices(ref vertText, ref vertIcons, x, y, z, ColorRgba.White);
 }
Beispiel #7
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;
				}
			}
		}
Beispiel #8
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.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 VertexC1P3T2[4];

            vertices[0].SetVertex(posTemp.X + edge1.X,
                                    posTemp.Y + edge1.Y,
                                    posTemp.Z + this.VertexZOffset,
                                    uvRect.X, uvRect.Y, mainClr);

            vertices[1].SetVertex(posTemp.X + edge2.X,
                                    posTemp.Y + edge2.Y,
                                    posTemp.Z + this.VertexZOffset,
                                    uvRect.X, uvRect.MaximumY, mainClr);

            vertices[2].SetVertex(posTemp.X + edge3.X,
                                    posTemp.Y + edge3.Y,
                                    posTemp.Z + this.VertexZOffset,
                                    uvRect.MaximumX, uvRect.MaximumY, mainClr);

            vertices[3].SetVertex(posTemp.X + edge4.X,
                                    posTemp.Y + edge4.Y,
                                    posTemp.Z + this.VertexZOffset,
                                    uvRect.MaximumX, uvRect.Y, 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;
                }
            }
        }
        protected internal override void OnCollectWorldOverlayDrawcalls(Canvas canvas)
        {
            base.OnCollectWorldOverlayDrawcalls(canvas);
            List<RigidBody> visibleColliders = this.QueryVisibleColliders().ToList();

            RigidBody selectedBody = this.QuerySelectedCollider();

            canvas.State.TextFont = Font.GenericMonospace10;
            canvas.State.TextInvariantScale = true;
            canvas.State.ZOffset = -0.5f;
            Font textFont = canvas.State.TextFont.Res;

            // Draw Shape layer
            foreach (RigidBody body in visibleColliders)
            {
                if (!body.Shapes.Any()) continue;
                float colliderAlpha = body == selectedBody ? 1.0f : (selectedBody != null ? 0.25f : 0.5f);
                float maxDensity = body.Shapes.Max(s => s.Density);
                float minDensity = body.Shapes.Min(s => s.Density);
                float avgDensity = (maxDensity + minDensity) * 0.5f;
                Vector3 objPos = body.GameObj.Transform.Pos;
                float objAngle = body.GameObj.Transform.Angle;
                float objScale = body.GameObj.Transform.Scale;
                int index = 0;
                foreach (ShapeInfo shape in body.Shapes)
                {
                    CircleShapeInfo circle = shape as CircleShapeInfo;
                    PolyShapeInfo poly = shape as PolyShapeInfo;
                    ChainShapeInfo chain = shape as ChainShapeInfo;
                    LoopShapeInfo loop = shape as LoopShapeInfo;

                    ObjectEditorCamViewState editorState = this.View.ActiveState as ObjectEditorCamViewState;
                    float shapeAlpha = colliderAlpha * (selectedBody == null || editorState == null || editorState.SelectedObjects.Any(sel => sel.ActualObject == shape) ? 1.0f : 0.5f);
                    float densityRelative = MathF.Abs(maxDensity - minDensity) < 0.01f ? 1.0f : shape.Density / avgDensity;
                    ColorRgba clr = shape.IsSensor ? this.ShapeSensorColor : this.ShapeColor;
                    ColorRgba fontClr = this.FgColor;
                    Vector2 center = Vector2.Zero;

                    if (!body.IsAwake) clr = clr.ToHsva().WithSaturation(0.0f).ToRgba();
                    if (!shape.IsValid) clr = this.ShapeErrorColor;

                    bool fillShape = (poly != null || circle != null);
                    Vector2[] shapeVertices = null;
                    if      (poly  != null) shapeVertices = poly .Vertices;
                    else if (loop  != null) shapeVertices = loop .Vertices;
                    else if (chain != null) shapeVertices = chain.Vertices;

                    if (circle != null)
                    {
                        Vector2 circlePos = circle.Position * objScale;
                        MathF.TransformCoord(ref circlePos.X, ref circlePos.Y, objAngle);

                        if (fillShape)
                        {
                            canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr.WithAlpha((0.25f + densityRelative * 0.25f) * shapeAlpha)));
                            canvas.FillCircle(
                                objPos.X + circlePos.X,
                                objPos.Y + circlePos.Y,
                                objPos.Z,
                                circle.Radius * objScale);
                        }
                        canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr.WithAlpha(shapeAlpha)));
                        canvas.DrawCircle(
                            objPos.X + circlePos.X,
                            objPos.Y + circlePos.Y,
                            objPos.Z,
                            circle.Radius * objScale);

                        center = circlePos;
                    }
                    else if (shapeVertices != null)
                    {
                        ColorRgba vertexFillColor = canvas.State.ColorTint * clr.WithAlpha((0.25f + densityRelative * 0.25f) * shapeAlpha);
                        ColorRgba vertexOutlineColor = canvas.State.ColorTint * clr;

                        // Prepare vertices to submit. We can't use higher-level canvas functionality
                        // here, because we want direct control over the vertex mode.
                        float viewSpaceScale = objScale;
                        Vector3 viewSpacePos = objPos;
                        canvas.DrawDevice.PreprocessCoords(ref viewSpacePos, ref viewSpaceScale);
                        VertexC1P3T2[] drawVertices = new VertexC1P3T2[shapeVertices.Length];
                        for (int i = 0; i < drawVertices.Length; i++)
                        {
                            drawVertices[i].Pos.X = shapeVertices[i].X * viewSpaceScale + viewSpacePos.X;
                            drawVertices[i].Pos.Y = shapeVertices[i].Y * viewSpaceScale + viewSpacePos.Y;
                            drawVertices[i].Pos.Z = viewSpacePos.Z;
                            drawVertices[i].Color = vertexOutlineColor;
                            MathF.TransformCoord(ref drawVertices[i].Pos.X, ref drawVertices[i].Pos.Y, objAngle);
                        }

                        // Calculate the center coordinate
                        for (int i = 0; i < drawVertices.Length; i++)
                            center += shapeVertices[i];
                        center /= shapeVertices.Length;
                        MathF.TransformCoord(ref center.X, ref center.Y, objAngle, objScale);

                        // Make sure to render using an alpha material
                        canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White));

                        // Fill the shape
                        if (fillShape)
                        {
                            VertexC1P3T2[] fillVertices = drawVertices.Clone() as VertexC1P3T2[];
                            for (int i = 0; i < fillVertices.Length; i++)
                                fillVertices[i].Color = vertexFillColor;
                            canvas.DrawVertices(fillVertices, VertexMode.TriangleFan);
                        }

                        // Draw the outline
                        canvas.DrawVertices(drawVertices, shape is ChainShapeInfo ? VertexMode.LineStrip : VertexMode.LineLoop);
                    }

                    // Draw shape index
                    if (body == selectedBody)
                    {
                        string indexText = index.ToString();
                        Vector2 textSize = textFont.MeasureText(indexText);
                        canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, fontClr.WithAlpha((shapeAlpha + 1.0f) * 0.5f)));
                        canvas.DrawText(indexText,
                            objPos.X + center.X,
                            objPos.Y + center.Y,
                            objPos.Z);
                    }

                    index++;
                }

                // Draw center of mass
                if (body.BodyType == BodyType.Dynamic)
                {
                    Vector2 localMassCenter = body.LocalMassCenter;
                    MathF.TransformCoord(ref localMassCenter.X, ref localMassCenter.Y, objAngle, objScale);
                    canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, this.MassCenterColor.WithAlpha(colliderAlpha)));
                    canvas.DrawLine(
                        objPos.X + localMassCenter.X - 5.0f,
                        objPos.Y + localMassCenter.Y,
                        objPos.Z,
                        objPos.X + localMassCenter.X + 5.0f,
                        objPos.Y + localMassCenter.Y,
                        objPos.Z);
                    canvas.DrawLine(
                        objPos.X + localMassCenter.X,
                        objPos.Y + localMassCenter.Y - 5.0f,
                        objPos.Z,
                        objPos.X + localMassCenter.X,
                        objPos.Y + localMassCenter.Y + 5.0f,
                        objPos.Z);
                }
            }
        }
Beispiel #10
0
        /// <summary>
        /// Emits a set of vertices based on a text. To render this text, simply use that set of vertices combined with
        /// the Fonts <see cref="Material"/>.
        /// </summary>
        /// <param name="text">The text to render.</param>
        /// <param name="vertices">The set of vertices that is emitted. You can re-use the same array each frame.</param>
        /// <returns>The number of emitted vertices. This values isn't necessarily equal to the emitted arrays length.</returns>
        public int EmitTextVertices(string text, ref VertexC1P3T2[] vertices)
        {
            int len = text.Length * 4;
            if (vertices == null || vertices.Length < len) vertices = new VertexC1P3T2[len];

            float curOffset = 0.0f;
            GlyphData glyphData;
            Rect uvRect;
            float glyphXOff;
            float glyphXAdv;
            for (int i = 0; i < text.Length; i++)
            {
                this.ProcessTextAdv(text, i, out glyphData, out uvRect, out glyphXAdv, out glyphXOff);

                Vector2 glyphPos;
                glyphPos.X = MathF.Round(curOffset + glyphXOff);
                glyphPos.Y = MathF.Round(0.0f);

                vertices[i * 4 + 0].Pos.X = glyphPos.X;
                vertices[i * 4 + 0].Pos.Y = glyphPos.Y;
                vertices[i * 4 + 0].Pos.Z = 0.0f;
                vertices[i * 4 + 0].TexCoord = uvRect.TopLeft;
                vertices[i * 4 + 0].Color = ColorRgba.White;

                vertices[i * 4 + 1].Pos.X = glyphPos.X + glyphData.width;
                vertices[i * 4 + 1].Pos.Y = glyphPos.Y;
                vertices[i * 4 + 1].Pos.Z = 0.0f;
                vertices[i * 4 + 1].TexCoord = uvRect.TopRight;
                vertices[i * 4 + 1].Color = ColorRgba.White;

                vertices[i * 4 + 2].Pos.X = glyphPos.X + glyphData.width;
                vertices[i * 4 + 2].Pos.Y = glyphPos.Y + glyphData.height;
                vertices[i * 4 + 2].Pos.Z = 0.0f;
                vertices[i * 4 + 2].TexCoord = uvRect.BottomRight;
                vertices[i * 4 + 2].Color = ColorRgba.White;

                vertices[i * 4 + 3].Pos.X = glyphPos.X;
                vertices[i * 4 + 3].Pos.Y = glyphPos.Y + glyphData.height;
                vertices[i * 4 + 3].Pos.Z = 0.0f;
                vertices[i * 4 + 3].TexCoord = uvRect.BottomLeft;
                vertices[i * 4 + 3].Color = ColorRgba.White;

                curOffset += glyphXAdv;
            }

            return len;
        }
Beispiel #11
0
        /// <summary>
        /// Emits a set of vertices based on a text. To render this text, simply use that set of vertices combined with
        /// the Fonts <see cref="Material"/>.
        /// </summary>
        /// <param name="text">The text to render.</param>
        /// <param name="vertices">The set of vertices that is emitted. You can re-use the same array each frame.</param>
        /// <param name="x">An X-Offset applied to the position of each emitted vertex.</param>
        /// <param name="y">An Y-Offset applied to the position of each emitted vertex.</param>
        /// <param name="clr">The color value that is applied to each emitted vertex.</param>
        /// <returns>The number of emitted vertices. This values isn't necessarily equal to the emitted arrays length.</returns>
        public int EmitTextVertices(string text, ref VertexC1P3T2[] vertices, float x, float y, ColorRgba clr)
        {
            int len = this.EmitTextVertices(text, ref vertices);

            Vector3 offset = new Vector3(x, y, 0);

            for (int i = 0; i < len; i++)
            {
                Vector3.Add(ref vertices[i].Pos, ref offset, out vertices[i].Pos);
                vertices[i].Color = clr;
            }

            return len;
        }
Beispiel #12
0
        /// <summary>
        /// Emits a set of vertices based on a text. To render this text, simply use that set of vertices combined with
        /// the Fonts <see cref="Material"/>.
        /// </summary>
        /// <param name="text">The text to render.</param>
        /// <param name="vertices">The set of vertices that is emitted. You can re-use the same array each frame.</param>
        /// <param name="x">An X-Offset applied to the position of each emitted vertex.</param>
        /// <param name="y">An Y-Offset applied to the position of each emitted vertex.</param>
        /// <param name="z">An Z-Offset applied to the position of each emitted vertex.</param>
        /// <param name="clr">The color value that is applied to each emitted vertex.</param>
        /// <param name="angle">An angle by which the text is rotated (before applying the offset).</param>
        /// <param name="scale">A factor by which the text is scaled (before applying the offset).</param>
        /// <returns>The number of emitted vertices. This values isn't necessarily equal to the emitted arrays length.</returns>
        public int EmitTextVertices(string text, ref VertexC1P3T2[] vertices, float x, float y, float z, ColorRgba clr, float angle = 0.0f, float scale = 1.0f)
        {
            int len = this.EmitTextVertices(text, ref vertices);

            Vector3 offset = new Vector3(x, y, z);
            Vector2 xDot, yDot;
            MathF.GetTransformDotVec(angle, scale, out xDot, out yDot);

            for (int i = 0; i < len; i++)
            {
                MathF.TransformDotVec(ref vertices[i].Pos, ref xDot, ref yDot);
                Vector3.Add(ref vertices[i].Pos, ref offset, out vertices[i].Pos);
                vertices[i].Color = clr;
            }

            return len;
        }
Beispiel #13
0
 /// <summary>
 /// Emits a set of vertices based on a text. To render this text, simply use that set of vertices combined with
 /// the Fonts <see cref="Material"/>.
 /// </summary>
 /// <param name="text">The text to render.</param>
 /// <param name="vertices">The set of vertices that is emitted. You can re-use the same array each frame.</param>
 /// <param name="x">An X-Offset applied to the position of each emitted vertex.</param>
 /// <param name="y">An Y-Offset applied to the position of each emitted vertex.</param>
 /// <param name="z">An Z-Offset applied to the position of each emitted vertex.</param>
 /// <returns>The number of emitted vertices. This values isn't necessarily equal to the emitted arrays length.</returns>
 public int EmitTextVertices(string text, ref VertexC1P3T2[] vertices, float x, float y, float z = 0.0f)
 {
     return this.EmitTextVertices(text, ref vertices, x, y, z, ColorRgba.White);
 }
Beispiel #14
0
        public void Draw( IDrawDevice device )
        {
            if( GameObj == null || !_loaded || Layers == null || Layers.Count == 0 )
                return;

            Vector3 tempPos = GameObj.Transform.Pos;
            float tempScale = 1f;
            device.PreprocessCoords( ref tempPos, ref tempScale );

            int halfMapW = W / 2;
            int halfMapH = H / 2;

            for (var i = Layers.Values.GetEnumerator(); i.MoveNext();) {

                var layer = i.Current;

                if (!layer.Visible)
                    continue;

                for (int y = 0; y < H; y++) {

                    for (int x = 0; x < W; x++) {

                        // Is renderable tile available?
                        int gid = layer.GetTile(x, y);
                        if (gid <= 0)
                            continue;

                        // Get the correct tileset for this GID
                        var tileset = FindTilesetByGID(gid);
                        if (tileset == null)
                            continue;

                        // Remove tileset's FirstGID from the tile ID
                        // so we get the correct position in the image.
                        int tileX = (gid - tileset.FirstGID) % tileset.W;
                        int tileY = (gid - tileset.FirstGID) / tileset.W;

                        // Let 'em float...
                        float tx = (float)tileX;
                        float ty = (float)tileY;
                        float tw = (float)TileW;
                        float th = (float)TileH;
                        float twp = (float)tileset.WPixel;
                        float thp = (float)tileset.HPixel;

                        var vertices = new VertexC1P3T2[4];

                        // Get tileset main color and set layer's opacity on it
                        var color = tileset.Image.Res.MainColor.WithAlpha( layer.Opacity );

                        var uvRatio = tileset.Image.Res.MainTexture.Res.UVRatio;

                        // Texture coordinates
                        var uvRect = new Rect(
                            uvRatio.X * (tx * tw) / twp,
                            uvRatio.Y * (ty * th) / thp,
                            uvRatio.X * tw / twp,
                            uvRatio.Y * th / thp
                        );

                        // Position
                        float posX = tempPos.X + ((float)x - (float)halfMapW) * (float)TileW;
                        float posY = tempPos.Y + ((float)y - (float)halfMapH) * (float)TileH;

                        // Bottom-left
                        vertices[0] = new VertexC1P3T2();
                        vertices[0].Pos.X = (posX - tw / 2) * tempScale;
                        vertices[0].Pos.Y = (posY + th / 2) * tempScale;
                        vertices[0].Pos.Z = tempPos.Z;
                        vertices[0].TexCoord.X = uvRect.LeftX;
                        vertices[0].TexCoord.Y = uvRect.BottomY;
                        vertices[0].Color = color;

                        // Top-left
                        vertices[1] = new VertexC1P3T2();
                        vertices[1].Pos.X = (posX - tw / 2) * tempScale;
                        vertices[1].Pos.Y = (posY - th / 2) * tempScale;
                        vertices[1].Pos.Z = tempPos.Z;
                        vertices[1].TexCoord.X = uvRect.LeftX;
                        vertices[1].TexCoord.Y = uvRect.TopY;
                        vertices[1].Color = color;

                        // Top-right
                        vertices[2] = new VertexC1P3T2();
                        vertices[2].Pos.X = (posX + tw / 2) * tempScale;
                        vertices[2].Pos.Y = (posY - th / 2) * tempScale;
                        vertices[2].Pos.Z = tempPos.Z;
                        vertices[2].TexCoord.X = uvRect.RightX;
                        vertices[2].TexCoord.Y = uvRect.TopY;
                        vertices[2].Color = color;

                        // Bottom-right
                        vertices[3] = new VertexC1P3T2();
                        vertices[3].Pos.X = (posX + tw / 2) * tempScale;
                        vertices[3].Pos.Y = (posY + th / 2) * tempScale;
                        vertices[3].Pos.Z = tempPos.Z;
                        vertices[3].TexCoord.X = uvRect.RightX;
                        vertices[3].TexCoord.Y = uvRect.BottomY;
                        vertices[3].Color = color;

                        device.AddVertices(tileset.Image, VertexMode.Quads, vertices);
                    }
                }
            }
        }
Beispiel #15
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;
            device.PreprocessCoords(ref posTemp, ref scaleTemp);

            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].Pos.Z += baseDepthOffset;
                vertices[1].Pos.Z += baseDepthOffset;
                vertices[2].Pos.Z += baseDepthOffset;
                vertices[3].Pos.Z += baseDepthOffset;
            }
            else
            {
                // Flat actors need to apply depth individually per vertex
                float worldBaseY = transform.Pos.Y;
                vertices[0].Pos.Z += this.offset + (worldBaseY + edge1.Y * transform.Scale / scaleTemp + this.height) * depthPerUnit;
                vertices[1].Pos.Z += this.offset + (worldBaseY + edge2.Y * transform.Scale / scaleTemp + this.height) * depthPerUnit;
                vertices[2].Pos.Z += this.offset + (worldBaseY + edge3.Y * transform.Scale / scaleTemp + this.height) * depthPerUnit;
                vertices[3].Pos.Z += this.offset + (worldBaseY + edge4.Y * transform.Scale / scaleTemp + this.height) * depthPerUnit;
            }
        }