Пример #1
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);
                    device.AddVertices(p.Input, VertexMode.Quads, vertices);
                }

                this.drawDevice.Render(p.ClearFlags, p.ClearColor, p.ClearDepth);
                Profile.TimePostProcessing.EndMeasure();
            }
        }
Пример #2
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];
            }

            if (this.texture == null)
            {
                return(len);
            }

            float     curOffset = 0.0f;
            GlyphData glyphData;
            Rect      uvRect;
            float     glyphXOff;
            float     glyphYOff;
            float     glyphXAdv;

            for (int i = 0; i < text.Length; i++)
            {
                this.ProcessTextAdv(text, i, out glyphData, out uvRect, out glyphXAdv, out glyphXOff, out glyphYOff);

                Vector2 glyphPos;
                glyphPos.X = MathF.Round(curOffset + glyphXOff);
                glyphPos.Y = MathF.Round(0 + glyphYOff);

                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);
        }
Пример #3
0
        public void RenderTexturedBackground(IDrawDevice device, ref TileMapLayer layer, int cacheIndex, float x, float y)
        {
            if (!cachedTexturedBackground.IsAvailable || cachedTexturedBackgroundAnimated)
            {
                RecreateTexturedBackground(ref layer);
            }

            // Fit the input material rect to the output size according to rendering step config
            Vector3 renderPos = new Vector3(device.ViewerPos.X - device.TargetSize.X / 2, device.ViewerPos.Y - device.TargetSize.Y / 2, layer.Depth);

            // Fit the target rect to actual pixel coordinates to avoid unnecessary filtering offsets
            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)
            {
                // AMD Bugfix?
                renderPos.Y -= 0.004f;
            }

            // Reserve the required space for vertex data in our locally cached buffer
            int neededVertices = 4;

            if (cachedVertices == null || cachedVertices.Length < neededVertices)
            {
                cachedVertices = new VertexC1P3T2[neededVertices];
            }

            // Render it as world-space fullscreen quad
            cachedVertices[0].Pos = new Vector3(renderPos.X, renderPos.Y, renderPos.Z);
            cachedVertices[1].Pos = new Vector3(renderPos.X + device.TargetSize.X, renderPos.Y, renderPos.Z);
            cachedVertices[2].Pos = new Vector3(renderPos.X + device.TargetSize.X, renderPos.Y + device.TargetSize.Y, renderPos.Z);
            cachedVertices[3].Pos = new Vector3(renderPos.X, renderPos.Y + device.TargetSize.Y, renderPos.Z);

            cachedVertices[0].TexCoord = new Vector2(0f, 0f);
            cachedVertices[1].TexCoord = new Vector2(1f, 0f);
            cachedVertices[2].TexCoord = new Vector2(1f, 1f);
            cachedVertices[3].TexCoord = new Vector2(0f, 1f);

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

            // Setup custom pixel shader
            BatchInfo material = device.RentMaterial();

            material.Technique   = texturedBackgroundShader;
            material.MainTexture = cachedTexturedBackground;
            material.SetValue("horizonColor", layer.BackgroundColor);
            material.SetValue("shift", new Vector2(x, y));
            material.SetValue("parallaxStarsEnabled", layer.ParallaxStarsEnabled ? 1f : 0f);

            device.AddVertices(material, VertexMode.Quads, cachedVertices, 0, 4);
        }
Пример #4
0
 public StaticVertex(VertexC1P3T2 vtx)
 {
     x = vtx.Pos.X;
     y = vtx.Pos.Y;
     z = vtx.Pos.Z;
     w = vtx.DepthOffset;
     u = vtx.TexCoord.X;
     v = vtx.TexCoord.Y;
     r = vtx.Color.R;
     g = vtx.Color.G;
     b = vtx.Color.B;
     a = vtx.Color.A;
 }
