예제 #1
0
        protected Texture2D SaveScreenShot(ref string filename, Action draw, Action drawOverlay)
        {
            filename = filename ?? "Default";
            filename = filename + "-" + Guid.NewGuid().ToString("B").ToUpper() + ".png";
            var backBuffer = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);

            backBuffer.Begin();
            GraphicsDevice.Clear(Color.Black);

            draw();

            backBuffer.End();

            var frontBuffer = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);

            frontBuffer.Begin();

            GraphicsDevice.Clear(Color.Black);

            GraphicsDevice.DrawFullscreenQuad(backBuffer, null, null, Color.White, null);
            GraphicsDevice.Textures[0] = null;

            drawOverlay();

            frontBuffer.End();

            using (var output = new FileStream(filename, FileMode.Create))
            {
                frontBuffer.SaveAsPng(output, frontBuffer.Width, frontBuffer.Height);
            }
            frontBuffer.Dispose();
            return(backBuffer);
        }
예제 #2
0
        /// <summary>
        /// Begins the rendering of all the lights in the scene.
        /// </summary>
        private void BeginLights(DrawingContext3D context)
        {
            if (hasLightBegin || hasSceneBegin)
            {
                throw new InvalidOperationException("Begin cannot be called until End has been successfully called.");
            }

            hasLightBegin = true;

            CreateLightBuffer();

            lightBuffer.Begin();

            // Setup render states for light rendering
            // Clear specular intensity to 0
            GraphicsDevice.Clear(new Color(context.ambientLightColor.X, context.ambientLightColor.Y, context.ambientLightColor.Z, 0));

            // Set render state for lights
            GraphicsDevice.BlendState        = lightBlendState;
            GraphicsDevice.DepthStencilState = DepthStencilState.None;

            // Set up textures and sampler states
            GraphicsDevice.Textures[0]      = depthBuffer;
            GraphicsDevice.Textures[1]      = normalBuffer;
            GraphicsDevice.SamplerStates[0] = GraphicsDevice.SamplerStates[1] = SamplerState.PointClamp;
        }
예제 #3
0
        private void DrawWithCombineMaterial(DrawingContext context, IList <IDrawableObject> drawables)
        {
            RenderTargetPool.Lock(InputTexture as RenderTarget2D);

            int i, p;

            for (p = 0; p < passes.Count; p++)
            {
                passes[p].GetActivePasses(workingPasses);

                RenderTarget2D intermediate = InputTexture as RenderTarget2D;
                for (i = 0; i < workingPasses.Count; ++i)
                {
                    var workingPass = (PostEffect)workingPasses[i];

                    RenderTarget2D previous = intermediate;
                    RenderTargetPool.Lock(previous);
                    intermediate = workingPass.PrepareRenderTarget(context.graphics, intermediate, null);
                    intermediate.Begin();

                    workingPass.InputTexture = previous;
                    workingPass.Draw(context, drawables);

                    intermediate.End();
                    RenderTargetPool.Unlock(previous);
                }

                passResults.Add(intermediate);
                workingPasses.Clear();
            }

            RenderTargetPool.Unlock(InputTexture as RenderTarget2D);

            if (fullScreenQuad == null)
            {
                fullScreenQuad = new FullScreenQuad(context.graphics);
            }

            context.graphics.BlendState = BlendState.Opaque;
            Material.texture            = InputTexture;

            for (i = 0, p = 0; p < passes.Count; p++)
            {
                if (passes[p].Enabled)
                {
                    Material.SetTexture(passes[p].TextureUsage, passResults[i]);
                    i++;
                }
            }

            fullScreenQuad.Draw(context, Material);

            lastEffects.Clear();
            passResults.Clear();
        }
예제 #4
0
        public override void Draw(DrawingContext context, IList <IDrawableObject> drawables)
        {
            if (Material == null)
            {
                Material = adoptionMaterial = new AdaptionMaterial(context.graphics);
            }
            else if (Material != adoptionMaterial)
            {
                throw new InvalidOperationException();
            }

            bool needLocalTexture = false;

            if (needLocalTexture = (currentFrame == null))
            {
                PrepareRenderTarget(context.graphics, InputTexture, null);
                currentFrame.Begin();
            }

            // Disable the adoption effect when we don't have a valid last frame texture
            // or when the adoption effect has been suspended for several frames.
#if SILVERLIGHT
            if (lastFrame == null || lastFrame.IsDisposed)
#else
            if (lastFrame == null || lastFrame.IsDisposed || lastFrame.IsContentLost)
#endif
            {
                CopyToScreen(context, drawables);
            }
            else
            {
                var graphics = context.graphics;
                graphics.Textures[0]      = adoptionMaterial.texture;
                graphics.Textures[1]      = lastFrame;
                graphics.SamplerStates[0] = graphics.SamplerStates[1] = SamplerState.PointClamp;
                adoptionMaterial.effect.Delta.SetValue((1 - (float)Math.Pow(0.98f, 30 * context.elapsedTime)) * Speed);

                base.Draw(context, drawables);

                graphics.SamplerStates[1] = context.SamplerState;
            }

            if (needLocalTexture)
            {
                currentFrame.End();

                InputTexture = currentFrame;
                CopyToScreen(context, drawables);
            }

            RenderTargetPool.Unlock(lastFrame);
            lastFrame    = currentFrame;
            currentFrame = null;
        }
