コード例 #1
0
        //private void GenerateHeightMapObject(float[,] heightData, Color4[] positionColorsArray)
        private void GenerateHeightMapSceneNodes(MeshBase heightMapMesh, Ab3d.DirectX.Material dxMaterial)
        {
            var meshObjectNode = new Ab3d.DirectX.MeshObjectNode(heightMapMesh, dxMaterial);

            meshObjectNode.Name = "HeightMeshObjectNode";

            _disposables.Add(meshObjectNode);

            var sceneNodeVisual3D = new SceneNodeVisual3D(meshObjectNode);

            RootContentVisual3D.Children.Add(sceneNodeVisual3D);


            // If you also want to render back faces of the height map you need to create another MeshObjectNode and set its IsBackFaceMaterial to true.
            // You can reuse the mesh. But this still requires almost twice the GPU power.
            var backDiffuseMaterial = new DiffuseMaterial(Brushes.Gray);
            var backDXMaterial      = new Ab3d.DirectX.Materials.WpfMaterial(backDiffuseMaterial);

            meshObjectNode = new Ab3d.DirectX.MeshObjectNode(heightMapMesh, backDXMaterial);
            meshObjectNode.IsBackFaceMaterial = true;
            meshObjectNode.Name = "HeightBackMeshObjectNode";

            _disposables.Add(meshObjectNode);

            sceneNodeVisual3D = new SceneNodeVisual3D(meshObjectNode);
            RootContentVisual3D.Children.Add(sceneNodeVisual3D);
        }
コード例 #2
0
        private Ab3d.DirectX.Material GeneratePositionColorMaterial(Color4[] positionColorsArray, DXDevice dxDevice)
        {
            Ab3d.DirectX.Material dxMaterial;

            if (positionColorsArray != null)
            {
                dxMaterial = new Ab3d.DirectX.Materials.VertexColorMaterial()
                {
                    PositionColors      = positionColorsArray, // The PositionColors property is used to specify colors for each vertex
                    CreateDynamicBuffer = false,               // We will not update the colors frequently

                    // To show specular effect set the specular data here:
                    //SpecularPower = 16,
                    //SpecularColor = Color3.White,
                    //HasSpecularColor = true
                };
            }
            else
            {
                // Solid color material:
                var diffuseMaterial = new DiffuseMaterial(Brushes.Green);

                // Texture material:
                //var imageBrush = new ImageBrush();
                //imageBrush.ImageSource = new BitmapImage(new Uri("pack://application:,,,/Resources/GrassTexture.jpg"));
                //var diffuseMaterial = new DiffuseMaterial(imageBrush);

                dxMaterial = new Ab3d.DirectX.Materials.WpfMaterial(diffuseMaterial);
            }

            // If DXDevice is already initialized, then we can also initialize (create DirectX resources) for the SimpleMesh.
            // This will create the DirectX resources and send them to the GPU
            if (dxDevice != null)
            {
                dxMaterial.InitializeResources(dxDevice);
            }

            return(dxMaterial);
        }
