Beispiel #1
0
        private void CreateAndBindTargets(int sizeX, int sizeY)
        {
            _d3dImageSource.SetRenderTargetDX10(null);

            Disposer.RemoveAndDispose(ref _renderTargetView);
            Disposer.RemoveAndDispose(ref _renderTargetIntermediateView);
            Disposer.RemoveAndDispose(ref _renderTargetIntermediateShaderResourceView);
            Disposer.RemoveAndDispose(ref _depthStencilView);
            Disposer.RemoveAndDispose(ref _renderTarget);
            Disposer.RemoveAndDispose(ref _renderTargetIntermediate);
            Disposer.RemoveAndDispose(ref _depthStencil);
            Disposer.RemoveAndDispose(ref _gammaCorrector);

            if (sizeX >= 2 && sizeY >= 2)
            {
                var colordesc = new Texture2DDescription
                {
                    BindFlags         = BindFlags.RenderTarget | BindFlags.ShaderResource,
                    Format            = Format.B8G8R8A8_UNorm,
                    Width             = sizeX,
                    Height            = sizeY,
                    MipLevels         = 1,
                    SampleDescription = new SampleDescription(1, 0),
                    Usage             = ResourceUsage.Default,
                    OptionFlags       = ResourceOptionFlags.Shared,
                    CpuAccessFlags    = CpuAccessFlags.None,
                    ArraySize         = 1
                };

                var renderTextureDescriptionForD3D9 = new Texture2DDescription
                {
                    BindFlags         = BindFlags.None,
                    Format            = Format.B8G8R8A8_UNorm,
                    Width             = sizeX,
                    Height            = sizeY,
                    MipLevels         = 1,
                    SampleDescription = new SampleDescription(1, 0),
                    Usage             = ResourceUsage.Staging,
                    OptionFlags       = ResourceOptionFlags.Shared,
                    CpuAccessFlags    = CpuAccessFlags.Read,
                    ArraySize         = 1
                };

                var depthdesc = new Texture2DDescription
                {
                    BindFlags         = BindFlags.DepthStencil,
                    Format            = Format.D32_Float_S8X24_UInt,
                    Width             = sizeX,
                    Height            = sizeY,
                    MipLevels         = 1,
                    SampleDescription = new SampleDescription(1, 0),
                    Usage             = ResourceUsage.Default,
                    OptionFlags       = ResourceOptionFlags.None,
                    CpuAccessFlags    = CpuAccessFlags.None,
                    ArraySize         = 1,
                };

                _renderTarget                 = new Texture2D(_device, colordesc);
                _renderTargetIntermediate     = new Texture2D(_device, colordesc);
                _depthStencil                 = new Texture2D(_device, depthdesc);
                _renderTargetIntermediateView = new RenderTargetView(_device, _renderTargetIntermediate);
                _renderTargetIntermediateShaderResourceView = new ShaderResourceView(_device, _renderTargetIntermediate);
                _renderTargetView = new RenderTargetView(_device, _renderTarget);
                _depthStencilView = new DepthStencilView(_device, _depthStencil);
                _gammaCorrector   = new D3D10GammaCorrector(_device, "Altaxo.CompiledShaders.Effects.GammaCorrector.cso");

                _d3dImageSource.SetRenderTargetDX10(_renderTarget);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Saves the project item as image to the provided stream.
        /// </summary>
        /// <param name="item">The item to export, for instance an item of type <see cref="Altaxo.Graph.Gdi.GraphDocument"/> or <see cref="Altaxo.Graph.Graph3D.GraphDocument"/>.</param>
        /// <param name="options">The export options.</param>
        /// <param name="toStream">The stream to save the image to.</param>
        public (int PixelsX, int PixelsY) ExportAsImageToStream(Altaxo.Main.IProjectItem item, Altaxo.Graph.Gdi.GraphExportOptions options, System.IO.Stream toStream)
        {
            // SharpDX.Configuration.EnableObjectTracking = true;
            // var listOfActiveObjects = SharpDX.Diagnostics.ObjectTracker.FindActiveObjects();

            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }
            if (!(item is Altaxo.Graph.Graph3D.GraphDocument))
            {
                throw new ArgumentException(string.Format("Expected item of type {0}, but it is of type {1}", typeof(Altaxo.Graph.Graph3D.GraphDocument), item.GetType()));
            }
            var doc = (Altaxo.Graph.Graph3D.GraphDocument)item;

            double sourceDpi = options.SourceDpiResolution;

            Viewing.D3D10Scene   scene = null;
            D3D10GraphicsContext g     = null;

            try
            {
                scene = new Viewing.D3D10Scene();
                g     = new D3D10GraphicsContext();

                doc.Paint(g);

                var matrix = doc.Camera.LookAtRHMatrix;

                var rect   = new RectangleD3D(PointD3D.Empty, doc.RootLayer.Size);
                var bounds = RectangleD3D.NewRectangleIncludingAllPoints(rect.Vertices.Select(x => matrix.Transform(x)));

                int pixelsX = (int)Math.Ceiling(sourceDpi * bounds.SizeX / 72.0);
                pixelsX = (int)(4 * Math.Ceiling((pixelsX + 3) / 4.0));

                int pixelsY = (int)(sourceDpi * bounds.SizeY / 72.0);

                double aspectRatio = pixelsY / (double)pixelsX;

                var sceneCamera = doc.Camera;

                if (sceneCamera is OrthographicCamera)
                {
                    var orthoCamera = (OrthographicCamera)sceneCamera;
                    orthoCamera = (OrthographicCamera)orthoCamera.WithWidthAtZNear(bounds.SizeX);

                    double offsX = -(1 + 2 * bounds.X / bounds.SizeX);
                    double offsY = -(1 + 2 * bounds.Y / bounds.SizeY);
                    sceneCamera = orthoCamera.WithScreenOffset(new PointD2D(offsX, offsY));
                }
                else if (sceneCamera is PerspectiveCamera)
                {
                    var viewProj     = sceneCamera.GetViewProjectionMatrix(1);                                                    // here we transform the points with AspectRatio=1, in order to get the AspectRatio of the ScreenBounds
                    var screenBounds = RectangleD3D.NewRectangleIncludingAllPoints(rect.Vertices.Select(x => viewProj.Transform(x)));
                    aspectRatio  = screenBounds.SizeY / screenBounds.SizeX;                                                       // this is the aspectRatio of our image
                    viewProj     = sceneCamera.GetViewProjectionMatrix(aspectRatio);                                              // now we get the transform with our aspectRatio determined above
                    screenBounds = RectangleD3D.NewRectangleIncludingAllPoints(rect.Vertices.Select(x => viewProj.Transform(x))); // this are our actual screenBounds, of course in relative screen coordinates, thus the ratio of sizeX and sizeY should now be 1

                    double scaleFactor = 2 / screenBounds.SizeX;                                                                  // since SizeX and SizeY should now be the same, we could have used SizeY alternatively
                    double offsX       = -(1 + scaleFactor * screenBounds.X);
                    double offsY       = -(1 + scaleFactor * screenBounds.Y);

                    pixelsY = (int)(4 * Math.Ceiling((aspectRatio * pixelsX + 3) / 4.0)); // now calculate the size of the image in y direction from the aspectRatio

                    var perspCamera = (PerspectiveCamera)sceneCamera;

                    sceneCamera = perspCamera.WithWidthAtZNear(perspCamera.WidthAtZNear / scaleFactor);
                    sceneCamera = sceneCamera.WithScreenOffset(new PointD2D(offsX, offsY));
                }
                else
                {
                    throw new NotImplementedException();
                }

                scene.SetCamera(sceneCamera);
                scene.SetLighting(doc.Lighting);
                scene.SetDrawing(g);

                Export(pixelsX, pixelsY, scene, options, toStream);
                return(pixelsX, pixelsY);
            }
            finally
            {
                Disposer.RemoveAndDispose(ref g);
                Disposer.RemoveAndDispose(ref scene);
            }
        }
Beispiel #3
0
 private static void EndD3D()
 {
     Disposer.RemoveAndDispose(ref D3D10ImageSource._d3DDevice);
     Disposer.RemoveAndDispose(ref D3D10ImageSource._d3DContext);
 }
Beispiel #4
0
        public void Export(int sizeX, int sizeY, ID3D10Scene scene, Altaxo.Graph.Gdi.GraphExportOptions options, System.IO.Stream toStream)
        {
            Device           device           = null;
            Texture2D        renderTarget     = null;
            Texture2D        renderTarget2    = null;
            Texture2D        depthStencil     = null;
            RenderTargetView renderTargetView = null;
            DepthStencilView depthStencilView = null;

            try
            {
                //device = new Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport, FeatureLevel.Level_10_0);
                device = D3D10DeviceFactory.Instance.BorrowDevice();
                // try to get the highest MSAA level with the highest quality
                int sampleCount        = 32;
                int qlevel_sampleCount = 0;

                for (; sampleCount >= 0; sampleCount /= 2)
                {
                    if (0 != (qlevel_sampleCount = device.CheckMultisampleQualityLevels(Format.B8G8R8A8_UNorm, sampleCount))) // quality level for sample count
                    {
                        break;
                    }
                }

                var colordesc = new Texture2DDescription
                {
                    BindFlags         = BindFlags.RenderTarget | BindFlags.ShaderResource,
                    Format            = Format.B8G8R8A8_UNorm_SRgb,
                    Width             = sizeX,
                    Height            = sizeY,
                    MipLevels         = 1,
                    SampleDescription = new SampleDescription(sampleCount, qlevel_sampleCount - 1),
                    Usage             = ResourceUsage.Default,
                    OptionFlags       = ResourceOptionFlags.Shared,
                    CpuAccessFlags    = CpuAccessFlags.None,
                    ArraySize         = 1
                };

                var depthdesc = new Texture2DDescription
                {
                    BindFlags         = BindFlags.DepthStencil,
                    Format            = Format.D32_Float_S8X24_UInt,
                    Width             = sizeX,
                    Height            = sizeY,
                    MipLevels         = 1,
                    SampleDescription = new SampleDescription(sampleCount, qlevel_sampleCount - 1),
                    Usage             = ResourceUsage.Default,
                    OptionFlags       = ResourceOptionFlags.None,
                    CpuAccessFlags    = CpuAccessFlags.None,
                    ArraySize         = 1,
                };

                renderTarget     = new Texture2D(device, colordesc);
                depthStencil     = new Texture2D(device, depthdesc);
                renderTargetView = new RenderTargetView(device, renderTarget);
                depthStencilView = new DepthStencilView(device, depthStencil);

                // Rendering

                device.OutputMerger.SetTargets(depthStencilView, renderTargetView);
                device.Rasterizer.SetViewports(new Viewport(0, 0, sizeX, sizeY, 0.0f, 1.0f));
                var clearColor = new Color4(1, 1, 1, 0); // Transparent
                if (options.BackgroundBrush != null)
                {
                    var axoColor = options.BackgroundBrush.Color.Color;
                    clearColor = new Color4(axoColor.ScR, axoColor.ScG, axoColor.ScB, axoColor.ScA);
                }
                device.ClearRenderTargetView(renderTargetView, clearColor);
                device.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);

                scene.Attach(device, new PointD2D(sizeX, sizeY));
                scene.Render();
                device.Flush();
                scene.Detach();

                if (sampleCount > 1) // if renderTarget is an MSAA render target, we first have to copy it into a non-MSAA render target before we can copy it to a CPU texture and then hope to save it
                {
                    // create a non-MSAA render target with the same size
                    var renderTarget2Description = new Texture2DDescription
                    {
                        BindFlags         = BindFlags.RenderTarget | BindFlags.ShaderResource,
                        Format            = Format.B8G8R8A8_UNorm_SRgb,
                        Width             = sizeX,
                        Height            = sizeY,
                        MipLevels         = 1,
                        SampleDescription = new SampleDescription(1, 0), // non MSAA
                        Usage             = ResourceUsage.Default,
                        OptionFlags       = ResourceOptionFlags.Shared,
                        CpuAccessFlags    = CpuAccessFlags.None,
                        ArraySize         = 1
                    };

                    renderTarget2 = new Texture2D(device, renderTarget2Description);                               // create non-MSAA render target
                    device.ResolveSubresource(renderTarget, 0, renderTarget2, 0, renderTarget.Description.Format); // copy from MSAA render target to the non-MSAA render target

                    var h = renderTarget;                                                                          // exchange renderTarget with renderTarget2
                    renderTarget  = renderTarget2;
                    renderTarget2 = h;
                }

                // renderTarget is now a non-MSAA renderTarget
                Texture2DExtensions.SaveToStream(renderTarget, options.ImageFormat, options.DestinationDpiResolution, toStream);
            }
            finally
            {
                Disposer.RemoveAndDispose(ref depthStencilView);
                Disposer.RemoveAndDispose(ref renderTargetView);
                Disposer.RemoveAndDispose(ref renderTarget2);
                Disposer.RemoveAndDispose(ref renderTarget);
                Disposer.RemoveAndDispose(ref depthStencil);

                device.ClearState();
                D3D10DeviceFactory.Instance.PassbackDevice(ref device);
                //device.QueryInterface<DeviceDebug>().ReportLiveDeviceObjects(ReportingLevel.Summary)
                // Disposer.RemoveAndDispose(ref device);
                //var activeObjects = SharpDX.Diagnostics.ObjectTracker.FindActiveObjects();
            }
        }