Пример #5
0
            private void PrepareVineVertices(ref VertexC1P3T2[] vertices, IDrawDevice device, ColorRgba mainClr, Rect uvRect)
            {
                if (vertices == null /*|| vertices.Length != 4*/)
                {
                    vertices = new VertexC1P3T2[(ChunkPositions.Length - 1) * 4];
                }

                Vector3 posTemp = this.gameobj.Transform.Pos;

                float uvStep = (uvRect.H / ChunkPositions.Length);

                int vertexOffset = 0;

                for (int i = 1; i < ChunkPositions.Length; i++)
                {
                    ref Vector2 source = ref ChunkPositions[i - 1];
                    ref Vector2 target = ref ChunkPositions[i];
Пример #6
0
        public Widget()
        {
            VisibilityGroup = VisibilityFlag.Group0;

            _areaOnScreen           = new Polygon(4);
            _activeAreaOnScreen     = new Polygon(4);
            _tempActiveAreaOnScreen = new Vector3[4];

            _rect        = new Duality.Rect(0, 0, 50, 50);
            _visibleRect = Rect.Empty;

            _vertices = new VertexC1P3T2[36];
            _points   = new MultiSpacePoint[16];

            for (int i = 0; i < _vertices.Length; i++)
            {
                _vertices[i] = new VertexC1P3T2();
            }
        }
Пример #7
0
        public void RenderTexturedBackground(IDrawDevice device, ref TileMapLayer layer, int cacheIndex, float x, float y)
        {
            if (cachedTexturedBackground == null || cachedTexturedBackgroundAnimated)
            {
                RecreateTexturedBackground(ref layer);
            }

            // Fit the input material rect to the output size according to rendering step config
            Vector3 renderPos = new Vector3(device.RefCoord.X - device.TargetSize.X / 2, device.RefCoord.Y - device.TargetSize.Y / 2, layer.Depth);
            float   scale     = 1.0f;

            device.PreprocessCoords(ref renderPos, ref scale);

            // Fit the target rect to actual pixel coordinates to avoid unnecessary filtering offsets
            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;
                // AMD Bugfix?
                renderPos.Y -= 0.001f;
            }

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

            int neededVertices = 4;

            if (cachedVertices[cacheIndex] == null || cachedVertices[cacheIndex].Length < neededVertices)
            {
                cachedVertices[cacheIndex] = vertexData = new VertexC1P3T2[neededVertices];
            }
            else
            {
                vertexData = cachedVertices[cacheIndex];
            }

            // Render it as world-space fullscreen quad
            vertexData[0].Pos = new Vector3(renderPos.X, renderPos.Y, renderPos.Z);
            vertexData[1].Pos = new Vector3(renderPos.X + device.TargetSize.X, renderPos.Y, renderPos.Z);
            vertexData[2].Pos = new Vector3(renderPos.X + device.TargetSize.X, renderPos.Y + device.TargetSize.Y, renderPos.Z);
            vertexData[3].Pos = new Vector3(renderPos.X, renderPos.Y + device.TargetSize.Y, renderPos.Z);

            vertexData[0].TexCoord = new Vector2(0.0f, 0.0f);
            vertexData[1].TexCoord = new Vector2(1f, 0.0f);
            vertexData[2].TexCoord = new Vector2(1f, 1f);
            vertexData[3].TexCoord = new Vector2(0.0f, 1f);

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

            // Setup custom pixel shader
            BatchInfo material = new BatchInfo(texturedBackgroundShader, cachedTexturedBackground);

            material.SetValue("horizonColor", layer.BackgroundColor);
            material.SetValue("shift", new Vector2(x, y));

            device.AddVertices(material, VertexMode.Quads, vertexData);
        }
Пример #8
0
        protected void PrepareVertices(ref VertexC1P3T2[] vertices, IDrawDevice device)
        {
            Texture mainTex = this.RetrieveMainTexture();
            ColorRgba mainClr = this.RetrieveMainColor();

            // Determine texture sprite rect
            Rect blockSpriteRect;
            if (mainTex != null)
                blockSpriteRect = Rect.AlignTopLeft(0, 0, mainTex.PxWidth, mainTex.PxHeight);
            else
                blockSpriteRect = Rect.AlignTopLeft(0, 0, 1, 1);

            // Determine block rects to draw
            Collider col = this.GameObj.GetComponent<Collider>();
            var blockShapes = col.Shapes.OfType<Collider.PolyShapeInfo>();
            var blockRects = blockShapes.Select(p => p.AABB).ToArray();

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

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

            if (vertices == null || vertices.Length != blockRects.Length * 4) vertices = new VertexC1P3T2[blockRects.Length * 4];
            for (int i = 0; i < blockRects.Length; i++)
            {
                Rect blockRect = blockRects[i];
                Rect uvRect = new Rect(
                    (blockRect.x - blockSpriteRect.x) / blockSpriteRect.w,
                    (blockRect.y - blockSpriteRect.y) / blockSpriteRect.h,
                    blockRect.w / blockSpriteRect.w,
                    blockRect.h / blockSpriteRect.h);

                Rect rectTemp = blockRect.Transform(this.GameObj.Transform.Scale.Xy);
                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);

                vertices[i * 4 + 0].pos.X = posTemp.X + edge1.X;
                vertices[i * 4 + 0].pos.Y = posTemp.Y + edge1.Y;
                vertices[i * 4 + 0].pos.Z = posTemp.Z;
                vertices[i * 4 + 0].texCoord.X = uvRect.x;
                vertices[i * 4 + 0].texCoord.Y = uvRect.y;
                vertices[i * 4 + 0].clr = mainClr;

                vertices[i * 4 + 1].pos.X = posTemp.X + edge2.X;
                vertices[i * 4 + 1].pos.Y = posTemp.Y + edge2.Y;
                vertices[i * 4 + 1].pos.Z = posTemp.Z;
                vertices[i * 4 + 1].texCoord.X = uvRect.x;
                vertices[i * 4 + 1].texCoord.Y = uvRect.MaxY;
                vertices[i * 4 + 1].clr = mainClr;

                vertices[i * 4 + 2].pos.X = posTemp.X + edge3.X;
                vertices[i * 4 + 2].pos.Y = posTemp.Y + edge3.Y;
                vertices[i * 4 + 2].pos.Z = posTemp.Z;
                vertices[i * 4 + 2].texCoord.X = uvRect.MaxX;
                vertices[i * 4 + 2].texCoord.Y = uvRect.MaxY;
                vertices[i * 4 + 2].clr = mainClr;

                vertices[i * 4 + 3].pos.X = posTemp.X + edge4.X;
                vertices[i * 4 + 3].pos.Y = posTemp.Y + edge4.Y;
                vertices[i * 4 + 3].pos.Z = posTemp.Z;
                vertices[i * 4 + 3].texCoord.X = uvRect.MaxX;
                vertices[i * 4 + 3].texCoord.Y = uvRect.y;
                vertices[i * 4 + 3].clr = mainClr;
            }
        }
