/// <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.vFrustum);
            Disposer.RemoveAndDispose(ref this.vViewport);
            Disposer.RemoveAndDispose(ref this.vLineParams);
            Disposer.RemoveAndDispose(ref this.rasterState);
            //Disposer.RemoveAndDispose(ref this.depthStencilState);
            Disposer.RemoveAndDispose(ref this.bHasInstances);

            this.effectName   = null;
            this.geometry     = null;
            this.technique    = null;
            this.vertexLayout = null;

            base.Detach();
        }
        private void TransformPositions()
        {
            // get old positions
            Vector3[] p = this.Geometry.Positions.Select(a => a).ToArray();
            int       n = p.Count();

            Vector4[] ph = new Vector4[n];

            // to homogeneous coordiantes
            for (int i = 0; i < n; i++)
            {
                ph[i] = p[i].ToVector4(1f);
            }
            // transform by this.DragTransform
            var T = this.DragTransform.ToMatrix();

            Vector4.Transform(ph, ref T, ph);

            // to inhomogeneous coordinates
            for (int i = 0; i < n; i++)
            {
                p[i] = ph[i].ToVector3();
            }

            // save as new positions in new geometry
            Color4[] colors = this.Geometry.Colors;
            Int32[]  ind    = this.Geometry.Indices;

            LineGeometry3D newG = new HelixToolkit.SharpDX.Wpf.LineGeometry3D();

            newG.Positions = p;
            newG.Colors    = colors;
            newG.Indices   = ind;

            this.Geometry = newG;
        }
        /// <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.vFrustum);
            Disposer.RemoveAndDispose(ref this.vViewport);
            Disposer.RemoveAndDispose(ref this.vLineParams);            
            Disposer.RemoveAndDispose(ref this.rasterState);
            //Disposer.RemoveAndDispose(ref this.depthStencilState);
            Disposer.RemoveAndDispose(ref this.bHasInstances);

            this.effectName = null;            
            this.geometry = null;
            this.technique = null;
            this.vertexLayout = null;

            base.Detach();
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="host"></param>
        public override void Attach(IRenderHost host)
        {
            /// --- attach
            this.effectName = Techniques.RenderSpineTest;
            base.Attach(host);

            if (this.Geometry == null)
            {
                return;
            }

            if (renderHost.RenderTechnique == Techniques.RenderDeferred || renderHost.RenderTechnique == Techniques.RenderGBuffer)
            {
                return;
            }

            // --- get device
            this.vertexLayout = host.Effects.GetLayout(this.effectName);
            this.technique    = effect.GetTechniqueByName(this.effectName);

            this.effectTransforms = new EffectTransformVariables(this.effect);
            this.geometry         = this.Geometry as LineGeometry3D;

            /// --- set up buffers
            this.vertexBuffer = device.CreateBuffer(BindFlags.VertexBuffer, DefaultVertex.SizeInBytes, this.Geometry.Positions.Select((x, ii) => new LinesVertex()
            {
                Position = new Vector4(x, 1f),
                Color    = this.Color,
            }).ToArray());

            /// --- set up indexbuffer
            this.indexBuffer = device.CreateBuffer(BindFlags.IndexBuffer, sizeof(int), this.geometry.Indices);


            /// --- init instances buffer
            this.hasInstances  = this.Instances != null;
            this.bHasInstances = this.effect.GetVariableByName("bHasInstances").AsScalar();
            if (this.hasInstances)
            {
                this.instanceBuffer = Buffer.Create(this.device, this.instanceArray, new BufferDescription(Matrix.SizeInBytes * this.instanceArray.Length, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, 0));
            }

            /// --- set up const variables
            this.vViewport   = effect.GetVariableByName("vViewport").AsVector();
            this.vFrustum    = effect.GetVariableByName("vFrustum").AsVector();
            this.vLineParams = effect.GetVariableByName("vLineParams").AsVector();

            /// --- set effect per object const vars
            var lineParams = new Vector4((float)this.Thickness, (float)this.Smoothness, 0, 0);

            this.vLineParams.Set(lineParams);

            /// === debug hack
            //{
            //    var texDiffuseMapView = ShaderResourceView.FromFile(device, @"G:\Projects\Deformation Project\FrameworkWPF2012\Externals\HelixToolkit-SharpDX\Source\Examples\SharpDX.Wpf\LightingDemo.SharpDX\TextureCheckerboard2.jpg");
            //    var texDiffuseMap = effect.GetVariableByName("texDiffuseMap").AsShaderResource();
            //    texDiffuseMap.SetResource(texDiffuseMapView);
            //}

            /// --- create raster state
            this.OnRasterStateChanged(this.DepthBias);



            //this.rasterState = new RasterizerState(this.device, rasterStateDesc);

            /// --- set up depth stencil state
            //var depthStencilDesc = new DepthStencilStateDescription()
            //{
            //    DepthComparison = Comparison.Less,
            //    DepthWriteMask = global::SharpDX.Direct3D11.DepthWriteMask.All,
            //    IsDepthEnabled = true,
            //};
            //this.depthStencilState = new DepthStencilState(this.device, depthStencilDesc);


            /// --- flush
            this.device.ImmediateContext.Flush();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="host"></param>
        public override void Attach(IRenderHost host)
        {
            /// --- attach            
            this.effectName = Techniques.RenderSpineTest;
            base.Attach(host);

            if (this.Geometry == null)            
                return;

            if (renderHost.RenderTechnique == Techniques.RenderDeferred || renderHost.RenderTechnique == Techniques.RenderGBuffer)
                return;  

            // --- get device
            this.vertexLayout = host.Effects.GetLayout(this.effectName);
            this.technique = effect.GetTechniqueByName(this.effectName);

            this.effectTransforms = new EffectTransformVariables(this.effect);
            this.geometry = this.Geometry as LineGeometry3D;
            
            /// --- set up buffers            
            this.vertexBuffer = device.CreateBuffer(BindFlags.VertexBuffer, DefaultVertex.SizeInBytes, this.Geometry.Positions.Select((x, ii) => new LinesVertex()
            {
                Position = new Vector4(x, 1f),
                Color = this.Color,
            }).ToArray());

            /// --- set up indexbuffer
            this.indexBuffer = device.CreateBuffer(BindFlags.IndexBuffer, sizeof(int), this.geometry.Indices);


            /// --- init instances buffer            
            this.hasInstances = this.Instances != null;
            this.bHasInstances = this.effect.GetVariableByName("bHasInstances").AsScalar();
            if (this.hasInstances)
            {
                this.instanceBuffer = Buffer.Create(this.device, this.instanceArray, new BufferDescription(Matrix.SizeInBytes * this.instanceArray.Length, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, 0));
            }

            /// --- set up const variables
            this.vViewport = effect.GetVariableByName("vViewport").AsVector();
            this.vFrustum = effect.GetVariableByName("vFrustum").AsVector();
            this.vLineParams = effect.GetVariableByName("vLineParams").AsVector();

            /// --- set effect per object const vars
            var lineParams = new Vector4((float)this.Thickness, (float)this.Smoothness, 0, 0);
            this.vLineParams.Set(lineParams);

            /// === debug hack
            //{
            //    var texDiffuseMapView = ShaderResourceView.FromFile(device, @"G:\Projects\Deformation Project\FrameworkWPF2012\Externals\HelixToolkit-SharpDX\Source\Examples\SharpDX.Wpf\LightingDemo.SharpDX\TextureCheckerboard2.jpg");
            //    var texDiffuseMap = effect.GetVariableByName("texDiffuseMap").AsShaderResource();
            //    texDiffuseMap.SetResource(texDiffuseMapView);                
            //}

            /// --- create raster state
            this.OnRasterStateChanged(this.DepthBias);
            

            
            //this.rasterState = new RasterizerState(this.device, rasterStateDesc);

            /// --- set up depth stencil state
            //var depthStencilDesc = new DepthStencilStateDescription()
            //{
            //    DepthComparison = Comparison.Less,
            //    DepthWriteMask = global::SharpDX.Direct3D11.DepthWriteMask.All,
            //    IsDepthEnabled = true,
            //};
            //this.depthStencilState = new DepthStencilState(this.device, depthStencilDesc);   
           

            /// --- flush
            this.device.ImmediateContext.Flush();
        }