예제 #5
0
        /// <summary>
        /// Begins the shadowmap generation process and clears the shadowmap to white.
        /// </summary>
        private void Begin()
        {
            if (hasBegin)
            {
                throw new InvalidOperationException("Begin cannot be called until End has been successfully called.");
            }

            hasBegin = true;
            if (renderTarget == null || renderTarget.IsDisposed ||
#if !SILVERLIGHT
                renderTarget.IsContentLost ||
#endif
                renderTarget.Format != SurfaceFormat || renderTarget.Width != Size)
            {
                if (renderTarget != null)
                {
                    renderTarget.Dispose();
                }
                renderTarget = new RenderTarget2D(graphics, Size, Size, false, SurfaceFormat,
                                                  graphics.PresentationParameters.DepthStencilFormat);
            }
            renderTarget.Begin();
            graphics.Clear(Color.White);
        }
예제 #6
0
        protected Texture2D SaveScreenShot(string filename, Action draw)
        {
            filename = filename ?? "Default";
            var backBuffer = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);

            backBuffer.Begin();
            GraphicsDevice.Clear(Color.Black);

            draw();

            backBuffer.End();
            using (var output = new FileStream(filename + "-" + Guid.NewGuid().ToString("B").ToUpper() + ".png", FileMode.Create))
            {
                backBuffer.SaveAsPng(output, backBuffer.Width, backBuffer.Height);
            }
            return(backBuffer);
        }
예제 #7
0
        /// <summary>
        /// Ends the shadowmap generation process and returns the result shadowmap texture.
        /// </summary>
        private Texture2D End(DrawingContext context)
        {
            if (!hasBegin)
            {
                throw new InvalidOperationException("Begin must be called successfully before End can be called.");
            }

            hasBegin = false;
            Texture2D map = renderTarget.End();

            if (BlurEnabled)
            {
                if (depthBlur == null || depthBlur.IsDisposed ||
#if !SILVERLIGHT
                    depthBlur.IsContentLost ||
#endif
                    depthBlur.Format != SurfaceFormat || depthBlur.Width != Size)
                {
                    if (depthBlur != null)
                    {
                        depthBlur.Dispose();
                    }
                    depthBlur = new RenderTarget2D(graphics, Size, Size, false, SurfaceFormat,
                                                   graphics.PresentationParameters.DepthStencilFormat);
                }

                // Blur H
                depthBlur.Begin();
                blur.texture   = map;
                blur.Direction = 0;
                fullScreenQuad.Draw(context, blur);
                map = depthBlur.End();

                // Blur V
                renderTarget.Begin();
                blur.texture   = map;
                blur.Direction = MathHelper.PiOver2;
                fullScreenQuad.Draw(context, blur);
                map = renderTarget.End();
            }

            context.textures[TextureUsage.ShadowMap] = map;
            return(Texture = map);
        }
예제 #8
0
        /// <summary>
        /// Draws this pass using the specified drawing context.
        /// </summary>
        public override void Draw(DrawingContext context, IList <IDrawableObject> drawables)
        {
            var passes = context.Passes;

            for (int i = 0; i < passes.Count; ++i)
            {
                if (passes[i].Enabled && passes[i] is LightPrePass)
                {
                    return;
                }
            }

            var graphics = context.graphics;

            if (depthMaterial == null)
            {
                depthMaterial = new DepthMaterial(graphics);
            }

            var surfaceFormat = SurfaceFormat.Single;

            if (depthBuffer == null || depthBuffer.IsDisposed || depthBuffer.IsContentLost)
            {
                if (depthBuffer != null)
                {
                    depthBuffer.Dispose();
                }
                depthBuffer = new RenderTarget2D(graphics, graphics.Viewport.Width, graphics.Viewport.Height,
                                                 false, surfaceFormat, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.DiscardContents);
            }

            if (drawingPass == null)
            {
                drawingPass = new DrawingPass();
                drawingPass.MaterialUsage = MaterialUsage.Depth;
            }

            depthBuffer.Begin();
            graphics.Clear(Color.White);
            drawingPass.Draw(context, drawables);
            depthBuffer.End();

            context.textures[TextureUsage.DepthBuffer] = depthBuffer;
        }
