Exemplo n.º 1
0
        private void OnSettingsCheckboxChanged(object sender, RoutedEventArgs e)
        {
            if (!this.IsLoaded)
            {
                return;
            }

            // Antialiased CheckBox is enabled only when we do not use geometry shader
            Antialias3DLinesCheckBox.IsEnabled = !(UseGeometryShaderCheckBox.IsChecked ?? false);

            // DXSceneDeviceCreated is called after DXScene and DXDevice are created and before the 3D objects are initialized
            if (MainViewportView.DXScene != null) // In case of WPF rendering the DXScene is null
            {
                MainViewportView.DXScene.UseGeometryShaderFor3DLines = UseGeometryShaderCheckBox.IsChecked ?? false;
                MainViewportView.DXScene.RenderAntialiased3DLines    = Antialias3DLinesCheckBox.IsChecked ?? false;

                MainViewportView.Refresh(); // Force rendering again
            }
        }
Exemplo n.º 2
0
        public PerPixelRenderingSample()
        {
            InitializeComponent();

            // If possible use UltraQualityHardwareRendering settings (software rendering or WPF 3D will be used in case a hardware rendering cannot be used)
            // This will use supersampling and improve rendering quality.
            MainViewportView.GraphicsProfiles = new GraphicsProfile[] { GraphicsProfile.UltraQualityHardwareRendering,
                                                                        GraphicsProfile.HighQualitySoftwareRendering,
                                                                        GraphicsProfile.Wpf3D, };

            var dxTestScene = new TestScene(DXViewport3D);

            dxTestScene.CreatesTestScene();
            dxTestScene.StartAnimation();

            var wpfTestScene = new TestScene(WpfViewport3D);

            wpfTestScene.CreatesTestScene();
            wpfTestScene.StartAnimation();

            CopyWpfCamera(); // Copy settings from WpfCamera to DXCamera

            this.Unloaded += (sender, args) => MainViewportView.Dispose();
        }
Exemplo n.º 3
0
        public PolyLinesSample()
        {
            InitializeComponent();


            // Slider changes are delayed (they are applied half second after the last slider change)
            _sliderTimer          = new DispatcherTimer(DispatcherPriority.Normal);
            _sliderTimer.Interval = TimeSpan.FromSeconds(0.5);
            _sliderTimer.Tick    += new EventHandler(_sliderTimer_Tick);

            PresentationTypeTextBlock.Text = MainViewportView.PresentationType.ToString();


            // To force rendering with WPF 3D uncomment the following line (be sure to reduce the number of spirals before strating the sample):
            //MainViewportView.GraphicsProfiles = new GraphicsProfile[] { GraphicsProfile.Wpf3D };


            PresentationTypeInfoControl.InfoText =
                @"PresentationType property on DXViewportView defines how the rendered image is presented to WPF.

By default DXViewportView is using DirectXImage- this sends the rendered image to the WPF composition system.
An advantage of this mode is that the 3D image can be combined with other WPF elements - WPF elements are seen through 3D scene or can be placed on top to 3D scene.
A disadvantage is that DXEngine needs that DXEngine needs to wait until the graphics card fully finishes rendering the 3D scene before the image can be sent to WPF. When rendering a very complex scene (and with lots of 3D lines that require geometry shader) this can be significantly slower then using DirectXOverlay that does not wait for GPU to complete the rendering.

When DXViewportView is using DirectXOverlay mode, the DirectX gets its own part of the screen with its own Hwnd.
This means that when DXEngine sends all the data to the graphics card it can simply call Present method and continue execution of .net code. Because graphics card has its own region of screen, it can continue rendering in the background and when ready show the image.
A disadvantage of DirectXOverlay is that it does not allow WPF objects to be drawn on top or below of DXView (the 3D image cannot be composed with other WPF objects).

When rendering many 3D lines, the DirectXOverlay mode can add a significant performance improvement over the DirectXImage mode.

To change the PresentationType in this sample, open the sample's XAML and change the value of the PresentationType in the DXViewportView declaration.";


            UseGeometryShaderInfoControl.InfoText =
                @"When 'Use geometry shader' is checked, the DXEngine is using a geometry shader to create 3D lines. In this case each 3D line is created from 2 triangles. This way the DXEngine can render thick lines (lines with thickness greater than 1).

When the 'Use geometry shader' is unchecked, then the 3D lines are rendered directly by graphics card without geometry shader. This can render only lines with thickness set to 1. But because graphic card does not need to use geometry shader, it can render the lines faster.";


            Antialias3DLinesInfoControl.InfoText =
                @"The 'Antialiased 3D lines' is enabled only when the 'Use geometry shader' is unchecked.

It specifies how the 3D lines that are rendered directly by graphic card are rendered:
- when checked the 3D lines are rendered with antialiasing,
- when unchecked the 3D lines are not antialiased (allowing to render the lines even faster).";


            DrawCallsCountInfoControl.InfoText =
                @"Modern graphics cards can easily render millions of 3D lines.
But such performance can be achieved only when the CPU is not limiting the performance with spending too much time in the DirectX and driver code.

Usually the time spent on the CPU can be estimated with checking the number of DirectX draw calls that are issued by the application.
It is very good to have less then 1000 draw calls per frame. Usually the number of draw calls starts affecting the 60 FPS frame rate when the number of draw calls exeeds a few thousand.

This can be easily tested in this sample:
- set the 'No.lines in one spiral:' to 100
- set both 'X spirals count' and 'Y spirals count' to 100

This will render 1 million 3D lines. Rotate the scene and you will see that the engine will be able to render only a few frames per second (having 10.000 draw calls).

Now reduce the number of 'X spirals count' and 'Y spirals count' to 10. Then increase the 'No. lines in one spiral:' to 10.000. This will again generate 1 million 3D lines.
But this time the rendering will be done with only 100 draw calls and this will make the performance much much better. If you have good graphic card you can easily increase the number of lines in one spiral to 50.000.

The point to remember is when trying to improve the performance it is usually good to try to reduce the number of draw calls.
When rendering 3D lines this can be achieved with using MultiLineVisual3D or PolyLineVisual3D or even MultiPolyLineVisual3D instead of many LineVisual3D objects.

NOTE:
You can get rendering statistics (including number of draw calls) with setting Ab3d.DirectX.DXDiagnostics.IsCollectingStatistics to true. Then you can subscribe to MainViewportView.DXScene.AfterFrameRendered event and there read date from the MainViewportView.DXScene.Statistics object.";

            this.Loaded += (sender, args) => RecreatePolyLines();


            // IMPORTANT:
            // It is very important to call Dispose method on DXSceneView after the control is not used any more (see help file for more info)
            this.Unloaded += (sender, args) => MainViewportView.Dispose();
        }