Пример #9
0
        private void RecreateTexturedBackground(ref TileMapLayer layer)
        {
            int w = layer.LayoutWidth;
            int h = layer.Layout.Length / w;

            cachedTexturedBackgroundAnimated = false;

            Texture renderTarget;

            if (cachedTexturedBackground != null)
            {
                renderTarget = cachedTexturedBackground.Res;
            }
            else
            {
                renderTarget = new Texture(w * 32, h * 32, TextureSizeMode.NonPowerOfTwo, TextureMagFilter.Linear, TextureMinFilter.Linear, TextureWrapMode.Repeat, TextureWrapMode.Repeat);

                switch (layer.BackgroundStyle)
                {
                case BackgroundStyle.Sky:
                default:
                    texturedBackgroundShader = ContentResolver.Current.RequestShader("TexturedBackground");
                    break;

                case BackgroundStyle.Circle:
                    texturedBackgroundShader = ContentResolver.Current.RequestShader("TexturedBackgroundCircle");
                    break;
                }
            }

            using (DrawDevice device = new DrawDevice()) {
                device.VisibilityMask = VisibilityFlag.AllFlags;
                device.RenderMode     = RenderMatrix.ScreenSpace;

                device.Target       = new RenderTarget(AAQuality.Off, false, renderTarget);
                device.TargetSize   = new Vector2(w * 32, h * 32);
                device.ViewportRect = new Rect(device.TargetSize);

                device.PrepareForDrawcalls();

                Material material = null;
                Texture  texture  = null;

                // Reserve the required space for vertex data in our locally cached buffer
                int            neededVertices = 4 * w * h;
                VertexC1P3T2[] vertexData     = new VertexC1P3T2[neededVertices];

                int vertexBaseIndex = 0;

                for (int x = 0; x < w; x++)
                {
                    for (int y = 0; y < h; y++)
                    {
                        LayerTile tile = layer.Layout[x + y * layer.LayoutWidth];

                        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);

                                cachedTexturedBackgroundAnimated = true;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            offset     = tile.MaterialOffset;
                            isFlippedX = tile.IsFlippedX;
                            isFlippedY = tile.IsFlippedY;
                        }

                        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
                            );

                        if (isFlippedX)
                        {
                            uvRect.X += uvRect.W;
                            uvRect.W *= -1;
                        }
                        if (isFlippedY)
                        {
                            uvRect.Y += uvRect.H;
                            uvRect.H *= -1;
                        }

                        Vector3 renderPos = new Vector3(x * 32, y * 32, 0);
                        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;
                        }

                        Vector2 tileXStep = new Vector2(32, 0);
                        Vector2 tileYStep = new Vector2(0, 32);

                        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      = ColorRgba.White;

                        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;
                        vertexData[vertexBaseIndex + 1].TexCoord.X = uvRect.X;
                        vertexData[vertexBaseIndex + 1].TexCoord.Y = uvRect.Y + uvRect.H;
                        vertexData[vertexBaseIndex + 1].Color      = ColorRgba.White;

                        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;
                        vertexData[vertexBaseIndex + 2].TexCoord.X = uvRect.X + uvRect.W;
                        vertexData[vertexBaseIndex + 2].TexCoord.Y = uvRect.Y + uvRect.H;
                        vertexData[vertexBaseIndex + 2].Color      = ColorRgba.White;

                        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;
                        vertexData[vertexBaseIndex + 3].TexCoord.X = uvRect.X + uvRect.W;
                        vertexData[vertexBaseIndex + 3].TexCoord.Y = uvRect.Y;
                        vertexData[vertexBaseIndex + 3].Color      = ColorRgba.White;

                        vertexBaseIndex += 4;
                    }
                }

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

                device.Render();
            }

            cachedTexturedBackground = renderTarget;
        }
