Пример #1
0
        private PixelData RenderToTexture(int width, int height, Action <Canvas> renderMethod)
        {
            PixelData pixelData;

            using (Texture texture = new Texture(width, height, TextureSizeMode.NonPowerOfTwo, TextureMagFilter.Nearest, TextureMinFilter.Nearest))
                using (RenderTarget renderTarget = new RenderTarget(AAQuality.Off, true, texture))
                    using (DrawDevice device = new DrawDevice())
                    {
                        device.Projection     = ProjectionMode.Screen;
                        device.VisibilityMask = VisibilityFlag.AllGroups | VisibilityFlag.ScreenOverlay;
                        device.Target         = renderTarget;
                        device.TargetSize     = renderTarget.Size;
                        device.ViewportRect   = new Rect(renderTarget.Size);

                        device.PrepareForDrawcalls();
                        {
                            Canvas canvas = new Canvas();
                            canvas.Begin(device);
                            renderMethod(canvas);
                            canvas.End();
                        }
                        device.Render();

                        pixelData = texture.GetPixelData();
                    }

            return(pixelData);
        }
Пример #2
0
        private PixelData RenderToTexture(int width, int height, Action <Canvas> renderMethod)
        {
            PixelData pixelData;

            using (Texture texture = new Texture(width, height, TextureSizeMode.NonPowerOfTwo, TextureMagFilter.Nearest, TextureMinFilter.Nearest))
                using (RenderTarget renderTarget = new RenderTarget(AAQuality.Off, texture))
                    using (DrawDevice device = new DrawDevice())
                    {
                        device.Perspective    = PerspectiveMode.Flat;
                        device.VisibilityMask = VisibilityFlag.AllGroups | VisibilityFlag.ScreenOverlay;
                        device.RenderMode     = RenderMatrix.OrthoScreen;
                        device.Target         = renderTarget;
                        device.ViewportRect   = new Rect(renderTarget.Width, renderTarget.Height);

                        device.PrepareForDrawcalls();
                        {
                            Canvas canvas = new Canvas(device);
                            renderMethod(canvas);
                        }
                        device.Render(ClearFlag.All, ColorRgba.TransparentBlack, 1.0f);

                        pixelData = texture.GetPixelData();
                    }

            return(pixelData);
        }
Пример #3
0
        private void RenderableControl_Paint(object sender, PaintEventArgs e)
        {
            if (DualityApp.ExecContext == DualityApp.ExecutionContext.Terminated)
            {
                return;
            }
            if (DualityApp.GraphicsBackend == null)
            {
                return;
            }

            // Retrieve OpenGL context
            try { this.graphicsControl.MakeCurrent(); } catch (Exception) { return; }

            // Perform rendering
            Size size = graphicsControl.Control.ClientSize;

            device.TargetSize   = new Vector2(size.Width, size.Height);
            device.ViewportRect = new Rect(device.TargetSize);

            device.PrepareForDrawcalls();

            canvas.Begin(device);

            this.OnRender(canvas);

            canvas.End();

            device.Render();

            // Make sure the rendered result ends up on screen
            this.graphicsControl.SwapBuffers();
        }
Пример #4
0
        private void Blit(DrawDevice device, BatchInfo source, RenderTarget target, Vector2 targetSize, Rect viewportRect)
        {
            device.Target       = target;
            device.TargetSize   = targetSize;
            device.ViewportRect = viewportRect;

            device.PrepareForDrawcalls();
            device.AddFullscreenQuad(source, TargetResize.Stretch);
            device.Render();
        }
Пример #5
0
        public static void Blit(this RenderSetup renderSetup, DrawDevice device, BatchInfo source, Rect screenRect)
        {
            device.Target       = null;
            device.TargetSize   = screenRect.Size;
            device.ViewportRect = screenRect;

            device.PrepareForDrawcalls();
            device.AddFullscreenQuad(source, TargetResize.Stretch);
            device.Render();
        }