예제 #9
0
        /// <summary>
        /// Draws the specified scene.
        /// </summary>
        public void Draw(float elapsedTime, Matrix view, Matrix projection)
        {
            if (isDrawing)
            {
                throw new InvalidOperationException("Cannot trigger another drawing of the scene while it's still been drawn");
            }

            this.matrices.View          = view;
            this.matrices.Projection    = projection;
            this.isDrawing              = true;
            this.VertexOffset           = 0;
            this.VertexBuffer           = null;
            this.PreviousMaterial       = null;
            this.elapsedTime            = elapsedTime;
            this.totalTime             += TimeSpan.FromSeconds(elapsedTime);
            this.totalSeconds           = (float)totalTime.TotalSeconds;
            this.boundingBoxNeedsUpdate = true;

            if (rootPass == null)
            {
                return;
            }

            graphics.SetVertexBuffer(null);
            graphics.Textures[0] = null;

            UpdateDefaultSamplerStates();

            AddDrawablesToView(matrices.ViewFrustum);

            UpdatePassGraph();
            UpdateActivePasses();

            RenderTarget2D lastRenderTarget            = null;
            RenderTarget2D intermediate                = null;
            bool           overrideViewFrustumLastPass = false;

            for (int i = 0; i < activePasses.Count; ++i)
            {
                var pass = activePasses[i];
                var overrideViewFrustum = false;

                // Query the drawables in the current view frustum only when the view frustum changed
                // or the pass overrides the frustum.
                Matrix passView, passProjection;
                if (pass.TryGetViewFrustum(out passView, out passProjection))
                {
                    matrices.View       = passView;
                    matrices.Projection = passProjection;
                    overrideViewFrustum = true;
                }

                if (overrideViewFrustum || overrideViewFrustumLastPass)
                {
                    AddDrawablesToView(matrices.ViewFrustum);
                    overrideViewFrustumLastPass = overrideViewFrustum;
                }

                if ((pass.PassOperation & PassOperation.EndRenderTarget) != 0)
                {
                    intermediate.End();
                    lastRenderTarget = intermediate;
                }

                if ((pass.PassOperation & PassOperation.BeginRenderTarget) != 0)
                {
                    intermediate = pass.PrepareRenderTarget(graphics, intermediate, pass.PassFormat);
                    intermediate.Begin();
                    RenderTargetPool.Lock(intermediate);
                }

                var postEffect = pass as IPostEffect;
                if (postEffect != null)
                {
                    postEffect.InputTexture = lastRenderTarget;
                    pass.Draw(this, drawablesInViewFrustum);
                    RenderTargetPool.Unlock(lastRenderTarget);
                }
                else
                {
                    pass.Draw(this, drawablesInViewFrustum);
                }
            }

            currentFrame++;
            isDrawing = false;
        }
예제 #10
0
        private void DrawWithoutCombineMaterial(DrawingContext context, IList <IDrawableObject> drawables)
        {
            RenderTargetPool.Lock(InputTexture as RenderTarget2D);

            int i, p;

            for (p = 0; p < passes.Count; p++)
            {
                passes[p].GetActivePasses(workingPasses);

                RenderTarget2D intermediate = InputTexture as RenderTarget2D;
                for (i = 0; i < workingPasses.Count - 1; ++i)
                {
                    var workingPass = (PostEffect)workingPasses[i];

                    RenderTarget2D previous = intermediate;
                    RenderTargetPool.Lock(previous);
                    intermediate = workingPass.PrepareRenderTarget(context.graphics, intermediate, null);
                    intermediate.Begin();

                    workingPass.InputTexture = previous;
                    workingPass.Draw(context, drawables);

                    intermediate.End();
                    RenderTargetPool.Unlock(previous);
                }

                PostEffect lastEffect;
                RenderTargetPool.Lock(intermediate);

                if (workingPasses.Count > 0)
                {
                    lastEffect = (PostEffect)workingPasses[workingPasses.Count - 1];
                }
                else
                {
                    if (basicPostEffect == null)
                    {
                        basicPostEffect          = new PostEffect();
                        basicPostEffect.Material = new TextureMaterial(context.graphics);
                    }
                    lastEffect = basicPostEffect;
                }

                lastEffects.Add(lastEffect);
                passResults.Add(intermediate);

                workingPasses.Clear();
            }

            RenderTargetPool.Unlock(InputTexture as RenderTarget2D);

            for (i = 0, p = 0; p < passes.Count; p++)
            {
                if (passes[p].Enabled)
                {
                    lastEffects[i].BlendState   = passes[p].BlendState;
                    lastEffects[i].InputTexture = passResults[i];
                    lastEffects[i].Draw(context, drawables);

                    RenderTargetPool.Unlock(passResults[i]);
                    i++;
                }
            }

            lastEffects.Clear();
            passResults.Clear();
        }