Пример #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;
		}
Пример #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="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>
		public void EmitTextVertices(string text, ref VertexC1P3T2[] vertices, float x, float y, float z, ColorRgba clr, float angle = 0.0f, float scale = 1.0f)
		{
			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 < vertices.Length; i++)
			{
				Vector3 vertex = vertices[i].Pos;

				MathF.TransformDotVec(ref vertex, ref xDot, ref yDot);
				vertex += offset;

				vertices[i].Pos = vertex;
				vertices[i].Color = clr;
			}
		}
Пример #12
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);
            }
        }
Пример #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="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;
		}
Пример #14
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>
		public void EmitTextVertices(string text, ref VertexC1P3T2[] vertices, float x, float y, ColorRgba clr)
		{
			this.EmitTextVertices(text, ref vertices);
			
			Vector3 offset = new Vector3(x, y, 0);

			for (int i = 0; i < vertices.Length; i++)
			{
				Vector3 vertex = vertices[i].Pos;
				vertex += offset;
				vertices[i].Pos = vertex;
				vertices[i].Color = clr;
			}
		}
Пример #15
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="clr">The color value that is applied to 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, ColorRgba clr)
		{
			int[] vertLen = this.EmitVertices(ref vertText, ref vertIcons);
			
			Vector3 offset = new Vector3(x, y, 0);

			if (clr == ColorRgba.White)
			{
				for (int i = 0; i < vertText.Length; i++)
				{
					for (int j = 0; j < vertLen[i + 1]; j++)
					{
						Vector3.Add(ref vertText[i][j].Pos, ref offset, out vertText[i][j].Pos);
					}
				}
				for (int i = 0; i < vertLen[0]; i++)
				{
					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++)
					{
						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++)
				{
					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;
		}
Пример #16
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>
		public void EmitVertices(ref VertexC1P3T2[][] vertText, ref VertexC1P3T2[] vertIcons, float x, float y, float z = 0.0f)
		{
			this.EmitVertices(ref vertText, ref vertIcons, x, y, z, ColorRgba.White);
		}
Пример #17
0
        void ICmpRenderer.Draw(IDrawDevice device)
        {
            if (_inEditor)
            {
                if (FXSource != null && FXTarget != null)
                {
                    Canvas c = new Canvas(device);

                    FXSource.DrawInEditor(c);
                    FXTarget.DrawInEditor(c);

                    Vector3 src = FXSource.GameObj.Transform.Pos;
                    Vector3 tar = FXTarget.GameObj.Transform.Pos;

                    c.PushState();

                    Vector3 line   = tar - src;
                    Vector2 normal = line.Xy.PerpendicularLeft;

                    Vector3 p1 = line * 0.33f;
                    Vector3 p2 = line * 0.33f;
                    Vector3 p3 = line * 0.67f;
                    Vector3 p4 = line * 0.67f;

                    p1 += src + new Vector3(normal * .04f, p1.Z);
                    p2 += src + new Vector3(normal * -.02f, p2.Z);
                    p3 += src + new Vector3(normal * .02f, p3.Z);
                    p4 += src + new Vector3(normal * -.04f, p4.Z);

                    c.State.ColorTint = Colors.Pink;
                    c.DrawLine(src.X, src.Y, src.Z, p1.X, p1.Y, p1.Z);
                    c.DrawLine(p1.X, p1.Y, p1.Z, p2.X, p2.Y, p2.Z);
                    c.DrawLine(p2.X, p2.Y, p2.Z, p3.X, p3.Y, p3.Z);
                    c.DrawLine(p3.X, p3.Y, p3.Z, p4.X, p4.Y, p4.Z);
                    c.DrawLine(p4.X, p4.Y, p4.Z, tar.X, tar.Y, tar.Z);

                    c.PopState();
                }
            }
            else
            {
                foreach (LightningBolt bolt in _bolts)
                {
                    if (bolt.IsAlive)
                    {
                        if (!bolt.BatchInfos.ContainsKey(device) || !bolt.BatchInfos[device].IsReady)
                        {
                            bolt.PrepareTextureForDrawDevice(device);
                        }

                        LightningBolt.BoltData bd = bolt.BatchInfos[device];

                        float scaleAtStart = device.GetScaleAtZ(FXSource.GameObj.Transform.Pos.Z);
                        float scaleAtEnd   = device.GetScaleAtZ(FXTarget.GameObj.Transform.Pos.Z);

                        Vector2 axis   = (bd.End - bd.Start).Xy;
                        Vector2 normal = axis.PerpendicularLeft.Normalized;

                        VertexC1P3T2[] v = new VertexC1P3T2[4];

                        v[0]          = new VertexC1P3T2();
                        v[0].Pos      = bd.Start - new Vector3(normal * Sway * scaleAtStart, 0);
                        v[0].TexCoord = new Vector2(0, 0);
                        v[0].Color    = bolt.CurrentColor;

                        v[1]          = new VertexC1P3T2();
                        v[1].Pos      = bd.Start + new Vector3(normal * Sway * scaleAtStart, 0);
                        v[1].TexCoord = new Vector2(0, 1);
                        v[1].Color    = bolt.CurrentColor;

                        v[2]          = new VertexC1P3T2();
                        v[2].Pos      = bd.End + new Vector3(normal * Sway * scaleAtEnd, 0);
                        v[2].TexCoord = new Vector2(1, 1);
                        v[2].Color    = bolt.CurrentColor;

                        v[3]          = new VertexC1P3T2();
                        v[3].Pos      = bd.End - new Vector3(normal * Sway * scaleAtEnd, 0);
                        v[3].TexCoord = new Vector2(1, 0);
                        v[3].Color    = bolt.CurrentColor;

                        device.AddVertices(bd.BatchInfo, VertexMode.Quads, v);
                    }
                }
            }
        }
Пример #18
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>
		public void EmitVertices(ref VertexC1P3T2[][] vertText, ref VertexC1P3T2[] vertIcons)
		{
			this.ValidateVertexCache();
			
			// Allocate memory
			if (vertIcons == null || vertIcons.Length != this.vertIconsCache.Length) vertIcons = new VertexC1P3T2[this.vertIconsCache.Length];
			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.vertTextCache[i].Length)
					vertText[i] = new VertexC1P3T2[this.vertTextCache[i].Length];
			}

			// Copy actual data
			Array.Copy(this.vertIconsCache, vertIcons, this.vertIconsCache.Length);
			for (int i = 0; i < this.vertTextCache.Length; i++)
				Array.Copy(this.vertTextCache[i], vertText[i], this.vertTextCache[i].Length);
		}
