/// <summary>
        /// 
        /// </summary>
        protected virtual void AttachMaterial()
        {
            this.phongMaterial = Material as PhongMaterial;
            if (phongMaterial != null)
            {
                this.effectMaterial = new EffectMaterialVariables(this.effect);

                /// --- has texture
                if (phongMaterial.DiffuseMap != null)
                {
                    this.texDiffuseMapView = ShaderResourceView.FromMemory(Device, phongMaterial.DiffuseMap.ToByteArray());
                    this.effectMaterial.texDiffuseMapVariable.SetResource(this.texDiffuseMapView);
                    this.effectMaterial.bHasDiffuseMapVariable.Set(true);
                }
                else
                {
                    this.effectMaterial.bHasDiffuseMapVariable.Set(false);
                }

                // --- has bumpmap
                if (phongMaterial.NormalMap != null)
                {
                    var geometry = this.Geometry as MeshGeometry3D;
                    if (geometry != null)
                    {
                        if (geometry.Tangents == null)
                        {
                            //System.Windows.MessageBox.Show(string.Format("No Tangent-Space found. NormalMap will be omitted."), "Warrning", MessageBoxButton.OK);
                            phongMaterial.NormalMap = null;
                        }
                        else
                        {
                            this.texNormalMapView = ShaderResourceView.FromMemory(Device, phongMaterial.NormalMap.ToByteArray());
                            this.effectMaterial.texNormalMapVariable.SetResource(this.texNormalMapView);
                            this.effectMaterial.bHasNormalMapVariable.Set(true);
                        }
                    }
                }
                else
                {
                    this.effectMaterial.bHasNormalMapVariable.Set(false);
                }

                // --- has displacement map
                if (phongMaterial.DisplacementMap != null)
                {
                    this.texDisplacementMapView = ShaderResourceView.FromMemory(Device, phongMaterial.DisplacementMap.ToByteArray());
                    this.effectMaterial.texDisplacementMapVariable.SetResource(this.texDisplacementMapView);
                    this.effectMaterial.bHasDisplacementMapVariable.Set(true);
                }
                else
                {
                    this.effectMaterial.bHasDisplacementMapVariable.Set(false);
                }
            }
        }
            /// <summary>
            /// Creates the material.
            /// </summary>
            /// <param name="texturePath">The texture path.</param>
            /// <returns>A WPF material.</returns>
            private Material CreateMaterial(string texturePath)
            {
                var mat = new PhongMaterial()
                {
                    AmbientColor = this.Ambient,
                    //AmbientMap = this.AmbientMap,

                    DiffuseColor = this.Diffuse,
                    DiffuseMap = (this.DiffuseMap == null) ? null : LoadImage(Path.Combine(texturePath, this.DiffuseMap)),

                    SpecularColor = this.Specular,
                    SpecularShininess = (float)this.SpecularCoefficient,
                    //SpecularMap = this.SpecularMap,

                    NormalMap = (this.BumpMap == null) ? null : LoadImage(Path.Combine(texturePath, this.BumpMap)),
                    //Dissolved = this.Dissolved,
                    //Illumination = this.Illumination,

                };

                //return mg.Children.Count != 1 ? mg : mg.Children[0];
                return mat;
            }
        /// <summary>
        /// 
        /// </summary>
        public override void Detach()
        {
            Disposer.RemoveAndDispose(ref this.vertexBuffer);
            Disposer.RemoveAndDispose(ref this.indexBuffer);
            Disposer.RemoveAndDispose(ref this.instanceBuffer);

            Disposer.RemoveAndDispose(ref this.effectMaterial);
            Disposer.RemoveAndDispose(ref this.effectTransforms);
            Disposer.RemoveAndDispose(ref this.texDiffuseMapView);
            Disposer.RemoveAndDispose(ref this.texNormalMapView);
            Disposer.RemoveAndDispose(ref this.texDisplacementMapView);
            Disposer.RemoveAndDispose(ref this.bHasInstances);

            this.phongMaterial = null;
            this.effectTechnique = null;
            this.vertexLayout = null;

            base.Detach();
        }
        private void SetImages(BitmapSource img)
        {
            var ratio = img.PixelWidth / (double)img.PixelHeight;
            var transform = Media3D.Transform3D.Identity;
            ushort orientation = 1;
            if (this.ExifReader != null && this.ExifReader.GetTagValue(ExifTags.Orientation, out orientation))
            {
                switch (orientation)
                {
                    default:
                    case 1: //
                        transform = transform.AppendTransform(new Media3D.ScaleTransform3D(ratio, 1.0, 1.0));
                        break;
                    case 2: //"-flip horizontal";;
                        //transform = Media3D.Transform3D.Identity;
                        break;
                    case 3: //"-rotate 180";;
                        transform = transform.AppendTransform(new Media3D.ScaleTransform3D(ratio, 1.0, 1.0));
                        transform = transform.AppendTransform(new Media3D.RotateTransform3D(new Media3D.AxisAngleRotation3D(new Vector3D(0, 0, 1), -180)));
                        break;
                    case 4: //"-flip vertical";;
                        //transform = Media3D.Transform3D.Identity;
                        break;
                    case 5: //"-transpose";;
                        //transform = Media3D.Transform3D.Identity;
                        break;
                    case 6: //"-rotate 90";;
                        transform = transform.AppendTransform(new Media3D.ScaleTransform3D(1.0, 1.0 / ratio, 1.0));
                        transform = transform.AppendTransform(new Media3D.RotateTransform3D(new Media3D.AxisAngleRotation3D(new Vector3D(0, 0, 1), -90)));
                        break;
                    case 7: //"-transverse";;
                        // transform = Media3D.Transform3D.Identity;
                        break;
                    case 8: //"-rotate 270";;
                        transform = transform.AppendTransform(new Media3D.ScaleTransform3D(1.0, 1.0 / ratio, 1.0));
                        transform = transform.AppendTransform(new Media3D.RotateTransform3D(new Media3D.AxisAngleRotation3D(new Vector3D(0, 0, 1), -270)));
                        break;
                }

                this.PlaneTransform = transform;
                this.GridTransform = transform;
            }
            else
            {
                if (ratio > 1)
                {
                    transform = transform.AppendTransform(new Media3D.ScaleTransform3D(ratio, 1.0, 1.0));
                    this.PlaneTransform = transform;
                    this.GridTransform = this.PlaneTransform;
                }
                else
                {
                    transform = transform.AppendTransform(new Media3D.ScaleTransform3D(1.0, 1.0 / ratio, 1.0));
                    this.PlaneTransform = transform;
                    this.GridTransform = this.PlaneTransform;
                }
            }

            var white = new PhongMaterial()
            {
                DiffuseColor = Color.White,
                AmbientColor = Color.Black,
                ReflectiveColor = Color.Black,
                EmissiveColor = Color.Black,
                SpecularColor = Color.Black,
                DiffuseMap = img,
            };

            this.PlaneMaterial = white;
            this.RenderTechnique = this.RenderTechniquesManager.RenderTechniques[DefaultRenderTechniqueNames.Blinn];
        }