Exemplo n.º 1
0
        public PerformanceAnalyzer(DXView dxView, string name = null, int initialCapacity = 10000)
        {
            if (dxView == null)
            {
                throw new ArgumentNullException("dxView");
            }

            _dxView          = dxView;
            _name            = name;
            _initialCapacity = initialCapacity;

            _dxScene = _dxView.DXScene;
        }
Exemplo n.º 2
0
        public SmoothLinesSample()
        {
            InitializeComponent();

            // NOTE: Standard GraphicsProfiles use the following MSAA and SSAA settings:
            // LowQualityHardwareRendering:    0xMSAA,  1xSSAA
            // NormalQualityHardwareRendering: 4xMSAA,  1xSSAA
            // HighQualityHardwareRendering:   4xMSAA,  4xSSAA
            // UltraQualityHardwareRendering:  2xMSAA, 16xSSAA

            // Get dpi scale
            if (Application.Current == null || Application.Current.MainWindow == null)
            {
                throw new Exception("Main application's window not yet created");
            }

            double dpiScaleX, dpiScaleY;

            DXView.GetDpiScale(Application.Current.MainWindow, out dpiScaleX, out dpiScaleY);

            _dpiScale = (dpiScaleX + dpiScaleY) * 0.5; // Get one value for dpi scale


            AddDXViewport3DGrid("No MSAA, No SSAA", "LowQualityHardwareRendering",
                                multisamplingCount: 0, supersamplingCount: 1, rowIndex: 0, columnIndex: 0);

            AddDXViewport3DGrid("4x MSAA, No SSAA", "NormalQualityHardwareRendering",
                                multisamplingCount: 4, supersamplingCount: 1, rowIndex: 0, columnIndex: 1);

            AddDXViewport3DGrid("4x MSAA, 4x SSAA", "HighQualityHardwareRendering",
                                multisamplingCount: 4, supersamplingCount: 4, rowIndex: 1, columnIndex: 0);

            AddDXViewport3DGrid("2x MSAA, 16x SSAA", "UltraQualityHardwareRendering",
                                multisamplingCount: 2, supersamplingCount: 16, rowIndex: 1, columnIndex: 1);


            // When there is no DPI scaling used, then do not show the DPI scale info
            if (_dpiScale == 1)
            {
                ScreenPixelLineThicknessTextBlock.Visibility = Visibility.Collapsed;
            }
            else
            {
                ScreenPixelLineThicknessTextBlock.Text = string.Format(System.Globalization.CultureInfo.InvariantCulture, ScreenPixelLineThicknessTextBlock.Text, _dpiScale);
            }
        }
Exemplo n.º 3
0
        public RectangularSelectionSample()
        {
            InitializeComponent();


            BoundsIn2DInfoControl.InfoText =
                @"The simplest technique to do rectangular selection is to convert the object's 3D bounds (axis aligned bounding box) into a 2D rectangle that represents the bounds on the screen. Then we can simply call IntersectsWith method that checks if the two 2D rectangles intersect.

Advantages:
- Very simple and fast when there is not a lot of 3D objects.
- Also selects the objects that are behind the objects closer to the camera.
- Can be used with only Ab3d.PowerToys (without Ab3d.DXEngine).

Disadvantages:
- Not accurate - the bounds of 3D objects and its bounds in 2D world are bigger then the the actual 3D object - selection is done before the user actually touches the 3D object.
- Slow when checking a lot of 3D objects.
- Cannot be used to select 3D lines.";


            ObjectIdMapInfoControl.InfoText =
                @"With Ab3d.DXEngine it is possible to render objects to a bitmap in such a way that each object is rendered with a different color where the color represents the object's id. When such a bitmap is rendered it is possible to get individual pixel colors and from that get the original object that was used to render the pixel.

Advantages:
- Pixel perfect accuracy.
- Fast when rendering a lot of objects.
- Can be used to select 3D lines.
- Can be extended to support some other selection types and not only rectangular selection.

Disadvantages:
- More complex (using custom rendering steps) than using simple bounding boxes.
- Slower when using simple 3D scene (DXEngine needs to set up the DirectX resources for another rendering pass; also much more memory is required).
- We need to find original WPF 3D object from DXEngine's RenderablePrimitive object.
- Cannot select objects that are behind some other objects that are closer to the camera.";


            MouseCameraControllerInfo1.AddCustomInfoLine(0, MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, "Rectangular selection");

            this.Cursor          = Cursors.Cross;
            OptionsBorder.Cursor = Cursors.Arrow;


            _selectedDiffuseMaterial = new DiffuseMaterial(Brushes.Red);

            _savedMaterials  = new Dictionary <GeometryModel3D, Material>();
            _savedLineColors = new Dictionary <BaseLineVisual3D, Color>();

            _disposables = new DisposeList();


            CreateTestScene();


            // Setup mouse events that will be used to show rectangular selection
            this.MouseLeftButtonDown += OnMouseLeftButtonDown;
            this.MouseMove           += OnMouseMove;
            this.MouseLeftButtonUp   += OnMouseLeftButtonUp;


            MainDXViewportView.DXSceneDeviceCreated += OnDxSceneDeviceCreated;

            this.Loaded += delegate(object sender, RoutedEventArgs args)
            {
                DXView.GetDpiScale(this, out _dpiScaleX, out _dpiScaleY);
            };

            this.Unloaded += delegate(object sender, RoutedEventArgs args)
            {
                if (_disposables != null)
                {
                    _disposables.Dispose();
                    _disposables = null;
                }

                MainDXViewportView.Dispose();
            };
        }
