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); }
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); }
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(); }
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(); }
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(); }
/// <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(); }
[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)); }
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); } } } }
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); }
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; }
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); } }
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; }
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); }
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; }