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