Пример #6
0
 /// <summary>
 /// Called to process the specified <see cref="RenderStep"/>.
 /// </summary>
 /// <param name="step"></param>
 /// <param name="drawDevice"></param>
 protected virtual void OnRenderSingleStep(RenderStep step, Scene scene, DrawDevice drawDevice)
 {
     drawDevice.PrepareForDrawcalls();
     if (step.Input == null)
     {
         this.CollectDrawcalls(step, scene, drawDevice);
     }
     else
     {
         drawDevice.AddFullscreenQuad(step.Input, step.InputResize);
     }
     drawDevice.Render();
 }
Пример #7
0
        [Test] public void RenderAndDispose()
        {
            PixelData pixelData;

            // In this test, we'll dispose the render target immediately after using it
            // and only retrieve the pixel data from its bound texture later on.
            // Since the texture that was rendered to is still alive, this should work.
            using (Texture texture = new Texture(8, 8, TextureSizeMode.NonPowerOfTwo, TextureMagFilter.Nearest, TextureMinFilter.Nearest))
            {
                using (RenderTarget renderTarget = new RenderTarget(AAQuality.High, false, texture))
                    using (DrawDevice device = new DrawDevice())
                    {
                        device.Projection     = ProjectionMode.Screen;
                        device.VisibilityMask = VisibilityFlag.AllGroups | VisibilityFlag.ScreenOverlay;
                        device.Target         = renderTarget;
                        device.TargetSize     = renderTarget.Size;
                        device.ViewportRect   = new Rect(renderTarget.Size);

                        device.PrepareForDrawcalls();
                        device.AddVertices(Material.SolidWhite, VertexMode.Quads,
                                           new VertexC1P3 {
                            Pos = new Vector3(0, 0, 0), Color = ColorRgba.Red
                        },
                                           new VertexC1P3 {
                            Pos = new Vector3(0, device.TargetSize.Y, 0), Color = ColorRgba.Red
                        },
                                           new VertexC1P3 {
                            Pos = new Vector3(device.TargetSize.X, device.TargetSize.Y, 0), Color = ColorRgba.Red
                        },
                                           new VertexC1P3 {
                            Pos = new Vector3(device.TargetSize.X, 0, 0), Color = ColorRgba.Red
                        });
                        device.Render();
                    }

                pixelData = texture.GetPixelData();
            }

            Assert.IsTrue(this.IsFilledWithColor(pixelData, ColorRgba.Red));
        }
Пример #8
0
        private void GenerateBackground(Random rng, int width, int height)
        {
            const int noiseSize    = 256;
            var       starTexture  = GeneratePointStarTexture(rng, width, height);
            var       noiseTexture = GenerateNoise(rng, noiseSize);

            if (Nebulae != null && Nebulae.Length > 0)
            {
                _material = new Material(Shader, ColorRgba.White, starTexture);

                using (var renderTarget = new RenderTarget(AAQuality.Off, starTexture))
                    using (var device = new DrawDevice())
                    {
                        device.Perspective    = PerspectiveMode.Flat;
                        device.VisibilityMask = VisibilityFlag.AllGroups | VisibilityFlag.ScreenOverlay;
                        device.RenderMode     = RenderMatrix.OrthoScreen;
                        device.Target         = renderTarget;
                        device.ViewportRect   = new Rect(renderTarget.Width, renderTarget.Height);

                        device.PrepareForDrawcalls();
                        var canvas = new Canvas(device);
                        canvas.State.SetMaterial(_material);

                        foreach (var n in Nebulae.Select(n => n.Res).Where(n => n != null))
                        {
                            _material.SetTexture("source", starTexture);
                            _material.SetTexture("noise", starTexture);
                            _material.SetUniform("color", 255f / n.Color.R, 255f / n.Color.G, 255f / n.Color.B);
                            _material.SetUniform("offset", n.Offset.X, n.Offset.Y);
                            _material.SetUniform("scale", n.Scale);
                            _material.SetUniform("density", n.Density);
                            _material.SetUniform("falloff", n.Falloff);
                            _material.SetUniform("tNoiseSize", noiseSize);
                            canvas.DrawRect(0, 0, width, height);
                            device.Render(ClearFlag.None, ColorRgba.TransparentBlack, 1.0f);
                        }
                    }
            }
        }