Пример #19
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>
		public void EmitVertices(ref VertexC1P3T2[][] vertText, ref VertexC1P3T2[] vertIcons, float x, float y, float z, ColorRgba clr, Vector2 xDot, Vector2 yDot)
		{
			this.EmitVertices(ref vertText, ref vertIcons);
			
			Vector3 offset = new Vector3(x, y, z);
			for (int i = 0; i < vertText.Length; i++)
			{
				for (int j = 0; j < vertText[i].Length; j++)
				{
					Vector3 vertex = vertText[i][j].Pos;

					MathF.TransformDotVec(ref vertex, ref xDot, ref yDot);
					vertex += offset;

					vertText[i][j].Pos = vertex;
					vertText[i][j].Color *= clr;
				}
			}
			for (int i = 0; i < vertIcons.Length; i++)
			{
				Vector3 vertex = vertIcons[i].Pos;

				MathF.TransformDotVec(ref vertex, ref xDot, ref yDot);
				vertex += offset;

				vertIcons[i].Pos = vertex;
				vertIcons[i].Color *= clr;
			}
		}
Пример #20
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++;
                }
            }
        }
Пример #21
0
        private void RenderTexturedBackground(IDrawDevice device)
        {
            if (cachedTexturedBackground == null)
            {
                return;
            }

            float timeMult = Time.TimeMult;

            backgroundX     += timeMult * 1.2f;
            backgroundY     += timeMult * -0.2f + timeMult * MathF.Sin(backgroundPhase) * 0.6f;
            backgroundPhase += timeMult * 0.001f;

            Vector3 renderPos = new Vector3(0, 0, (device.NearZ + device.FarZ) * 0.5f);

            // Fit the target rect to actual pixel coordinates to avoid unnecessary filtering offsets
            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;
                // AMD Bugfix?
                renderPos.Y -= 0.001f;
            }

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

            int neededVertices = 4;

            if (cachedVertices == null || cachedVertices.Length < neededVertices)
            {
                cachedVertices = vertexData = new VertexC1P3T2[neededVertices];
            }
            else
            {
                vertexData = cachedVertices;
            }

            // Render it as world-space fullscreen quad
            vertexData[0].Pos = new Vector3(renderPos.X, renderPos.Y, renderPos.Z);
            vertexData[1].Pos = new Vector3(renderPos.X + device.TargetSize.X, renderPos.Y, renderPos.Z);
            vertexData[2].Pos = new Vector3(renderPos.X + device.TargetSize.X, renderPos.Y + device.TargetSize.Y, renderPos.Z);
            vertexData[3].Pos = new Vector3(renderPos.X, renderPos.Y + device.TargetSize.Y, renderPos.Z);

            vertexData[0].TexCoord = new Vector2(0.0f, 0.0f);
            vertexData[1].TexCoord = new Vector2(1f, 0.0f);
            vertexData[2].TexCoord = new Vector2(1f, 1f);
            vertexData[3].TexCoord = new Vector2(0.0f, 1f);

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

            // Setup custom pixel shader
            BatchInfo material = new BatchInfo(texturedBackgroundShader, cachedTexturedBackground);

            material.SetValue("horizonColor", horizonColor);
            material.SetValue("shift", new Vector2(backgroundX, backgroundY));

            device.AddVertices(material, VertexMode.Quads, vertexData);
        }
