private void DisposeDXViewportView() { if (_mainDXViewportView == null) { return; } if (_camera1 != null) { _camera1.StopRotation(); RootGrid.Children.Remove(_camera1); _camera1 = null; } if (_mouseCameraController != null) { RootGrid.Children.Remove(_mouseCameraController); _mouseCameraController = null; } _mainDXViewportView.SceneRendered -= MainDxViewportViewOnSceneRendered; _mainDXViewportView.Dispose(); _mainDXViewportView = null; }
public void UnsubscribeLastShownDXViewportView() { if (_lastShownDXViewportView == null) { return; } _lastShownDXViewportView.GraphicsProfileRejected -= OnGraphicsProfileRejected; _lastShownDXViewportView.DXSceneInitialized -= OnDXSceneInitialized; _lastShownDXViewportView.Unloaded -= OnDXViewportViewUnloaded; _lastShownDXViewportView = null; SetRejectedGraphicsProfileWarningImageToolTip(null); // If no DXViewportView will be shown, then we show the "Selected graphics profile:" instead of "Used graphics profile:" GraphicsProfileTypeTextBlock.Text = "Selected graphics profile:"; if (DXEngineSettings.Current.GraphicsProfiles != null && DXEngineSettings.Current.GraphicsProfiles[0] != null) { ShowGraphicsProfile(DXEngineSettings.Current.GraphicsProfiles[0], dxViewportView: null); } Wpf3DRenderingWarningPanel.Visibility = Visibility.Collapsed; }
public void Update(DXViewportView MainDXViewportView) { Color4 preC = Color4.White; for (int i = 0; i < colors.Count; i++) { Color4 c = colors[i]; colors[i] = WColor.GetColor(i, preC); preC = colors[i]; } if (material == null) { return; } material.PositionColors = colors.ToArray(); material.Update(); var sceneNode = MainDXViewportView.GetSceneNodeForWpfObject(node.GetGeometryModel3D()); if (sceneNode != null) { sceneNode.NotifySceneNodeChange(SceneNode.SceneNodeDirtyFlags.MaterialChanged); } }
public void Dispose() { if (MainDXViewportView != null) { MainDXViewportView.Dispose(); MainDXViewportView = null; } MainViewport = null; WireframeVisual = null; }
private DXViewportView CreateSimpleDXSceneViewFromCode(DXViewportView masterDXViewportView, RenderingTypes renderingType, out TargetPositionCamera targetPositionCamera, out MouseCameraController mouseCameraController) { Viewport3D viewport3D = new Viewport3D(); DXViewportView createDXViewportView; if (masterDXViewportView != null) { // Create a child DXViewportView with using a constructor that takes a masterDXViewportView. // When useMasterRenderingSteps parameter is true (by default), then the RenderingSteps in the master DXViewportView.DXScene are used. // To customize rendering of a child DXViewportView, set useMasterRenderingSteps to false. This will create new RenderingSteps that can be customized (see below). bool useMasterRenderingSteps = renderingType == RenderingTypes.Standard; createDXViewportView = new DXViewportView(masterDXViewportView, viewport3D, useMasterRenderingSteps); } else { // Create master DXViewportView with using constructor that takes only Viewport3D. createDXViewportView = new DXViewportView(viewport3D); } createDXViewportView.DXSceneDeviceCreated += delegate(object sender, EventArgs e) { // Enable transparency sorting for each View (this way transparent objects are correctly rendered for each child view camera). createDXViewportView.DXScene.IsTransparencySortingEnabled = true; SetSpecialRenderingType(createDXViewportView, renderingType); }; // Because each view supports its own camera, we need to create a new TargetPositionCamera and MouseCameraController for each view. double cameraHeading = masterDXViewportView == null ? 30 : _rnd.Next(360); targetPositionCamera = new TargetPositionCamera() { TargetPosition = new Point3D(0, 0, 0), Heading = cameraHeading, Attitude = -20, ShowCameraLight = ShowCameraLightType.Never, // If we have a camera light then the light position will be defined (and changed) with changing the camera position in one view Distance = 1000, TargetViewport3D = viewport3D }; mouseCameraController = new MouseCameraController() { TargetCamera = targetPositionCamera, RotateCameraConditions = MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, MoveCameraConditions = MouseCameraController.MouseAndKeyboardConditions.ControlKey | MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed }; return(createDXViewportView); }
// This method can be used to change the depth bias value after the Visual3D (line visual or WireframeVisual3D) has already been rendered by DXEngine (or at least the DXEngine has already initialized the 3D SceneNodes). // To set initial line depth bias value, it is much easier to use the the following (see also the CreateScene method above): // _multiLineVisual3D.SetDXAttribute(DXAttributeType.LineDepthBias, depthBias); public static void SetDepthBias(DXViewportView parentDXViewportView, BaseVisual3D lineVisual3D, double depthBiasValue) { var lineSceneNode = parentDXViewportView.GetSceneNodeForWpfObject(lineVisual3D); if (lineSceneNode == null) { return; } // First check if we got WpfWireframeVisual3DNode that is created from WireframeVisual3D // This is handled differently then LineVisual3D objects because WpfWireframeVisual3DNode defines the DepthBias property var wpfWireframeVisual3DNode = lineSceneNode as WpfWireframeVisual3DNode; if (wpfWireframeVisual3DNode != null) { wpfWireframeVisual3DNode.DepthBias = (float)depthBiasValue; return; } // Handle other 3D lines Visual3D objects: // To change the DepthBias we need to get to the used LineMaterial // LineMaterial is used on the ScreenSpaceLineNode (in the DXEngine's scene nodes hierarchy). // Currently the MultiLineVisual3D is converted into WpfModelVisual3DNode with one ScreenSpaceLineNode set as child. // But this might be optimized in the future so that WpfModelVisual3DNode would be converted directly into ScreenSpaceLineNode. // Thefore here we check both options: var screenSpaceLineNode = lineSceneNode as ScreenSpaceLineNode; if (screenSpaceLineNode == null && lineSceneNode.ChildNodesCount == 1) { screenSpaceLineNode = lineSceneNode.ChildNodes[0] as ScreenSpaceLineNode; } if (screenSpaceLineNode != null) { // Get line material // The LineMaterial is of type ILineMaterial that does not provide setters for properties // Therefore we need to cast that into the actual LineMaterial object var lineMaterial = screenSpaceLineNode.LineMaterial as LineMaterial; if (lineMaterial != null) { lineMaterial.DepthBias = (float)depthBiasValue; // Finally we can set DepthBias // When we change properties on the DXEngine objects, we need to manually notify the DXEngine about the changes // We do that with NotifySceneNodeChange method screenSpaceLineNode.NotifySceneNodeChange(SceneNode.SceneNodeDirtyFlags.MaterialChanged); } } }
private void ShowGraphicsProfile(GraphicsProfile graphicsProfile, DXViewportView dxViewportView) { if (dxViewportView == null) { GraphicsProfileTypeTextBlock.Text = "Selected graphics profile:"; UpdateUsedGraphicsProfileDescription(graphicsProfile, null); } else { GraphicsProfileTypeTextBlock.Text = "Used graphics profile:"; UpdateUsedGraphicsProfileDescription(graphicsProfile, dxViewportView); } }
public SceneView3D(DXDevice dxDevice) { InitializeComponent(); MainViewport = new Viewport3D(); MainViewport.IsHitTestVisible = false; MainDXViewportView = new DXViewportView(dxDevice, MainViewport); MainDXViewportView.BackgroundColor = Colors.Transparent; // Workaround for using one DXDevice with multiple DXScenes // We need to reset LastUsedFrameNumber stored in each effect // This ensures that the effect will be correctly initialized for each DXScene. // This will not be needed in the next version of DXEngine. MainDXViewportView.SceneRendered += delegate(object sender, EventArgs args) { if (MainDXViewportView.DXScene == null) // WPF 3D rendering is used { return; } var allEffects = MainDXViewportView.DXScene.DXDevice.EffectsManager.Effects; var effectsCount = allEffects.Count; for (var i = 0; i < effectsCount; i++) { allEffects[i].ResetLastUsedFrameNumber(); } }; WireframeVisual = new WireframeVisual3D() { WireframeType = WireframeVisual3D.WireframeTypes.OriginalSolidModel, LineColor = Colors.Black, LineThickness = 2, SolidModelColor = Colors.White }; MainViewport.Children.Add(WireframeVisual); ViewportBorder.Child = MainDXViewportView; SetupViews(); this.Loaded += delegate(object sender, RoutedEventArgs args) { UpdateViewType(); }; }
public DXEventManager3DWrapper(DXViewportView dxViewportView) : base(dxViewportView.Viewport3D) { if (dxViewportView == null) { throw new ArgumentNullException(nameof(dxViewportView)); } _dxViewportView = dxViewportView; this.CustomEventsSourceElement = dxViewportView; EnsureRayMeshGeometry3DHitTestResultConstructor(); }
private void DiagnosticsButton_OnClick(object sender, RoutedEventArgs e) { if (_lastShownDXViewportView == null || _lastShownDXViewportView.IsDisposed) { _lastShownDXViewportView = FindDXViewportView(ContentFrame.Content); if (_lastShownDXViewportView == null) { return; } } OpenDiagnosticsWindow(); }
private void Dispose() { if (_disposables != null) { _disposables.Dispose(); _disposables = null; } if (_mainDXViewportView != null) { _mainDXViewportView.Dispose(); _mainDXViewportView = null; } }
public RenderToBitmap() { InitializeComponent(); SetupDXEngine(); SetupContent(); this.Unloaded += delegate(object sender, RoutedEventArgs args) { if (_dxViewportView != null) { _dxViewportView.Dispose(); _dxViewportView = null; } }; }
private void Dispose() { DisposeOculusRiftVirtualRealityProvider(); if (_dxViewportView != null) { _dxViewportView.Dispose(); _dxViewportView = null; } if (_dxDevice != null) { _dxDevice.Dispose(); _dxDevice = null; } }
private void SetupDXEngine() { _dxViewportView = new DXViewportView(); // To use render to bitmap on a server, it is possible to use software rendering with the following line: //_dxViewportView.GraphicsProfiles = new GraphicsProfile[] { GraphicsProfile.HighQualitySoftwareRendering }; // Because the DXViewportView is not shown in the UI, we need to manually sets its size (without this the current version will not be initialized correctly - this will be improved in the future) _dxViewportView.Width = 128; _dxViewportView.Height = 128; // By default the BackgroundColor is set to transparent. // We set that to white so that the saved bitmap has a white background. _dxViewportView.BackgroundColor = Colors.White; _viewport3D = new Viewport3D(); _camera = new TargetPositionCamera() { //Heading = HeadingSlider.Value, Attitude = -15, Distance = 300, TargetPosition = new Point3D(0, 10, 0), ShowCameraLight = ShowCameraLightType.Always, TargetViewport3D = _viewport3D }; UpdateCamera(); _dxViewportView.Viewport3D = _viewport3D; // Initialize the scene with creating DirectX device and required resources try { _dxViewportView.InitializeScene(); } catch (Exception ex) { MessageBox.Show("Error initializing DXEngine:\r\n" + ex.Message); RenderButton.IsEnabled = false; } _isFirstRender = true; }
public void SubscribeDXViewportView(DXViewportView dxViewportView) { if (dxViewportView == null) { DisableDiagnosticsButton(); CloseDiagnosticsWindow(); return; } // Apply user settings // First set the GraphicsProfiles that should be used by DXEngine // If the GraphicsProfiles were not explicitly set in the loaded sample, set the GraphicsProfiles to settings defined by user // The GraphicsProfiles are stored by DXEngineSettings - stores GraphicsProfiles based on user choice or by recommended graphic profile if (ReferenceEquals(dxViewportView.GraphicsProfiles, DXView.DefaultGraphicsProfiles)) { dxViewportView.GraphicsProfiles = DXEngineSettings.Current.GraphicsProfiles; } // If UseDirectXOverlay is set to true, then force DirectXOverlay for all DXView controls (this can be used to enable graphical debugging) if (DXEngineSettings.Current.UseDirectXOverlay) { dxViewportView.PresentationType = DXView.PresentationTypes.DirectXOverlay; } // Subscribe events that will save any rejected GraphicsProfile and the used GraphicsProfile dxViewportView.GraphicsProfileRejected += OnGraphicsProfileRejected; dxViewportView.DXSceneInitialized += OnDXSceneInitialized; dxViewportView.Unloaded += OnDXViewportViewUnloaded; _rejectedGraphicProfilesReasons = null; _lastShownDXViewportView = dxViewportView; // We are now showing "Used graphics profile:" instead of "Selected graphics profile:" GraphicsProfileTypeTextBlock.Text = "Used graphics profile:"; // When we have a DXViewportView we can enable diagnostics button EnableDiagnosticsButton(); if (_diagnosticsWindow != null) { _diagnosticsWindow.DXView = dxViewportView; } }
private void SetSpecialRenderingType(DXViewportView dxViewportView, RenderingTypes renderingType) { if (dxViewportView.DXScene.DefaultRenderObjectsRenderingStep == null) { return; // Not yet initialized } // First reset any previous customizations dxViewportView.DXScene.DefaultRenderObjectsRenderingStep.OverrideEffect = null; dxViewportView.DXScene.DefaultRenderObjectsRenderingStep.FilterObjectsFunction = null; dxViewportView.DXScene.DefaultRenderObjectsRenderingStep.FilterRenderingQueuesFunction = null; if (renderingType == RenderingTypes.Wireframe) { // Use ModelColorLineEffect to render the 3D objects as wireframe (model colors define the color of the lines). // Note that instanced objects and some other advanced objects are not rendered. if (_modelColorLineEffect == null) { _modelColorLineEffect = _masterDXViewportView.DXScene.DXDevice.EffectsManager.GetEffect <ModelColorLineEffect>(); _modelColorLineEffect.LineThickness = 1; } dxViewportView.DXScene.DefaultRenderObjectsRenderingStep.OverrideEffect = _modelColorLineEffect; } else if (renderingType == RenderingTypes.FilterByObjects) { dxViewportView.DXScene.DefaultRenderObjectsRenderingStep.FilterObjectsFunction = delegate(RenderablePrimitiveBase renderablePrimitive) { var originalSceneNode = renderablePrimitive.OriginalObject as SceneNode; if (originalSceneNode != null) { return(originalSceneNode.Name.StartsWith("Sphere") || originalSceneNode.Name.StartsWith("Cylinder")); } return(false); }; } else if (renderingType == RenderingTypes.FilerByRenderingQueue) { dxViewportView.DXScene.DefaultRenderObjectsRenderingStep.FilterRenderingQueuesFunction = renderingQueue => renderingQueue.Name == "CustomRenderingQueue"; } dxViewportView.DXScene.NotifyChange(DXScene.ChangeNotifications.RenderingStepsChanged); }
private void SetupDXEngine() { _dxViewportView = new DXViewportView(); // For this sample we force software rendering (for example to be used on server or other computer without graphics card) if (ForceSoftwareRendering) { _dxViewportView.GraphicsProfiles = new GraphicsProfile[] { GraphicsProfile.HighQualitySoftwareRendering } } ; // Because the DXViewportView is not shown in the UI, we need to manually sets its size (without this the current version will not be initialized correctly - this will be improved in the future) _dxViewportView.Width = 128; _dxViewportView.Height = 128; _viewport3D = new Viewport3D(); _camera = new TargetPositionCamera() { //Heading = HeadingSlider.Value, Attitude = -20, Distance = 200, ShowCameraLight = ShowCameraLightType.Always, TargetViewport3D = _viewport3D }; UpdateCamera(); _dxViewportView.Viewport3D = _viewport3D; // Initialize the scene with creating DirectX device and required resources try { _dxViewportView.InitializeScene(); } catch (Exception ex) { MessageBox.Show("Error initializing DXEngine:\r\n" + ex.Message); RenderButton.IsEnabled = false; } _isFirstRender = true; }
private void OnUnloaded(object sender, RoutedEventArgs e) { if (_modelColorLineEffect != null) { _modelColorLineEffect.Dispose(); _modelColorLineEffect = null; } // Dispose DXViewportViews in the opposite order (so first child DXViewportView and lastly _masterDXViewportView) for (int i = _dxViewportViews.Count - 1; i >= 0; i--) { _dxViewportViews[i].Dispose(); } _dxViewportViews.Clear(); _masterDXViewportView = null; }
// Searches the logical controls tree and returns the first instance of DXViewportView if found private DXViewportView FindDXViewportView(object element) { DXViewportView foundDViewportView = element as DXViewportView; if (foundDViewportView != null) { return(foundDViewportView); } if (element is ContentControl) { // Check the element's Content foundDViewportView = FindDXViewportView(((ContentControl)element).Content); } else if (element is Decorator) // for example Border { // Check the element's Child foundDViewportView = FindDXViewportView(((Decorator)element).Child); } else if (element is Page) { // Page is not ContentControl so handle it specially (note: Window is ContentControl) foundDViewportView = FindDXViewportView(((Page)element).Content); } else if (element is Panel) { Panel panel = (Panel)element; // Check each child of a Panel foreach (UIElement oneChild in panel.Children) { foundDViewportView = FindDXViewportView(oneChild); if (foundDViewportView != null) { break; } } } return(foundDViewportView); }
// This must be called on the same thread as the objects were created on protected virtual void Dispose(bool disposing) { if (dxViewportView != null) { dxViewportView.Dispose(); dxViewportView = null; } if (dxScene != null) { dxScene.Dispose(); dxScene = null; } if (_dxDevice != null) { _dxDevice.Dispose(); _dxDevice = null; } wpfViewport3D = null; }
public RenderToBitmap() { InitializeComponent(); ConvertToNonPremultipliedAlphaInfoControl.InfoText = @"Ab3d.DXEngine and internally WPF are using pre-multiplied alpha textures. This means that color values (red, green, blue) are multiplied by alpha value. See internet for reasons why this is better. When rendering bitmap that is will be shown in a WPF application, then it is recommended to preserve the pre-multiplied alpha. When rendering bitmap that will be saved to png file and when there are transparent pixels in the texture, then it is better to convert the rendered image into non pre-multiplied bitmap because png files do not support pre-multiplied alpha. To test the difference when saving to png, uncomment the code in the SetupContent method."; SetupDXEngine(); SetupContent(); this.Unloaded += delegate(object sender, RoutedEventArgs args) { if (_dxViewportView != null) { _dxViewportView.Dispose(); _dxViewportView = null; } }; }
private void AddNewDXViewportView(Grid parentGrid, int rowIndex, int columnIndex, double sphereRadius, double depthBias, bool createDXEngine, string title, out Border createdBorder, out Viewport3D createdViewport3D, out DXViewportView createdDXViewportView, out TargetPositionCamera createdTargetPositionCamera) { createdBorder = new Border() { BorderBrush = Brushes.Black, BorderThickness = new Thickness(1, 1, 1, 1), SnapsToDevicePixels = true }; createdViewport3D = new Viewport3D(); createdTargetPositionCamera = new TargetPositionCamera() { Heading = 30, Attitude = -20, Distance = 200, TargetPosition = new Point3D(0, 0, 0), ShowCameraLight = ShowCameraLightType.Always, TargetViewport3D = createdViewport3D }; bool showSphere = ShowSphereRadioButton.IsChecked ?? false; CreateScene(createdViewport3D, sphereRadius, depthBias, createdTargetPositionCamera, showSphere); if (createDXEngine) { createdDXViewportView = new DXViewportView(createdViewport3D); createdDXViewportView.SnapsToDevicePixels = true; createdBorder.Child = createdDXViewportView; } else { createdBorder.Child = createdViewport3D; createdDXViewportView = null; } Grid.SetRow(createdBorder, rowIndex); Grid.SetColumn(createdBorder, columnIndex); parentGrid.Children.Add(createdBorder); parentGrid.Children.Add(createdTargetPositionCamera); if (!string.IsNullOrEmpty(title)) { var textBlock = new TextBlock() { Text = title, Foreground = Brushes.Black, FontSize = 12, Margin = new Thickness(10, 5, 5, 5), HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top }; Grid.SetRow(textBlock, rowIndex); Grid.SetColumn(textBlock, columnIndex); parentGrid.Children.Add(textBlock); } }
private void CreateDXViewportView(bool isDirectXOverlay) { _mainViewport3D = new Viewport3D(); _lightsGroup = new Model3DGroup(); _mainViewport3D.Children.Add(_lightsGroup.CreateModelVisual3D()); UpdateLightingMode(); _camera1 = new TargetPositionCamera() { TargetPosition = new Point3D(0, 0, 0), Heading = 30, Attitude = -10, Distance = 1500, ShowCameraLight = ShowCameraLightType.Never, TargetViewport3D = _mainViewport3D }; _mouseCameraController = new MouseCameraController() { RotateCameraConditions = MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, MoveCameraConditions = MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed | MouseCameraController.MouseAndKeyboardConditions.ControlKey, EventsSourceElement = ViewportBorder, TargetCamera = _camera1 }; RootGrid.Children.Add(_camera1); RootGrid.Children.Add(_mouseCameraController); _mainDXViewportView = new DXViewportView(_mainViewport3D) { BackgroundColor = Colors.White, PresentationType = isDirectXOverlay ? DXView.PresentationTypes.DirectXOverlay : DXView.PresentationTypes.DirectXImage }; var maxBackgroundThreadsCount = (int)ThreadsCountSlider.Value; _mainDXViewportView.DXSceneDeviceCreated += delegate(object sender, EventArgs args) { if (_mainDXViewportView.DXScene != null) { _mainDXViewportView.DXScene.MaxBackgroundThreadsCount = maxBackgroundThreadsCount; } }; _mainDXViewportView.SceneRendered += MainDxViewportViewOnSceneRendered; ViewportBorder.Child = _mainDXViewportView; _camera1.StartRotation(40, 0); // Notify MainWindow about a new MainDXViewportView - so we can open DiagnosticsWindow if (_parentWindow != null) { ((MainWindow)_parentWindow).UnsubscribeLastShownDXViewportView(); ((MainWindow)_parentWindow).SubscribeDXViewportView(_mainDXViewportView); ((MainWindow)_parentWindow).MaxBackgroundThreadsCount = maxBackgroundThreadsCount; // prevent setting MaxBackgroundThreadsCount from the setting dialog } }
private void CreateInitialScene() { for (int i = 0; i < ColumnsCount; i++) { ViewsGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }); } for (int i = 0; i < RowsCount; i++) { ViewsGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) }); } if (ColumnsCount > 1) { for (int i = 0; i < ColumnsCount; i++) { var gridSplitter = new GridSplitter() { HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Stretch, Width = 2, Background = Brushes.Gray, }; Grid.SetColumn(gridSplitter, i); if (RowsCount > 1) { Grid.SetRow(gridSplitter, 0); Grid.SetRowSpan(gridSplitter, RowsCount); } ViewsGrid.Children.Add(gridSplitter); } } if (RowsCount > 1) { for (int i = 0; i < RowsCount; i++) { _horizontalGridSplitter = new GridSplitter() { HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Bottom, Height = 2, Background = Brushes.Gray, }; Grid.SetRow(_horizontalGridSplitter, i); if (ColumnsCount > 1) { Grid.SetColumn(_horizontalGridSplitter, 0); Grid.SetColumnSpan(_horizontalGridSplitter, ColumnsCount); } ViewsGrid.Children.Add(_horizontalGridSplitter); } } _dxViewportViews = new List <DXView>(); // Create master DXViewportView that will define the 3D scene _masterDXViewportView = AddNewDXViewportView(null, 0, 0, addToRootGrid: true, renderingType: RenderingTypes.Standard, addDrawSelectionComboBox: false); _masterDXViewportView.Name = "MainDXViewportView"; _masterDXViewportView.BackgroundColor = Colors.White; _masterDXViewportView.DXSceneDeviceCreated += OnMasterDXSceneCreated; // Create 3D scene AddHouseWithTreesModel(); var lightingRigVisual3D = new Ab3d.Visuals.LightingRigVisual3D(); _masterDXViewportView.Viewport3D.Children.Add(lightingRigVisual3D); // Add child DXViewportViews int usedColumnsCount = ColumnsCount > 1 ? ColumnsCount : 1; int usedRowsCount = RowsCount > 1 ? RowsCount : 1; int index = 1; // This is used to create different RenderingTypes; start with wireframe for (int i = 0; i < usedRowsCount; i++) { for (int j = 0; j < usedColumnsCount; j++) { if (i == 0 && j == 0) { continue; // We have already created the main DXViewportView } // Force wireframe rendering for DXViewportView defined in the first row (except the masterDXViewportView) var renderingType = (RenderingTypes)(index % 4); var dxViewportView = AddNewDXViewportView(_masterDXViewportView, i, j, renderingType); dxViewportView.Name = $"DXViewportView_{i + 1}_{j + 1}"; index++; } } }
public Grid CreateScene() { var rootGrid = new Grid(); var textBlock = new TextBlock() { Text = _title, FontSize = 16, FontWeight = FontWeights.Bold, Margin = new Thickness(10, 5, 10, 10), VerticalAlignment = VerticalAlignment.Top, HorizontalAlignment = HorizontalAlignment.Left }; _reportTextBlock = new TextBlock() { Text = "", FontSize = 10, Margin = new Thickness(10, 30, 10, 10), VerticalAlignment = VerticalAlignment.Top, HorizontalAlignment = HorizontalAlignment.Left, TextWrapping = TextWrapping.Wrap }; var rootBorder = new Border() { Background = Brushes.Transparent, BorderBrush = Brushes.Black, BorderThickness = new Thickness(2, 2, 2, 2), Margin = new Thickness(1, 2, 1, 2) }; MainViewport3D = new Viewport3D(); var rootModel3DGroup = Create3DScene(new Point3D(0, -300, 0), XCount, YCount, ZCount, 30); MainCamera = new TargetPositionCamera() { TargetViewport3D = MainViewport3D, TargetPosition = new Point3D(0, 0, 0), Heading = 130, // start from back where sorting errors are most obvious Attitude = -20, Distance = 500, ShowCameraLight = ShowCameraLightType.Always }; MainCamera.CameraChanged += OnMainCameraChanged; var mouseCameraController = new MouseCameraController() { TargetCamera = MainCamera, EventsSourceElement = rootBorder, RotateCameraConditions = MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, MoveCameraConditions = MouseCameraController.MouseAndKeyboardConditions.Disabled // disable mouse move }; if (_useDXEngine) { _dxViewportView = new DXViewportView(); _dxViewportView.Viewport3D = MainViewport3D; rootBorder.Child = _dxViewportView; _dxViewportView.DXSceneDeviceCreated += delegate(object sender, EventArgs e) { // Always disable transparency sorting on start // If _useDXEngineSorting the IsTransparencySortingEnabled will be set to true after // the first rendering statistics will be collected (see CollectStatistics method for more info) _dxViewportView.DXScene.IsTransparencySortingEnabled = false; }; _dxViewportView.SceneRendered += delegate(object sender, EventArgs e) { CollectStatistics(); }; // To manually change the order of objects after they have been sorted use SortingCompleted event: //_dxViewportView.DXScene.TransparentRenderingQueue.SortingCompleted += delegate(object sender, RenderingQueueSortingCompletedEventArgs e) //{ // // Here it is possible to change the order of item with changing the indexes in the e.SortedIndexes array. // // IMPORTANT: // // To get objects count use e.RenderablePrimitives.Count and not e.SortedIndexes.Length as it may be too big! //}; Ab3d.DirectX.DXDiagnostics.IsCollectingStatistics = true; } else { rootBorder.Child = MainViewport3D; } if (_useTransparencySorter) { _transparencySorter = new TransparencySorter(rootModel3DGroup, MainCamera); } MainCamera.Refresh(); rootGrid.Children.Add(rootBorder); rootGrid.Children.Add(textBlock); rootGrid.Children.Add(_reportTextBlock); return(rootGrid); }
public void UpdateUsedGraphicsProfileDescription(GraphicsProfile usedGraphicsProfile, DXViewportView dxViewportView) { string graphicsInfoText; string graphicsProfileName = usedGraphicsProfile.DisplayName ?? usedGraphicsProfile.Name; if (usedGraphicsProfile.DriverType == GraphicsProfile.DriverTypes.Wpf3D || dxViewportView == null || dxViewportView.DXScene == null) { // Show only profile name for WPF 3D or when we do not have dxViewportView.DXScene graphicsInfoText = graphicsProfileName + Environment.NewLine; } else { string adapterInfo = usedGraphicsProfile.DefaultAdapterDescription ?? dxViewportView.DXScene.DXDevice.Adapter.Description1.Description; string samplingDescription; int multiSamplingCount, superSamplingCount; if (_lastShownDXViewportView != null && _lastShownDXViewportView.DXScene != null) { multiSamplingCount = _lastShownDXViewportView.DXScene.UsedMultisamplingDescription.Count; superSamplingCount = _lastShownDXViewportView.DXScene.SupersamplingCount; } else { multiSamplingCount = 1; superSamplingCount = 1; } if (multiSamplingCount <= 1 && superSamplingCount <= 1) { samplingDescription = ""; } else if (multiSamplingCount > 1 && superSamplingCount <= 1) { samplingDescription = string.Format(" ({0}xMSAA)", multiSamplingCount); } else if (multiSamplingCount <= 1 && superSamplingCount > 1) { samplingDescription = string.Format(" ({0}xSSAA)", superSamplingCount); } else { samplingDescription = string.Format(" ({0}xMSAA {1}xSSAA)", multiSamplingCount, superSamplingCount); } graphicsInfoText = graphicsProfileName + " on \r\n" + adapterInfo + samplingDescription; } SelectedGraphicInfoTextBlock.Text = graphicsInfoText; }
private void InitializeOvrAndDirectX() { if (UseOculusRift) { // Initializing Oculus VR is very simple when using OculusWrapVirtualRealityProvider // First we create an instance of OculusWrapVirtualRealityProvider _oculusRiftVirtualRealityProvider = new OculusWrapVirtualRealityProvider(_ovr, multisamplingCount: 4); try { // Then we initialize Oculus OVR and create a new DXDevice that uses the same adapter (graphic card) as Oculus Rift _dxDevice = _oculusRiftVirtualRealityProvider.InitializeOvrAndDXDevice(requestedOculusSdkMinorVersion: 17); } catch (Exception ex) { MessageBox.Show("Failed to initialize the Oculus runtime library.\r\nError: " + ex.Message, "Oculus error", MessageBoxButton.OK, MessageBoxImage.Error); return; } string ovrVersionString = _ovr.GetVersionString(); _originalWindowTitle = string.Format("DXEngine OculusWrap Sample (OVR v{0})", ovrVersionString); this.Title = _originalWindowTitle; // Reset tracking origin at startup _ovr.RecenterTrackingOrigin(_oculusRiftVirtualRealityProvider.SessionPtr); } else { // Create DXDevice that will be used to create DXViewportView var dxDeviceConfiguration = new DXDeviceConfiguration(); dxDeviceConfiguration.DriverType = DriverType.Hardware; dxDeviceConfiguration.SupportedFeatureLevels = new FeatureLevel[] { FeatureLevel.Level_11_0 }; // Oculus requires at least feature level 11.0 _dxDevice = new DXDevice(dxDeviceConfiguration); _dxDevice.InitializeDevice(); _originalWindowTitle = this.Title; } // Create WPF's Viewport3D _viewport3D = new Viewport3D(); // Create DXViewportView - a control that will enable DirectX 11 rendering of standard WPF 3D content defined in Viewport3D. // We use a specified DXDevice that was created by the _oculusRiftVirtualRealityProvider.InitializeOvrAndDXDevice (this way the same adapter is used by Oculus and DXEngine). _dxViewportView = new DXViewportView(_dxDevice, _viewport3D); _dxViewportView.BackgroundColor = Colors.Aqua; // Currently DXEngine support showing Oculus mirror texture only with DirectXOverlay presentation type (not with DirectXImage) _dxViewportView.PresentationType = DXView.PresentationTypes.DirectXOverlay; if (UseOculusRift) { // The _dxViewportView will show Oculus mirrow window. // The mirror window can be any size, for this sample we use 1/2 the HMD resolution. _dxViewportView.Width = _oculusRiftVirtualRealityProvider.HmdDescription.Resolution.Width / 2.0; _dxViewportView.Height = _oculusRiftVirtualRealityProvider.HmdDescription.Resolution.Height / 2.0; } // When the DXViewportView is initialized, we set the _oculusRiftVirtualRealityProvider to the DXScene object _dxViewportView.DXSceneInitialized += delegate(object sender, EventArgs args) { if (_dxViewportView.UsedGraphicsProfile.DriverType != GraphicsProfile.DriverTypes.Wpf3D && _dxViewportView.DXScene != null && _oculusRiftVirtualRealityProvider != null) { // Initialize Virtual reality rendering _dxViewportView.DXScene.InitializeVirtualRealityRendering(_oculusRiftVirtualRealityProvider); // Initialized shadow rendering (see Ab3d.DXEngine.Wpf.Samples project - DXEngine/ShadowRenderingSample for more info _varianceShadowRenderingProvider = new VarianceShadowRenderingProvider() { ShadowMapSize = 1024, ShadowDepthBluringSize = 2, ShadowTreshold = 0.2f }; _dxViewportView.DXScene.InitializeShadowRendering(_varianceShadowRenderingProvider); } }; // Enable collecting rendering statistics (see _dxViewportView.DXScene.Statistics class) DXDiagnostics.IsCollectingStatistics = true; // Subscribe to SceneRendered to collect FPS statistics _dxViewportView.SceneRendered += DXViewportViewOnSceneRendered; // Add _dxViewportView to the RootGrid // Before that we resize the window to be big enough to show the mirrored texture this.Width = _dxViewportView.Width + 30; this.Height = _dxViewportView.Height + 50; RootGrid.Children.Add(_dxViewportView); // Create FirstPersonCamera _camera = new FirstPersonCamera() { TargetViewport3D = _viewport3D, Position = new Point3D(0, 1, 4), Heading = 0, Attitude = 0, ShowCameraLight = ShowCameraLightType.Never }; RootGrid.Children.Add(_camera); // Initialize XBOX controller that will control the FirstPersonCamera _xInputCameraController = new XInputCameraController(); _xInputCameraController.TargetCamera = _camera; _xInputCameraController.MovementSpeed = 0.02; _xInputCameraController.MoveVerticallyWithDPadButtons = true; // We handle the rotation by ourself to prevent rotating the camera up and down - this is done only by HMD _xInputCameraController.RightThumbChanged += delegate(object sender, XInputControllerThumbChangedEventArgs e) { // Apply only horizontal rotation _camera.Heading += e.NormalizedX * _xInputCameraController.RotationSpeed; // Mark the event as handled e.IsHandled = true; }; _xInputCameraController.StartCheckingController(); // Now we can create our sample 3D scene CreateSceneObjects(); // Add lights var lightsVisual3D = new ModelVisual3D(); var lightsGroup = new Model3DGroup(); var directionalLight = new DirectionalLight(Colors.White, new Vector3D(0.5, -0.3, -0.3)); directionalLight.SetDXAttribute(DXAttributeType.IsCastingShadow, true); // Set this light to cast shadow lightsGroup.Children.Add(directionalLight); var ambientLight = new AmbientLight(System.Windows.Media.Color.FromRgb(30, 30, 30)); lightsGroup.Children.Add(ambientLight); lightsVisual3D.Content = lightsGroup; _viewport3D.Children.Add(lightsVisual3D); // Start rendering if (RenderAt90Fps) { // WPF do not support rendering at more the 60 FPS. // But with a trick where a rendering loop is created in a background thread, it is possible to achieve more than 60 FPS. // In case of sumbiting frames to Oculus Rift, the ovr.SubmitFrame method will limit rendering to 90 FPS. // // NOTE: // When using DXEngine, it is also possible to render the scene in a background thread. // This requires that the 3D scene is also created in the background thread and that the events and other messages are // passed between UI and background thread in a thread safe way. This is too complicated for this simple sample project. // To see one possible implementation of background rendering, see the BackgroundRenderingSample in the Ab3d.DXEngine.Wpf.Samples project. var backgroundWorker = new BackgroundWorker(); backgroundWorker.DoWork += (object sender, DoWorkEventArgs args) => { // Create an action that will be called by Dispatcher var refreshDXEngineAction = new Action(() => { UpdateScene(); // Render DXEngine's 3D scene again if (_dxViewportView != null) { _dxViewportView.Refresh(); } }); while (_dxViewportView != null && !_dxViewportView.IsDisposed) // Render until window is closed { if (_oculusRiftVirtualRealityProvider != null && _oculusRiftVirtualRealityProvider.LastSessionStatus.ShouldQuit) // Stop rendering - this will call RunWorkerCompleted where we can quit the application { break; } // Sleep for 1 ms to allow WPF tasks to complete (for example handling XBOX controller events) System.Threading.Thread.Sleep(1); // Call Refresh to render the DXEngine's scene // This is a synchronous call and will wait until the scene is rendered. // Because Oculus is limited to 90 fps, the call to ovr.SubmitFrame will limit rendering to 90 FPS. Dispatcher.Invoke(refreshDXEngineAction); } }; backgroundWorker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs args) { if (_oculusRiftVirtualRealityProvider != null && _oculusRiftVirtualRealityProvider.LastSessionStatus.ShouldQuit) { this.Close(); // Exit the application } }; backgroundWorker.RunWorkerAsync(); } else { // Subscribe to WPF rendering event (called approximately 60 times per second) CompositionTarget.Rendering += CompositionTargetOnRendering; } }
private DXViewportView AddDXViewport3DGrid(string title, string graphicsProfileName, int multisamplingCount, int supersamplingCount, int rowIndex, int columnIndex) { var viewport3D = new Viewport3D(); var sceneModelVisual3D = CreateScene(); viewport3D.Children.Add(sceneModelVisual3D); var dxViewportView = new DXViewportView(viewport3D); dxViewportView.BackgroundColor = Colors.White; dxViewportView.UseLayoutRounding = true; dxViewportView.SnapsToDevicePixels = true; // Set GraphicsProfile: var graphicsProfile = new GraphicsProfile(string.Format("{0}xMSAA_{1}xSSAA_HardwareRendering", multisamplingCount, supersamplingCount), GraphicsProfile.DriverTypes.DirectXHardware, ShaderQuality.High, preferedMultisampleCount: multisamplingCount, supersamplingCount: supersamplingCount, textureFiltering: TextureFilteringTypes.Anisotropic_x4); dxViewportView.GraphicsProfiles = new GraphicsProfile[] { graphicsProfile, GraphicsProfile.Wpf3D }; // Add WPF 3D as fallback var border = new Border() { Background = Brushes.White, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(1, 1, 1, 1), Margin = new Thickness(1, 1, 2, 2), UseLayoutRounding = true, SnapsToDevicePixels = true }; border.Child = dxViewportView; var targetPositionCamera = new TargetPositionCamera() { TargetPosition = new Point3D(0, 0, 0), Heading = 0, Attitude = 0, ShowCameraLight = ShowCameraLightType.Always, CameraType = BaseCamera.CameraTypes.OrthographicCamera, CameraWidth = 800, Distance = 800, TargetViewport3D = viewport3D }; dxViewportView.DXRenderSizeChanged += delegate(object sender, DXViewSizeChangedEventArgs args) { targetPositionCamera.CameraWidth = dxViewportView.DXRenderSize.Width; }; var mouseCameraController = new MouseCameraController() { TargetCamera = targetPositionCamera, EventsSourceElement = border, RotateCameraConditions = MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, MoveCameraConditions = MouseCameraController.MouseAndKeyboardConditions.ControlKey | MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, }; var titlesPanel = new StackPanel() { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top, Margin = new Thickness(10, 5, 10, 0) }; if (title != null) { var textBlock = new TextBlock() { Text = title, FontSize = 18, FontWeight = FontWeights.Bold, TextWrapping = TextWrapping.Wrap, Foreground = new SolidColorBrush(Color.FromRgb(32, 32, 32)), }; titlesPanel.Children.Add(textBlock); } if (graphicsProfileName != null) { var textBlock = new TextBlock() { Text = "GraphicsProfile: " + graphicsProfileName, FontSize = 12, TextWrapping = TextWrapping.Wrap, VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(15, 0, 0, 0) }; titlesPanel.Children.Add(textBlock); } var viewRootGrid = new Grid(); viewRootGrid.Children.Add(border); viewRootGrid.Children.Add(titlesPanel); viewRootGrid.Children.Add(targetPositionCamera); viewRootGrid.Children.Add(mouseCameraController); Grid.SetColumn(viewRootGrid, columnIndex); Grid.SetRow(viewRootGrid, rowIndex); RootGrid.Children.Add(viewRootGrid); return(dxViewportView); }
/// <summary> /// CreateDXViewportView /// </summary> /// <param name="clientWindowWidth">clientWindowWidth</param> /// <param name="clientWindowHeight">clientWindowHeight</param> /// <param name="dpiScaleX">DPI scale: 1 means no scale (96 DPI)</param> /// <param name="dpiScaleY">DPI scale: 1 means no scale (96 DPI)</param> /// <param name="preferedMultisamplingCount">preferedMultisamplingCount</param> public void InitializeDXViewportView(int clientWindowWidth, int clientWindowHeight, double dpiScaleX, double dpiScaleY, int preferedMultisamplingCount) { // To render the 3D scene to the custom hWnd, we need to create the DXViewportView with a custom DXScene, // that was initialized with calling InitializeSwapChain mathod (with passed hWnd). // To create a custom DXScene we first need to create a DXDevice objects (wrapper around DirectX Device object) var dxDeviceConfiguration = new DXDeviceConfiguration(); dxDeviceConfiguration.DriverType = DriverType.Hardware; // We could also specify Software rendering here try { _dxDevice = new DXDevice(dxDeviceConfiguration); _dxDevice.InitializeDevice(); } catch (Exception ex) { MessageBox.Show("Cannot create required DirectX device.\r\n" + ex.Message); return; } if (_dxDevice.Device == null) { MessageBox.Show("Cannot create required DirectX device."); return; } // Now we can create the DXScene dxScene = new Ab3d.DirectX.DXScene(_dxDevice); // ensure we have a valid size; we will resize later to the correct size if (clientWindowWidth <= 0) { clientWindowWidth = 1; } if (clientWindowHeight <= 0) { clientWindowHeight = 1; } dxScene.InitializeSwapChain(_hWnd, (int)(clientWindowWidth * dpiScaleX), (int)(clientWindowHeight * dpiScaleY), preferedMultisamplingCount, (float)dpiScaleX, (float)dpiScaleY); wpfViewport3D = new Viewport3D(); dxViewportView = new DXViewportView(dxScene, wpfViewport3D); // Because _dxViewportView is not shown in the UI, the DXEngineShoop (DXEngine's diagnostics tool) cannot find it // To enable using DXEngineSnoop in such cases, we can set the Application's Property: Application.Current.Properties["DXView"] = new WeakReference(dxViewportView); OnDXViewportViewInitialized(); }
private void AddDXViewport3DGrid(string title, string subTitle, int multisamplingCount, int supersamplingCount, int rowIndex, int columnIndex) { var viewport3D = new Viewport3D(); var sceneModelVisual3D = CreateScene(); viewport3D.Children.Add(sceneModelVisual3D); var dxViewportView = new DXViewportView(viewport3D); // Set GraphicsProfile: var graphicsProfile = new GraphicsProfile(string.Format("{0}MSAA_{1}SSAA_HardwareRendering", multisamplingCount, supersamplingCount), GraphicsProfile.DriverTypes.DirectXHardware, ShaderQuality.High, preferedMultisampleCount: multisamplingCount, supersamplingCount: supersamplingCount, textureFiltering: TextureFilteringTypes.Anisotropic_x4); dxViewportView.GraphicsProfiles = new GraphicsProfile[] { graphicsProfile, GraphicsProfile.Wpf3D }; // Add WPF 3D as fallback var border = new Border() { Background = Brushes.Transparent, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(1, 1, 1, 1), Margin = new Thickness(1, 1, 3, 3), UseLayoutRounding = true, SnapsToDevicePixels = true }; border.Child = dxViewportView; var targetPositionCamera = new TargetPositionCamera() { TargetPosition = new Point3D(15, 50, 5), Heading = -17, Attitude = -25, ShowCameraLight = ShowCameraLightType.Always, Distance = 80, TargetViewport3D = viewport3D }; var mouseCameraController = new MouseCameraController() { TargetCamera = targetPositionCamera, EventsSourceElement = border, RotateCameraConditions = MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, MoveCameraConditions = MouseCameraController.MouseAndKeyboardConditions.ControlKey | MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, }; var titlesPanel = new StackPanel() { Orientation = Orientation.Vertical, HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top, Margin = new Thickness(10, 10, 10, 0) }; if (title != null) { var textBlock = new TextBlock() { Text = title, FontSize = 18, FontWeight = FontWeights.Bold, TextWrapping = TextWrapping.Wrap, Foreground = new SolidColorBrush(Color.FromRgb(32, 32, 32)), }; titlesPanel.Children.Add(textBlock); } if (subTitle != null) { var textBlock = new TextBlock() { Text = subTitle, FontSize = 14, TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 3, 0, 0) }; titlesPanel.Children.Add(textBlock); } var viewRootGrid = new Grid(); viewRootGrid.Children.Add(border); viewRootGrid.Children.Add(titlesPanel); viewRootGrid.Children.Add(targetPositionCamera); viewRootGrid.Children.Add(mouseCameraController); Grid.SetColumn(viewRootGrid, columnIndex); Grid.SetRow(viewRootGrid, rowIndex); RootGrid.Children.Add(viewRootGrid); }