Пример #9
0
        private PixelData RenderToTexture(int width, int height, AAQuality antialiasing, Action <IDrawDevice> renderMethod)
        {
            PixelData pixelData;

            using (Texture texture = new Texture(width, height, TextureSizeMode.NonPowerOfTwo, TextureMagFilter.Nearest, TextureMinFilter.Nearest))
                using (RenderTarget renderTarget = new RenderTarget(antialiasing, false, texture))
                    using (DrawDevice device = new DrawDevice())
                    {
                        device.Projection     = ProjectionMode.Screen;
                        device.VisibilityMask = VisibilityFlag.AllGroups | VisibilityFlag.ScreenOverlay;
                        device.Target         = renderTarget;
                        device.TargetSize     = renderTarget.Size;
                        device.ViewportRect   = new Rect(renderTarget.Size);

                        device.PrepareForDrawcalls();
                        renderMethod(device);
                        device.Render();

                        pixelData = renderTarget.GetPixelData();
                    }

            return(pixelData);
        }
Пример #10
0
        private void RecreateTexturedBackground(TileSet levelTileset, ref TileMapLayer layer)
        {
            int w = layer.LayoutWidth;
            int h = layer.Layout.Length / w;

            Texture targetTexture;

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

            using (DrawDevice device = new DrawDevice()) {
                device.VisibilityMask = VisibilityFlag.AllFlags;
                device.Projection     = ProjectionMode.Screen;

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

                    device.PrepareForDrawcalls();

                    // ToDo
                    Material material = levelTileset.GetDefaultTile(0).Material.Res;
                    Texture  texture  = material.MainTexture.Res;

                    // Reserve the required space for vertex data in our locally cached buffer
                    int neededVertices = 4 * w * h;
                    if (cachedVertices == null || cachedVertices.Length < neededVertices)
                    {
                        cachedVertices = new VertexC1P3T2[neededVertices];
                    }

                    int vertexIndex = 0;

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

                            Point2 offset     = tile.MaterialOffset;
                            bool   isFlippedX = tile.IsFlippedX;
                            bool   isFlippedY = tile.IsFlippedY;

                            Rect uvRect = new Rect(
                                offset.X * texture.UVRatio.X / texture.ContentWidth,
                                offset.Y * texture.UVRatio.Y / texture.ContentHeight,
                                levelTileset.TileSize * texture.UVRatio.X / texture.ContentWidth,
                                levelTileset.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);

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

                            cachedVertices[vertexIndex + 0].Pos.X      = renderPos.X;
                            cachedVertices[vertexIndex + 0].Pos.Y      = renderPos.Y;
                            cachedVertices[vertexIndex + 0].Pos.Z      = renderPos.Z;
                            cachedVertices[vertexIndex + 0].TexCoord.X = uvRect.X;
                            cachedVertices[vertexIndex + 0].TexCoord.Y = uvRect.Y;
                            cachedVertices[vertexIndex + 0].Color      = ColorRgba.White;

                            cachedVertices[vertexIndex + 1].Pos.X      = renderPos.X + tileYStep.X;
                            cachedVertices[vertexIndex + 1].Pos.Y      = renderPos.Y + tileYStep.Y;
                            cachedVertices[vertexIndex + 1].Pos.Z      = renderPos.Z;
                            cachedVertices[vertexIndex + 1].TexCoord.X = uvRect.X;
                            cachedVertices[vertexIndex + 1].TexCoord.Y = uvRect.Y + uvRect.H;
                            cachedVertices[vertexIndex + 1].Color      = ColorRgba.White;

                            cachedVertices[vertexIndex + 2].Pos.X      = renderPos.X + tileXStep.X + tileYStep.X;
                            cachedVertices[vertexIndex + 2].Pos.Y      = renderPos.Y + tileXStep.Y + tileYStep.Y;
                            cachedVertices[vertexIndex + 2].Pos.Z      = renderPos.Z;
                            cachedVertices[vertexIndex + 2].TexCoord.X = uvRect.X + uvRect.W;
                            cachedVertices[vertexIndex + 2].TexCoord.Y = uvRect.Y + uvRect.H;
                            cachedVertices[vertexIndex + 2].Color      = ColorRgba.White;

                            cachedVertices[vertexIndex + 3].Pos.X      = renderPos.X + tileXStep.X;
                            cachedVertices[vertexIndex + 3].Pos.Y      = renderPos.Y + tileXStep.Y;
                            cachedVertices[vertexIndex + 3].Pos.Z      = renderPos.Z;
                            cachedVertices[vertexIndex + 3].TexCoord.X = uvRect.X + uvRect.W;
                            cachedVertices[vertexIndex + 3].TexCoord.Y = uvRect.Y;
                            cachedVertices[vertexIndex + 3].Color      = ColorRgba.White;

                            vertexIndex += 4;
                        }
                    }

                    device.AddVertices(material, VertexMode.Quads, cachedVertices, 0, vertexIndex);
                    device.Render();
                }
            }

            cachedTexturedBackground = targetTexture;
        }