예제 #11
0
        void CaptureScreen()
        {
            if (screenCapture != null)
            {
                screenCapture.Dispose();
            }

            using (var graphics = glControl.CreateGraphics())
            {
                var cameraZoom = camera.Zoom;
                var cameraPos  = camera.Position;
                ResetCamera();

                if (frameBufferObjects)
                {
                    using (var renderTarget = new RenderTarget2D(textureWidth, textureHeight))
                    {
                        var pixelsPerMeter = spriteBatch.PixelsPerMeter;
                        spriteBatch.SetDimensions(textureWidth, textureHeight);
                        spriteBatch.PixelsPerMeter = project.PixelsPerMillimeter;

                        renderTarget.Begin();
                        RenderModel(new RectangleF(-backgroundWidth / 2, -backgroundHeight / 2, backgroundWidth, backgroundHeight), CaptureMarkerSize, 2);
                        renderTarget.End();

                        screenCapture = renderTarget.Texture.ToBitmap();
                        if (textureWidth != backgroundWidth || textureHeight != backgroundHeight)
                        {
                            using (var rawCapture = screenCapture)
                            {
                                screenCapture = rawCapture.Clone(new Rectangle(
                                                                     (textureWidth - backgroundWidth) / 2,
                                                                     (textureHeight - backgroundHeight) / 2,
                                                                     backgroundWidth, backgroundHeight),
                                                                 screenCapture.PixelFormat);
                            }
                        }

                        screenCapture.SetResolution(project.PixelsPerMillimeter * MillimetersPerInch, project.PixelsPerMillimeter * MillimetersPerInch);
                        spriteBatch.PixelsPerMeter = pixelsPerMeter;
                        spriteBatch.SetDimensions(glControl.Width, glControl.Height);
                    }
                }
                else
                {
                    screenCapture = new Bitmap(backgroundWidth, backgroundHeight);
                    var blockColumns    = backgroundWidth / glControl.Width;
                    var blockRows       = backgroundHeight / glControl.Height;
                    var remainderWidth  = backgroundWidth % glControl.Width;
                    var remainderHeight = backgroundHeight % glControl.Height;

                    var pixelsPerMeter = spriteBatch.PixelsPerMeter;
                    spriteBatch.PixelsPerMeter = project.PixelsPerMillimeter;

                    var viewWidthInMillimeters  = glControl.Width / project.PixelsPerMillimeter;
                    var viewHeightInMillimeters = glControl.Height / project.PixelsPerMillimeter;
                    var widthInMillimeters      = backgroundWidth / project.PixelsPerMillimeter;
                    var heightInMillimeters     = backgroundHeight / project.PixelsPerMillimeter;
                    var offsetX = -widthInMillimeters / 2 + viewWidthInMillimeters / 2;
                    var offsetY = -heightInMillimeters / 2 + viewHeightInMillimeters / 2;

                    for (int i = 0; i <= blockRows; i++)
                    {
                        for (int j = 0; j <= blockColumns; j++)
                        {
                            if (j == blockColumns && remainderWidth == 0)
                            {
                                continue;
                            }
                            if (i == blockRows && remainderHeight == 0)
                            {
                                continue;
                            }

                            var captureWidth  = j == blockColumns ? remainderWidth : glControl.Width;
                            var captureHeight = i == blockRows ? remainderHeight : glControl.Height;
                            var bitmapData    = screenCapture.LockBits(new System.Drawing.Rectangle(j * glControl.Width, i * glControl.Height, captureWidth, captureHeight),
                                                                       System.Drawing.Imaging.ImageLockMode.WriteOnly,
                                                                       System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                            camera.Position = new Vector2(offsetX + j * viewWidthInMillimeters, offsetY + i * viewHeightInMillimeters);
                            RenderModel(new RectangleF(-backgroundWidth / 2, -backgroundHeight / 2, backgroundWidth, backgroundHeight), DefaultMarkerSize, 2);
                            glControl.SwapBuffers();

                            GL.ReadPixels(0, 0, bitmapData.Width, bitmapData.Height, PixelFormat.Bgr, PixelType.UnsignedByte, bitmapData.Scan0);
                            screenCapture.UnlockBits(bitmapData);
                        }
                    }

                    screenCapture.RotateFlip(RotateFlipType.RotateNoneFlipY);
                    screenCapture.SetResolution(project.PixelsPerMillimeter * MillimetersPerInch, project.PixelsPerMillimeter * MillimetersPerInch);
                    spriteBatch.PixelsPerMeter = pixelsPerMeter;
                }

                camera.Zoom     = cameraZoom;
                camera.Position = cameraPos;
                deviceDpiX      = graphics.DpiX;
            }
        }