コード例 #3
0
        private void AddSimpleMesh()
        {
            // To show _meshGeometry3D with using low level DXEngine object we will do the following:
            // 1) Create a array of PositionNormalTexture data - this will represent a managed vertex buffer array.
            // 2) Create a SimpleMesh<PositionNormalTexture> object that will create an unmanaged vertex buffer from managed vertex buffer.
            // 3) Create a MeshObjectNode (derived from SceneNode) from the SimpleMesh.
            // 4) Create a SceneNodeVisual3D that will allow us to add the MeshObjectNode to the Viewport3D children.


            // 1) Create a array of PositionNormalTexture data - this will represent a managed vertex buffer array.

            int positionsCount = _meshGeometry3D.Positions.Count;

            _vertexBufferArray = new PositionNormalTexture[positionsCount];
            FillVertexBuffer(_vertexBufferArray, _meshGeometry3D.Positions, _meshGeometry3D.Normals, _meshGeometry3D.TextureCoordinates);

            var indexBuffer = new int[_meshGeometry3D.TriangleIndices.Count];

            _meshGeometry3D.TriangleIndices.CopyTo(indexBuffer, 0);


            // 2) Create a SimpleMesh<PositionNormalTexture> object that will create an unmanaged vertex buffer from managed vertex buffer.

            bool createDynamicVertexBuffer = UseDynamicBufferCheckBox.IsChecked ?? false;

            _simpleMesh = new SimpleMesh <PositionNormalTexture>(_vertexBufferArray,
                                                                 indexBuffer,
                                                                 inputLayoutType: InputLayoutType.Position | InputLayoutType.Normal | InputLayoutType.TextureCoordinate,
                                                                 name: "SimpleMesh-from-PositionNormalTexture-array",
                                                                 createDynamicVertexBuffer: createDynamicVertexBuffer);

            // We can also manually specify the bounds of the mesh
            // If this is not done, then the SimpleMesh will go through all positions and calculate that.
            // But because the bounds are already calculated by MeshGeometry3D, we can just use that value (we only need to convert that to DXEngine's bounds).
            _simpleMesh.Bounds = _meshGeometry3D.Bounds.ToDXEngineBounds();

            _originalMeshSizeY = _simpleMesh.Bounds.BoundingBox.Maximum.Y - _simpleMesh.Bounds.BoundingBox.Minimum.Y;

            _disposables.Add(_simpleMesh);


            var diffuseMaterial = new DiffuseMaterial(Brushes.Silver);
            var dxMaterial      = new Ab3d.DirectX.Materials.WpfMaterial(diffuseMaterial);

            _disposables.Add(dxMaterial);


            // 3) Create a MeshObjectNode (derived from SceneNode) from the SimpleMesh.

            _meshObjectNode      = new Ab3d.DirectX.MeshObjectNode(_simpleMesh, dxMaterial);
            _meshObjectNode.Name = "MeshObjectNode-from-SimpleMesh";

            _disposables.Add(_meshObjectNode);


            // 4) Create a SceneNodeVisual3D that will allow us to add the MeshObjectNode to the Viewport3D children.

            var sceneNodeVisual3D = new SceneNodeVisual3D(_meshObjectNode);


            // Scale and translate the sceneNodeVisual3D and than add it to the scene
            AddVisual3D(sceneNodeVisual3D);
        }
        private void UpdateFogUsage()
        {
            if (MainDXViewportView.DXScene == null) // probably WPF 3D rendering is used
            {
                return;
            }


            // First make sure that we have the StandardEffect that is used by default
            if (_defaultStandardEffect == null)
            {
                _defaultStandardEffect = MainDXViewportView.DXScene.DXDevice.EffectsManager.GetStandardEffect();
            }


            // First reset the changes of previously changed SceneNodes
            if (_changedDXMaterial != null)
            {
                _changedDXMaterial.Effect = null;
                _changedDXMaterial        = null;
            }

            if (_yellowFogWpfMaterial != null)
            {
                // Replace _yellowFogWpfMaterial with default YellowMaterial
                var yellowMaterial = this.FindResource("YellowMaterial") as DiffuseMaterial;

                foreach (var baseModelVisual3D in MainViewport.Children.OfType <BaseModelVisual3D>())
                {
                    if (ReferenceEquals(baseModelVisual3D.Material, _yellowFogWpfMaterial))
                    {
                        baseModelVisual3D.Material = yellowMaterial;
                    }
                }

                _yellowFogWpfMaterial = null;
            }


            // NOTES:
            // We can use two ways to use custom FogEffect:
            //
            // 1) Set FogEffect as StandardEffect on EffectsManager.
            //    StandardEffect is used when DXEngine is rendering standard WPF materials (diffuse, specular, emissive).
            //    This means that if we change the StandardEffect, then all standard objects will be rendered with FogEffect.
            //    Other objects like 3D lines will still be rendered with their special effects.
            //
            // 2) Set FogEffect to the Effect property on the WpfMaterial object that is a DXEngine's material object created from WPF's material.
            //    When setting Effect property on DXEngine's material, the material will be rendered with the specified effect (instead of StandardEffect).


            // Additional notes:
            // 1) EffectsManager is created when the DXDevice is created.
            //    This means that you cannot access it in the constructor of this class.
            //    If you need to change the StandardEffect (or some other setting on DXDevice) before the first frame is rendered,
            //    you need to use DXSceneDeviceCreated or DXSceneInitialized event handler to do that (as in this case).


            Effect newStandardEffect;

            if (StandardEffectRadioButton.IsChecked ?? false)
            {
                newStandardEffect = _fogEffect;
            }
            else if (RootBoxRadioButton.IsChecked ?? false)
            {
                newStandardEffect = _defaultStandardEffect;

                // Get the DXEngine's material that is created from the WPF's Material used for BaseBoxVisual3D
                var dxMaterial = Ab3d.DirectX.Materials.WpfMaterial.GetUsedDXMaterial(BaseBoxVisual3D.Material, MainDXViewportView.DXScene.DXDevice);

                if (dxMaterial != null)
                {
                    // Now we can specify the exact effect that will be used to render dxMaterial (if this is not specified, then StandardEffect is used)
                    dxMaterial.Effect  = _fogEffect;
                    _changedDXMaterial = dxMaterial;
                }
            }
            else if (ReplaceRadioButton.IsChecked ?? false)
            {
                newStandardEffect = _defaultStandardEffect;

                // Create a clone of YellowMaterial
                var yellowMaterial = this.FindResource("YellowMaterial") as DiffuseMaterial;

                if (yellowMaterial != null)
                {
                    _yellowFogWpfMaterial = yellowMaterial.Clone();

                    // Now create a DXEngine's material that is created from WPF's material:
                    var yellowFogDXEngineMaterial = new Ab3d.DirectX.Materials.WpfMaterial(_yellowFogWpfMaterial);

                    // Specify the exact effect that will be used to render this material (if not specified, then the StandardEffect is used)
                    yellowFogDXEngineMaterial.Effect = _fogEffect;

                    // Now that we have both WPF material and DXEngine's material,
                    // we can specify that whenever the _yellowFogWpfMaterial will be used (and when our DXDevice is used),
                    // we should use the specified yellowFogDXEngineMaterial.
                    // This is done with the static SetUsedDXMaterial method.
                    //
                    // TIP: The same approach can be used to use some other rendering technique to render on material - for example to use ModelColorLineEffect, ThickLineEffect or SolidColorEffect.
                    Ab3d.DirectX.Materials.WpfMaterial.SetUsedDXMaterial(_yellowFogWpfMaterial, yellowFogDXEngineMaterial);

                    // NOTE:
                    // Instead of calling SetUsedDXMaterial, we could also specify the DXDevice in the WpfMaterial constructor.
                    // This would call the SetUsedDXMaterial behind the scenes. But we did it here in the long way to better demonstrate what is going on.
                    // The following code would call SetUsedDXMaterial in the constructor:
                    // var yellowFogDXEngineMaterial = new Ab3d.DirectX.Materials.WpfMaterial(_yellowFogWpfMaterial, MainDXViewportView.DXScene.DXDevice);

                    // After the _yellowFogWpfMaterial is "connected" to the yellowFogDXEngineMaterial, we can assign it insetad of yellow material:
                    foreach (var baseModelVisual3D in MainViewport.Children.OfType <BaseModelVisual3D>())
                    {
                        if (ReferenceEquals(baseModelVisual3D.Material, yellowMaterial))
                        {
                            baseModelVisual3D.Material = _yellowFogWpfMaterial;
                        }
                    }
                }
            }
            else
            {
                newStandardEffect = _defaultStandardEffect;
            }

            MainDXViewportView.DXScene.DXDevice.EffectsManager.SetStandardEffect(newStandardEffect);
        }
        private void GenerateHeightMapObject(float[,] heightData, Color4[] positionColorsArray)
        {
            PositionNormalTexture[] vertexBuffer;
            int[] indexBuffer;

            CreateHeightVertexAndIndexBuffer(heightData,
                                             centerPosition: new Vector3(0, 0, 0),
                                             size: new Vector3(1000, 20, 200),
                                             vertexBuffer: out vertexBuffer,
                                             indexBuffer: out indexBuffer);

            var simpleMesh = new SimpleMesh <PositionNormalTexture>(vertexBuffer,
                                                                    indexBuffer,
                                                                    inputLayoutType: InputLayoutType.Position | InputLayoutType.Normal | InputLayoutType.TextureCoordinate,
                                                                    name: "HeightSimpleMesh");

            _disposables.Add(simpleMesh);


            Ab3d.DirectX.Material dxMaterial;

            if (positionColorsArray != null)
            {
                dxMaterial = new Ab3d.DirectX.Materials.VertexColorMaterial()
                {
                    PositionColors      = positionColorsArray, // The PositionColors property is used to specify colors for each vertex
                    CreateDynamicBuffer = false,               // We will not update the colors frequently

                    // To show specular effect set the specular data here:
                    //SpecularPower = 16,
                    //SpecularColor = Color3.White,
                    //HasSpecularColor = true
                };
            }
            else
            {
                // Solid color material:
                var diffuseMaterial = new DiffuseMaterial(Brushes.Green);

                // Texture material:
                //var imageBrush = new ImageBrush();
                //imageBrush.ImageSource = new BitmapImage(new Uri("pack://application:,,,/Resources/GrassTexture.jpg"));
                //var diffuseMaterial = new DiffuseMaterial(imageBrush);

                dxMaterial = new Ab3d.DirectX.Materials.WpfMaterial(diffuseMaterial);
            }

            _disposables.Add(dxMaterial);

            var meshObjectNode = new Ab3d.DirectX.MeshObjectNode(simpleMesh, dxMaterial);

            meshObjectNode.Name = "HeightMeshObjectNode";

            _disposables.Add(meshObjectNode);

            var sceneNodeVisual3D = new SceneNodeVisual3D(meshObjectNode);

            MainViewport.Children.Add(sceneNodeVisual3D);


            // If you also want to render back faces of the height map you need to create another MeshObjectNode and set its IsBackFaceMaterial to true.
            // You can reuse the mesh. But this still requires almost twice the GPU power.
            var backDiffuseMaterial = new DiffuseMaterial(Brushes.Gray);
            var backDXMaterial      = new Ab3d.DirectX.Materials.WpfMaterial(backDiffuseMaterial);

            meshObjectNode = new Ab3d.DirectX.MeshObjectNode(simpleMesh, backDXMaterial);
            meshObjectNode.IsBackFaceMaterial = true;
            meshObjectNode.Name = "HeightBackMeshObjectNode";

            _disposables.Add(meshObjectNode);

            sceneNodeVisual3D = new SceneNodeVisual3D(meshObjectNode);
            MainViewport.Children.Add(sceneNodeVisual3D);
        }