Пример #11
0
        private void ProcessCombineSceneStep(DrawDevice drawDevice)
        {
            // ToDo: Split lighting to RGB channels
            // ToDo: Implement dynamic lighting/shadows (https://github.com/mattdesl/lwjgl-basics/wiki/2D-Pixel-Perfect-Shadows)

            Vector2 viewSize   = drawDevice.TargetSize;
            Vector2 viewOffset = new Vector2(
                drawDevice.RefCoord.X - viewSize.X / 2,
                drawDevice.RefCoord.Y - viewSize.Y / 2
                );

            float ambientLight   = levelHandler.AmbientLightCurrent;
            float viewWaterLevel = (levelHandler.WaterLevel - viewOffset.Y);

            // Blit ambient light color
            {
                BatchInfo material = drawDevice.RentMaterial();
                material.Technique = DrawTechnique.Solid;
                material.MainColor = new ColorRgba(ambientLight, 0, 0);
                this.Blit(drawDevice, material, lightingTarget);
            }

            // Render lights (target was set in previous step)
            drawDevice.PrepareForDrawcalls();

            foreach (GameObject actor in levelHandler.ActiveObjects)
            {
                LightEmitter light = actor.GetComponent <LightEmitter>();
                if (light != null)
                {
                    // World-space to screen-space position transformation
                    Vector3 pos = actor.Transform.Pos;
                    pos.X -= viewOffset.X;
                    pos.Y -= viewOffset.Y;

                    float left   = pos.X - light.RadiusFar;
                    float top    = pos.Y - light.RadiusFar;
                    float right  = pos.X + light.RadiusFar;
                    float bottom = pos.Y + light.RadiusFar;

                    if (left < viewSize.X &&
                        top < viewSize.Y &&
                        right > 0 &&
                        bottom > 0)
                    {
                        lightBuffer[0].Pos.X = left;
                        lightBuffer[0].Pos.Y = top;

                        lightBuffer[1].Pos.X = left;
                        lightBuffer[1].Pos.Y = bottom;

                        lightBuffer[2].Pos.X = right;
                        lightBuffer[2].Pos.Y = bottom;

                        lightBuffer[3].Pos.X = right;
                        lightBuffer[3].Pos.Y = top;

                        // Use TexCoord X & Y for screen-space Light position
                        lightBuffer[0].TexCoord.X = lightBuffer[1].TexCoord.X = lightBuffer[2].TexCoord.X = lightBuffer[3].TexCoord.X = pos.X;
                        lightBuffer[0].TexCoord.Y = lightBuffer[1].TexCoord.Y = lightBuffer[2].TexCoord.Y = lightBuffer[3].TexCoord.Y = pos.Y;
                        // Use TexCoord Z & W for Light radius
                        lightBuffer[0].TexCoord.Z = lightBuffer[1].TexCoord.Z = lightBuffer[2].TexCoord.Z = lightBuffer[3].TexCoord.Z = light.RadiusNear;
                        lightBuffer[0].TexCoord.W = lightBuffer[1].TexCoord.W = lightBuffer[2].TexCoord.W = lightBuffer[3].TexCoord.W = light.RadiusFar;

                        // Use Red channel for Light intensity
                        lightBuffer[0].Color.R = lightBuffer[1].Color.R = lightBuffer[2].Color.R = lightBuffer[3].Color.R = (byte)(light.Intensity * 255);
                        // Use Green channel for Light brightness
                        lightBuffer[0].Color.G = lightBuffer[1].Color.G = lightBuffer[2].Color.G = lightBuffer[3].Color.G = (byte)(light.Brightness * 255);

                        switch (light.Type)
                        {
                        default:
                        case LightType.Solid:
                            drawDevice.AddVertices(lightingMaterial, VertexMode.Quads, lightBuffer);
                            break;

                        case LightType.WithNoise:
                            drawDevice.AddVertices(lightingNoiseMaterial, VertexMode.Quads, lightBuffer);
                            break;
                        }
                    }
                }
            }

            drawDevice.Render();

            // Resize Blur targets
            SetupTargets((Point2)drawDevice.TargetSize);

            // Blit it into screen
            {
                BatchInfo material = drawDevice.RentMaterial();
                material.Technique   = DrawTechnique.Solid;
                material.MainTexture = mainTexture;
                this.Blit(drawDevice, material, targetPingPongA[0]);
            }

            // Downsample to lowest target
            for (int i = 1; i < targetPingPongA.Length; i++)
            {
                BatchInfo material = drawDevice.RentMaterial();
                material.Technique   = downsampleShader;
                material.MainTexture = targetPingPongA[i - 1].Targets[0];
                material.SetValue("pixelOffset", new Vector2(1f / material.MainTexture.Res.ContentWidth, 1f / material.MainTexture.Res.ContentHeight));

                this.Blit(drawDevice, material, targetPingPongA[i]);
            }

            // Blur all targets, separating horizontal and vertical blur
            for (int i = 0; i < targetPingPongA.Length; i++)
            {
                BatchInfo material = drawDevice.RentMaterial();
                material.Technique   = blurShader;
                material.MainTexture = targetPingPongA[i].Targets[0];
                material.SetValue("blurDirection", new Vector2(1f, 0f));
                material.SetValue("pixelOffset", new Vector2(1f / material.MainTexture.Res.ContentWidth, 1f / material.MainTexture.Res.ContentHeight));

                this.Blit(drawDevice, material, targetPingPongB[i]);

                material.MainTexture = targetPingPongB[i].Targets[0];
                material.SetValue("blurDirection", new Vector2(0f, 1f));
                material.SetValue("pixelOffset", new Vector2(1f / material.MainTexture.Res.ContentWidth, 1f / material.MainTexture.Res.ContentHeight));

                this.Blit(drawDevice, material, targetPingPongA[i]);
            }

            // Blit it into screen
            if (viewWaterLevel < viewSize.Y)
            {
                // Render lighting with water
                BatchInfo material = drawDevice.RentMaterial();
                material.Technique = combineSceneWaterShader;
                material.SetTexture("mainTex", mainTexture);
                material.SetTexture("lightTex", lightingTexture);
                material.SetTexture("displacementTex", noiseTexture); // Underwater displacement

                material.SetTexture("blurHalfTex", targetPingPongA[1].Targets[0]);
                material.SetTexture("blurQuarterTex", targetPingPongA[2].Targets[0]);

                material.SetValue("ambientLight", ambientLight);
                material.SetValue("darknessColor", levelHandler.DarknessColor);

                material.SetValue("waterLevel", viewWaterLevel / viewSize.Y);

                this.Blit(drawDevice, material, finalTarget);
            }
            else
            {
                // Render lighting without water
                BatchInfo material = drawDevice.RentMaterial();
                material.Technique = combineSceneShader;
                material.SetTexture("mainTex", mainTexture);
                material.SetTexture("lightTex", lightingTexture);

                material.SetTexture("blurHalfTex", targetPingPongA[1].Targets[0]);
                material.SetTexture("blurQuarterTex", targetPingPongA[2].Targets[0]);

                material.SetValue("ambientLight", ambientLight);
                material.SetValue("darknessColor", levelHandler.DarknessColor);

                this.Blit(drawDevice, material, finalTarget);
            }
        }