Пример #22
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;
		}
Пример #23
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="clr">The color value that is applied to each emitted vertex.</param>
		public void EmitVertices(ref VertexC1P3T2[][] vertText, ref VertexC1P3T2[] vertIcons, float x, float y, ColorRgba clr)
		{
			this.EmitVertices(ref vertText, ref vertIcons);
			
			Vector3 offset = new Vector3(x, y, 0);

			for (int i = 0; i < vertText.Length; i++)
			{
				for (int j = 0; j < vertText[i].Length; j++)
				{
					Vector3 vertex = vertText[i][j].Pos;
					vertex += offset;
					vertText[i][j].Pos = vertex;
					vertText[i][j].Color *= clr;
				}
			}
			for (int i = 0; i < vertIcons.Length; i++)
			{
				Vector3 vertex = vertIcons[i].Pos;
				vertex += offset;
				vertIcons[i].Pos = vertex;
				vertIcons[i].Color *= clr;
			}
		}
Пример #24
0
        [Test] public void RentAndClear()
        {
            VertexBatchStore memory = new VertexBatchStore();

            // Repeatedly rent slices of varying types from memory
            {
                VertexSlice <VertexC1P3> slice = memory.Rent <VertexC1P3>(4);
                slice[0] = new VertexC1P3 {
                    Color = new ColorRgba(0)
                };
                slice[1] = new VertexC1P3 {
                    Color = new ColorRgba(1)
                };
                slice[2] = new VertexC1P3 {
                    Color = new ColorRgba(2)
                };
                slice[3] = new VertexC1P3 {
                    Color = new ColorRgba(3)
                };
            }
            {
                VertexSlice <VertexC1P3T2> slice = memory.Rent <VertexC1P3T2>(3);
                slice[0] = new VertexC1P3T2 {
                    Color = new ColorRgba(4)
                };
                slice[1] = new VertexC1P3T2 {
                    Color = new ColorRgba(5)
                };
                slice[2] = new VertexC1P3T2 {
                    Color = new ColorRgba(6)
                };
            }
            {
                VertexSlice <VertexC1P3> slice = memory.Rent <VertexC1P3>(2);
                slice[0] = new VertexC1P3 {
                    Color = new ColorRgba(7)
                };
                slice[1] = new VertexC1P3 {
                    Color = new ColorRgba(8)
                };
            }
            {
                VertexSlice <VertexC1P3> slice = memory.Rent <VertexC1P3>(1);
                slice[0] = new VertexC1P3 {
                    Color = new ColorRgba(9)
                };
            }

            // Assert correct storage property values
            Assert.AreEqual(
                1 + Math.Max(
                    VertexDeclaration.Get <VertexC1P3>().TypeIndex,
                    VertexDeclaration.Get <VertexC1P3T2>().TypeIndex),
                memory.TypeIndexCount);
            Assert.AreEqual(1, memory.GetBatchCount <VertexC1P3>());
            Assert.AreEqual(1, memory.GetBatchCount <VertexC1P3T2>());

            // Retrieve specific internal vertex arrays
            VertexBatch <VertexC1P3>   batchA    = memory.GetBatch <VertexC1P3>(0);
            VertexBatch <VertexC1P3T2> batchB    = memory.GetBatch <VertexC1P3T2>(0);
            RawList <VertexC1P3>       verticesA = batchA.Vertices;
            RawList <VertexC1P3T2>     verticesB = batchB.Vertices;

            // Assert that they contain all the data we submitted in the correct order
            Assert.AreEqual(7, batchA.Count);
            Assert.AreEqual(3, batchB.Count);
            Assert.AreEqual(7, verticesA.Count);
            Assert.AreEqual(3, verticesB.Count);

            Assert.AreEqual(new ColorRgba(0), verticesA[0].Color);
            Assert.AreEqual(new ColorRgba(1), verticesA[1].Color);
            Assert.AreEqual(new ColorRgba(2), verticesA[2].Color);
            Assert.AreEqual(new ColorRgba(3), verticesA[3].Color);

            Assert.AreEqual(new ColorRgba(4), verticesB[0].Color);
            Assert.AreEqual(new ColorRgba(5), verticesB[1].Color);
            Assert.AreEqual(new ColorRgba(6), verticesB[2].Color);

            Assert.AreEqual(new ColorRgba(7), verticesA[4].Color);
            Assert.AreEqual(new ColorRgba(8), verticesA[5].Color);
            Assert.AreEqual(new ColorRgba(9), verticesA[6].Color);

            // Clear all vertices
            memory.Clear();

            // Assert correct storage property values
            Assert.AreEqual(0, memory.TypeIndexCount);
            Assert.AreEqual(0, memory.GetBatchCount <VertexC1P3>());
            Assert.AreEqual(0, memory.GetBatchCount <VertexC1P3T2>());

            // Assert that the vertices are gone, but capacity isn't
            Assert.AreEqual(0, batchA.Count);
            Assert.AreEqual(0, batchB.Count);
            Assert.AreEqual(0, verticesA.Count);
            Assert.AreEqual(0, verticesB.Count);
            Assert.GreaterOrEqual(verticesA.Capacity, 7);
            Assert.GreaterOrEqual(verticesB.Capacity, 3);
        }
Пример #25
0
        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;
                            drawVertices[i].Pos.Y = shapeVertices[i].Y;
                            drawVertices[i].Pos.Z = 0.0f;
                            MathF.TransformCoord(ref drawVertices[i].Pos.X, ref drawVertices[i].Pos.Y, objAngle, viewSpaceScale);

                            drawVertices[i].Pos.X += viewSpacePos.X;
                            drawVertices[i].Pos.Y += viewSpacePos.Y;
                            drawVertices[i].Pos.Z += viewSpacePos.Z;
                            drawVertices[i].Color  = vertexOutlineColor;
                        }

                        // 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);
                }
            }
        }
Пример #26
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>
		public void 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);
			this.EmitVertices(ref vertText, ref vertIcons, x, y, z, clr, xDot, yDot);
		}
Пример #27
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);
		}
Пример #28
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;
		}