Exemplo n.º 4
0
        private void RenderButton_OnClick(object sender, RoutedEventArgs e)
        {
            // Update camera based on the HeadingSlider value
            UpdateCamera();

            var stopwatch = new Stopwatch();

            stopwatch.Start();


            BitmapWidth  = (int)ImageBorder.ActualWidth;
            BitmapHeight = (int)ImageBorder.ActualHeight;

            double dpiScaleX, dpiScaleY;

            DXView.GetDpiScale(this, out dpiScaleX, out dpiScaleY);

            double dpiX = 96.0 * dpiScaleX; // 96 is the default dpi value without any scaling
            double dpiY = 96.0 * dpiScaleY;


            // The following 6 lines are not needed because the DXViewportView is not shown:

            _viewport3D.Width  = BitmapWidth;
            _viewport3D.Height = BitmapHeight;

            // Because DXViewportView is not actually show, we need to call Measure and Arrange
            _viewport3D.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            _viewport3D.Arrange(new Rect(0, 0, _viewport3D.DesiredSize.Width, _viewport3D.DesiredSize.Height));

            // Update camera
            _camera.Refresh();

            // Update 3D lines
            Ab3d.Utilities.LinesUpdater.Instance.Refresh();


            int multiSamplingCount, superSamplingCount;

            GetAntiAliasingSettings(out multiSamplingCount, out superSamplingCount);


            var convertToNonPreMultipledAlpha = ConvertToNonPremultipliedAlphaCheckBox.IsChecked ?? false;

            if (ReuseWriteableBitmapCheckBox.IsChecked ?? false)
            {
                // Create only one instance of WriteableBitmap, then reuse it with other calls to RenderToBitmap

                if (_writeableBitmap == null) // we would also need to recreate the WriteableBitmap in case the size changes
                {
                    int finalBitmapWidth  = (int)(BitmapWidth * dpiScaleX);
                    int finalBitmapHeight = (int)(BitmapHeight * dpiScaleY);

                    // When using WriteableBitmap, the RenderToBitmap will use pre-multiplied alpha
                    // or non pre-multiplied alpha based on the pixel format (Pbgra32 for pre-multiplied alpha).
                    //
                    // When the rendered image is shown in WPF, then it is recommended to use Pbgra32 (pre-multiplied alpha)
                    // because this is also what is internally used by WPF.
                    //
                    // But when the image is saved to png image, then the image should be non pre-multiplied
                    // because png does not support pre-multiplied image.

                    var pixelFormat = convertToNonPreMultipledAlpha ? PixelFormats.Bgra32 : PixelFormats.Pbgra32;

                    _writeableBitmap = new WriteableBitmap(finalBitmapWidth, finalBitmapHeight, 96, 96, pixelFormat, null); // always use 96 as dpi for WriteableBitmap otherwise the bitmap will be shown too small
                }

                _dxViewportView.RenderToBitmap(_writeableBitmap, multiSamplingCount, superSamplingCount);

                _renderBitmap = _writeableBitmap;
            }
            else
            {
                // When we do not need to reuse the WriteableBitmap, we can use the following RenderToBitmap method:
                _renderBitmap = _dxViewportView.RenderToBitmap(width:  (int)(BitmapWidth * dpiScaleX),
                                                               height: (int)(BitmapHeight * dpiScaleY),
                                                               preferedMultisampling: multiSamplingCount, // when -1 is used, then the currently used multisampling is used
                                                               supersamplingCount: superSamplingCount,
                                                               dpiX: dpiX,
                                                               dpiY: dpiY,
                                                               convertToNonPreMultipledAlpha: convertToNonPreMultipledAlpha); // pixel format of the returned image will be Pbgra32 (when convertToNonPreMultipledAlpha is false) or Bgra32 when true.
            }


            // Display render time (note that the first time the scene is rendered the time is bigger because of additional initializations)
            stopwatch.Stop();
            InfoTextBlock.Text = string.Format("Render time: {0:0.0}ms", stopwatch.Elapsed.TotalMilliseconds);

            if (_isFirstRender)
            {
                InfoTextBlock.Text += " (note: render time of the first image is longer then the time to render other images)";
                _isFirstRender      = false;
            }

            RenderedImage.Source = _renderBitmap;

            TipTextBlock.Visibility = Visibility.Collapsed;

            SaveButton.Visibility = Visibility.Visible;
        }