Пример #12
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;
        }
Пример #13
0
        protected override void OnRenderPointOfView(Scene scene, DrawDevice drawDevice, Rect viewportRect, Vector2 imageSize)
        {
            // Set up the picking render target to match the proper size
            if (this.pickingTex == null)
            {
                this.pickingTex = new Texture(
                    (int)viewportRect.W,
                    (int)viewportRect.H,
                    TextureSizeMode.Default,
                    TextureMagFilter.Nearest,
                    TextureMinFilter.Nearest);
            }
            if (this.pickingRT == null)
            {
                this.pickingRT = new RenderTarget(
                    AAQuality.Off,
                    true,
                    this.pickingTex);
                this.pickingRT.DepthBuffer = true;
            }
            this.ResizeRenderTarget(this.pickingRT, (Point2)viewportRect.Size);

            ContentRef <RenderTarget> oldDeviceTarget     = drawDevice.Target;
            ProjectionMode            oldDeviceProjection = drawDevice.Projection;
            VisibilityFlag            oldDeviceMask       = drawDevice.VisibilityMask;

            drawDevice.PickingIndex = 1;
            drawDevice.ClearColor   = ColorRgba.Black;
            drawDevice.ClearDepth   = 1.0f;
            drawDevice.Target       = this.pickingRT;
            drawDevice.TargetSize   = imageSize;
            drawDevice.ViewportRect = new Rect(this.pickingRT.Size);

            if (this.pickingMap == null)
            {
                this.pickingMap = new List <ICmpRenderer>();
            }
            this.pickingMap.Clear();

            // Render the world
            {
                drawDevice.VisibilityMask = oldDeviceMask & VisibilityFlag.AllGroups;
                drawDevice.Projection     = oldDeviceProjection;
                drawDevice.ClearFlags     = ClearFlag.All;

                drawDevice.PrepareForDrawcalls();
                this.CollectRendererDrawcalls(scene, drawDevice);
                drawDevice.Render();
            }

            // Render screen overlays
            if (this.renderOverlay)
            {
                drawDevice.VisibilityMask = oldDeviceMask;
                drawDevice.Projection     = ProjectionMode.Screen;
                drawDevice.ClearFlags     = ClearFlag.None;

                drawDevice.PrepareForDrawcalls();
                this.CollectRendererDrawcalls(scene, drawDevice);
                drawDevice.Render();
            }

            drawDevice.PickingIndex   = 0;
            drawDevice.VisibilityMask = oldDeviceMask;
            drawDevice.Projection     = oldDeviceProjection;
            drawDevice.Target         = oldDeviceTarget;

            // Move data to local buffer
            int pxNum     = this.pickingTex.ContentWidth * this.pickingTex.ContentHeight;
            int pxByteNum = pxNum * 4;

            if (this.pickingBuffer == null)
            {
                this.pickingBuffer = new byte[pxByteNum];
            }
            else if (pxByteNum > this.pickingBuffer.Length)
            {
                Array.Resize(ref this.pickingBuffer, Math.Max(this.pickingBuffer.Length * 2, pxByteNum));
            }

            this.pickingRT.GetPixelData(this.pickingBuffer);
        }
Пример #14
0
		private PixelData RenderToTexture(int width, int height, Action<Canvas> renderMethod)
		{
			PixelData pixelData;

			using (Texture texture = new Texture(width, height, TextureSizeMode.NonPowerOfTwo))
			using (RenderTarget renderTarget = new RenderTarget(AAQuality.Off, texture))
			using (DrawDevice device = new DrawDevice())
			{
				device.Perspective = PerspectiveMode.Flat;
				device.VisibilityMask = VisibilityFlag.AllGroups | VisibilityFlag.ScreenOverlay;
				device.RenderMode = RenderMatrix.OrthoScreen;
				device.Target = renderTarget;
				device.ViewportRect = new Rect(renderTarget.Width, renderTarget.Height);

				device.PrepareForDrawcalls();
				{
					Canvas canvas = new Canvas(device);
					renderMethod(canvas);
				}
				device.Render(ClearFlag.All, ColorRgba.TransparentBlack, 1.0f);

				pixelData = texture.GetPixelData();
			}

			return pixelData;
		}