Exemplo n.º 1
0
        private void Render()
        {
            var device = this.device;
            if (device == null)
                return;

            var renderTarget = colorBuffer;
            if (renderTarget == null)
                return;

            if (renderRenderable != null)
            {
                /// ---------------------------------------------------------------------------
                /// this part is done only if the scene is not attached
                /// it is an attach and init pass for all elements in the scene-graph                
                if (!sceneAttached)
                {
                    try
                    {
                        Light3D.LightCount = 0;
                        sceneAttached = true;
                        ClearColor = renderRenderable.BackgroundColor;
                        IsShadowMapEnabled = renderRenderable.IsShadowMappingEnabled;

                        var blinn = RenderTechniquesManager.RenderTechniques[DefaultRenderTechniqueNames.Blinn];
                        RenderTechnique = renderRenderable.RenderTechnique == null ? blinn : renderRenderable.RenderTechnique;
                            
                        if (renderContext != null)
                        {
                            renderContext.Dispose();
                        }
                        renderContext = new RenderContext(this, EffectsManager.GetEffect(RenderTechnique));
                        renderRenderable.Attach(this);

                        RenderTechniquesManager.RenderTechniques.TryGetValue(DeferredRenderTechniqueNames.GBuffer, out gbuffer);
                        RenderTechniquesManager.RenderTechniques.TryGetValue(DeferredRenderTechniqueNames.Deferred, out deferred);

                        if (RenderTechnique == deferred)
                        {
                            deferredRenderer.InitBuffers(this, Format.R32G32B32A32_Float);
                        }
                        else if (RenderTechnique == gbuffer)
                        {
                            deferredRenderer.InitBuffers(this, Format.B8G8R8A8_UNorm);
                        }
                    }
                    catch (Exception ex)
                    {
                        //MessageBox.Show("DPFCanvas: Error attaching element: " + string.Format(ex.Message), "Error");
                        Debug.WriteLine("DPFCanvas: Error attaching element: " + string.Format(ex.Message), "Error");
                        throw;
                    }
                }

                // ---------------------------------------------------------------------------
                // this part is per frame
                // ---------------------------------------------------------------------------

                SetDefaultRenderTargets();
                
                if (RenderTechnique == deferred)
                {
                    /// set G-Buffer                    
                    deferredRenderer.SetGBufferTargets();

                    /// render G-Buffer pass                
                    renderRenderable.Render(renderContext);

                    /// call deferred render 
                    deferredRenderer.RenderDeferred(renderContext, renderRenderable);

                }
                else if (RenderTechnique == gbuffer)
                {
                    /// set G-Buffer
                    deferredRenderer.SetGBufferTargets(targetWidth / 2, targetHeight / 2);

                    /// render G-Buffer pass                    
                    renderRenderable.Render(renderContext);

                    /// reset render targets and run lighting pass                                         
#if MSAA
                    deferredRenderer.RenderGBufferOutput(ref renderTargetNMS);
#else
                    this.deferredRenderer.RenderGBufferOutput(ref this.colorBuffer);
#endif
                }
                else
                {
                    this.device.ImmediateContext.ClearRenderTargetView(colorBufferView, ClearColor);
                    this.device.ImmediateContext.ClearDepthStencilView(depthStencilBufferView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);

                    renderRenderable.Render(renderContext);
                }
            }

            this.device.ImmediateContext.Flush();
        }
Exemplo n.º 2
0
        public override void Render(RenderContext context)
        {
            if (!this.IsRendering) return;

            /// --- set context
            this.device.ImmediateContext.InputAssembler.InputLayout = this.vertexLayout;
            this.device.ImmediateContext.InputAssembler.PrimitiveTopology = Direct3D.PrimitiveTopology.TriangleList;
            this.device.ImmediateContext.InputAssembler.SetIndexBuffer(this.indexBuffer, Format.R32_UInt, 0);
            this.device.ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(this.vertexBuffer, CubeVertex.SizeInBytes, 0));

            this.device.ImmediateContext.Rasterizer.State = rasterState;
            this.device.ImmediateContext.OutputMerger.DepthStencilState = depthStencilState;

            /// --- set constant paramerers 
            var worldMatrix = Matrix.Translation(((PerspectiveCamera)context.Camera).Position.ToVector3());
            this.effectTransforms.mWorld.SetMatrix(ref worldMatrix);

            /// --- render the geometry
            this.technique.GetPassByIndex(0).Apply(device.ImmediateContext);
            this.device.ImmediateContext.DrawIndexed(this.geometry.Indices.Length, 0, 0);
        }
Exemplo n.º 3
0
        static internal void Render(
            IntPtr pRenderTarget,
            DUCE.Channel channel,
            Visual visual,
            int width,
            int height,
            double dpiX,
            double dpiY,
            Matrix worldTransform,
            Rect windowClip
            )
        {
            DUCE.Resource target =
                new DUCE.Resource();
            DUCE.Resource root =
                new DUCE.Resource();

            DUCE.ResourceHandle targetHandle = DUCE.ResourceHandle.Null;
            DUCE.ResourceHandle rootHandle = DUCE.ResourceHandle.Null;

            Matrix deviceTransform = new Matrix(
                dpiX * (1.0 / 96.0),    0,
                0,                      dpiY * (1.0 / 96.0),
                0,                      0);

            deviceTransform = worldTransform * deviceTransform;
            MatrixTransform mtDeviceTransform = new MatrixTransform(deviceTransform);

            DUCE.ResourceHandle deviceTransformHandle =
                ((DUCE.IResource)mtDeviceTransform).AddRefOnChannel(channel);


            try
            {
                // ------------------------------------------------------------
                //   Create the composition target and root visual resources.

                target.CreateOrAddRefOnChannel(target, channel, DUCE.ResourceType.TYPE_GENERICRENDERTARGET);
                targetHandle = target.Handle;

                DUCE.CompositionTarget.PrintInitialize(
                    targetHandle,
                    pRenderTarget,
                    width,
                    height,
                    channel);

                root.CreateOrAddRefOnChannel(root, channel, DUCE.ResourceType.TYPE_VISUAL);
                rootHandle = root.Handle;

                DUCE.CompositionNode.SetTransform(
                    rootHandle,
                    deviceTransformHandle,
                    channel);

                DUCE.CompositionTarget.SetRoot(
                    targetHandle,
                    rootHandle,
                    channel);

                channel.CloseBatch();
                channel.Commit();


                // ------------------------------------------------------------
                //   Render the freshly created target.

                RenderContext renderContext = new RenderContext();

                renderContext.Initialize(channel, rootHandle);

                visual.Precompute();

                visual.Render(renderContext, 0);

                // ------------------------------------------------------------
                //   Flush the channel and present the composition target.

                channel.CloseBatch();
                channel.Commit();
                channel.Present();

                MediaContext mediaContext = MediaContext.CurrentMediaContext;
                mediaContext.NotifySyncChannelMessage(channel);

            }
            finally
            {
                // ------------------------------------------------------------
                //   Clean up and release the root visual.

                if (!rootHandle.IsNull)
                {
                    DUCE.CompositionNode.RemoveAllChildren(
                        rootHandle,
                        channel);

                    ((DUCE.IResource)visual).ReleaseOnChannel(channel);

                    root.ReleaseOnChannel(channel);
                }


                // ------------------------------------------------------------
                //   Release the world transform.

                if (!deviceTransformHandle.IsNull)
                {
                    ((DUCE.IResource)mtDeviceTransform).ReleaseOnChannel(channel);
                }


                // ------------------------------------------------------------
                //   Clean up and release the composition target.

                if (!targetHandle.IsNull)
                {
                    DUCE.CompositionTarget.SetRoot(
                        targetHandle,
                        DUCE.ResourceHandle.Null,
                        channel);

                    target.ReleaseOnChannel(channel);
                }

                // ------------------------------------------------------------
                //   Flush the channel and present the composition target.

                channel.CloseBatch();
                channel.Commit();
                channel.Present();

                MediaContext mediaContext = MediaContext.CurrentMediaContext;
                mediaContext.NotifySyncChannelMessage(channel);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Update children
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="handle"></param>
        private void UpdateChildren(RenderContext ctx,
                                    DUCE.ResourceHandle handle)
        {
            DUCE.Channel channel = ctx.Channel;

            //
            // Visit children of this visual.
            //
            //
            // If content node is connected child node indicies need to be offset by one.
            //

            UInt32 connectedChildIndex =
                CheckFlagsAnd(channel, VisualProxyFlags.IsContentNodeConnected) ? (UInt32)1 : 0;

            bool isChildrenZOrderDirty = CheckFlagsAnd(channel, VisualProxyFlags.IsChildrenZOrderDirty);
            int childCount = VisualChildrenCount;

            //
            // If the visual children have been re-ordered, enqueue a packet to RemoveAllChildren,
            // then reinsert all the children.  The parent visual will release the children when
            // the RemoveAllChildren packet, but the managed visuals will still have references
            // to them so that they won't be destructed and recreated.
            //
            if (isChildrenZOrderDirty)
            {
                DUCE.CompositionNode.RemoveAllChildren(
                    handle,
                    channel);
            }

            for (int i = 0; i < childCount; i++)
            {
                Visual child = GetVisualChild(i);
                if (child != null)
                {
                    //
                    // Recurse if the child visual is dirty
                    // or it has not been marshalled yet.
                    //
                    if (child.CheckFlagsAnd(channel, VisualProxyFlags.IsSubtreeDirtyForRender)
                        || !(child.IsOnChannel(channel)))
                    {
                        child.RenderRecursive(ctx);
                    }

                    //
                    // Make sure that all the marshaled children are
                    // connected to the parent visual or that the ZOrder
                    // of the children has changed.
                    //
                    if (child.IsOnChannel(channel))
                    {
                        bool isConnectedToParent = child.CheckFlagsAnd(channel, VisualProxyFlags.IsConnectedToParent);

                        if (!isConnectedToParent || isChildrenZOrderDirty)
                        {
                            DUCE.CompositionNode.InsertChildAt(
                                handle,
                                ((DUCE.IResource)child).GetHandle(channel),
                                connectedChildIndex,
                                channel);

                            child.SetFlags(
                                channel,
                                true,
                                VisualProxyFlags.IsConnectedToParent);
                        }

                        connectedChildIndex++;
                    }
                }
            }

            SetFlags(channel, false, VisualProxyFlags.IsChildrenZOrderDirty);
        }
Exemplo n.º 5
0
 /// <summary>
 /// RenderContent is implemented by derived classes to hook up their
 /// content. The implementer of this function can assert that the
 /// visual is marshaled on the current channel when the function
 /// is executed.
 /// </summary>
 internal virtual void RenderContent(RenderContext ctx, bool isOnChannel)
 {
     /* do nothing */
 }
Exemplo n.º 6
0
        /// <summary>
        /// RenderContent is implemented by derived classes to hook up their
        /// content. The implementer of this function can assert that the _hCompNode
        /// is valid on a channel when the function is executed.
        /// </summary>
        internal override void RenderContent(RenderContext ctx, bool isOnChannel)
        {
            DUCE.Channel channel = ctx.Channel;

            Debug.Assert(!CheckFlagsAnd(channel, VisualProxyFlags.IsContentConnected));
            Debug.Assert(_proxy.IsOnChannel(channel));


            //
            // Create the content on the channel.
            //

            if (_content != null)
            {
                DUCE.CompositionNode.SetContent(
                    _proxy.GetHandle(channel),
                    ((DUCE.IResource)_content).AddRefOnChannel(channel),
                    channel);

                SetFlags(
                    channel, 
                    true, 
                    VisualProxyFlags.IsContentConnected);
            }
            else if (isOnChannel) /*_content == null*/
            {
                DUCE.CompositionNode.SetContent(
                    _proxy.GetHandle(channel),
                    DUCE.ResourceHandle.Null,
                    channel);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Update content
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="flags"></param>
        /// <param name="isOnChannel">The Visual exists on channel.</param>        
        private void UpdateContent(RenderContext ctx,
                                   VisualProxyFlags flags,
                                   bool isOnChannel)
        {
            //
            // Hookup content to the Visual
            //

            if ((flags & VisualProxyFlags.IsContentDirty) != 0)
            {
                RenderContent(ctx, isOnChannel);
                SetFlags(ctx.Channel, false, VisualProxyFlags.IsContentDirty);
            }
        }
Exemplo n.º 8
0
 /// <summary>
 /// Renders the scene.
 /// </summary>
 void IRenderable.Render(RenderContext context)
 {            
     context.Camera = this.Camera;
     foreach (Element3D e in this.Items)
     {
         e.Render(context);
     }
 }
Exemplo n.º 9
0
        internal void Render(RenderContext ctx, UInt32 childIndex)
        {
            DUCE.Channel channel = ctx.Channel;

            //
            // Currently everything is sent to the compositor. IsSubtreeDirtyForRender
            // indicates that something in the sub-graph of this Visual needs to have an update
            // sent to the compositor. Hence traverse if this bit is set. Also traverse when the
            // sub-graph has not yet been sent to the compositor.
            //

            if (CheckFlagsAnd(channel, VisualProxyFlags.IsSubtreeDirtyForRender)
                || !IsOnChannel(channel))
            {
                RenderRecursive(ctx);
            }


            //
            // Connect the root visual to the composition root if necessary.
            //

            if (IsOnChannel(channel)
                && !CheckFlagsAnd(channel, VisualProxyFlags.IsConnectedToParent)
                && !ctx.Root.IsNull)
            {
                DUCE.CompositionNode.InsertChildAt(
                    ctx.Root,
                    _proxy.GetHandle(channel),
                    childIndex,
                    channel);

                SetFlags(
                    channel,
                    true,
                    VisualProxyFlags.IsConnectedToParent);
            }
        }
Exemplo n.º 10
0
        private void Compile(DUCE.Channel channel)
        {
            MediaContext mctx = MediaContext.From(Dispatcher);

            Invariant.Assert(_rootVisual.Value!=null);

            // 1) Check if we have a cached render context.
            // 2) Initialize the render context.
            // 3) Call to render the scene graph (transforming it into the composition scene graph).
            // 4) Deinitalize the render context and cache it if possible.

            // ------------------------------------------------------------------------------------
            // 1) Get cached render context if possible.

            // For performance reasons the render context is cached between frames. Here we check if
            // we have a cached one. If we don't we just create a new one. If we do have one, we use
            // the render context. Note that we null out the _cachedRenderContext field. This means
            // that in failure cases we will always recreate the render context.

            RenderContext rc = null;

            Invariant.Assert(channel != null);
            if (_cachedRenderContext != null)
            {
                rc = _cachedRenderContext;
                _cachedRenderContext = null;
            }
            else
            {
                rc = new RenderContext();
            }

            // ------------------------------------------------------------------------------------
            // 2) Prepare the render context.

            rc.Initialize(channel, _contentRoot.GetHandle(channel));

            // ------------------------------------------------------------------------------------
            // 3) Compile the scene.

            if (mctx.IsConnected)
            {
               _rootVisual.Value.Render(rc, 0);
            }

            // ------------------------------------------------------------------------------------
            // 4) Cache the render context.

            Debug.Assert(_cachedRenderContext == null);
            _cachedRenderContext = rc;
        }
Exemplo n.º 11
0
        internal override void RenderContent(RenderContext ctx, bool isOnChannel)
        {
            DUCE.Channel channel = ctx.Channel;

            //
            // At this point, the visual has to be marshalled. Force 
            // marshalling of the camera and viewport in case we have
            // just created a new visual resource.
            //

            Debug.Assert(IsOnChannel(channel));
            VisualProxyFlags flags = _proxy.GetFlags(channel);


            //
            // Make sure the camera resource is being marshalled properly.
            //

            if ((flags & VisualProxyFlags.Viewport3DVisual_IsCameraDirty) != 0) 
            {
                Camera camera = Camera;
                if (camera != null) 
                {
                    DUCE.Viewport3DVisualNode.SetCamera(
                        ((DUCE.IResource)this).GetHandle(channel),
                        ((DUCE.IResource)camera).AddRefOnChannel(channel),
                        channel);
                }
                else if (isOnChannel) /* camera == null */
                {
                    DUCE.Viewport3DVisualNode.SetCamera(
                        ((DUCE.IResource)this).GetHandle(channel),
                        DUCE.ResourceHandle.Null,
                        channel);
                }
                SetFlags(channel, false, VisualProxyFlags.Viewport3DVisual_IsCameraDirty);
            }


            //
            // Set the viewport if it's dirty.
            //

            if ((flags & VisualProxyFlags.Viewport3DVisual_IsViewportDirty) != 0) 
            {
                DUCE.Viewport3DVisualNode.SetViewport(
                    ((DUCE.IResource)this).GetHandle(channel),
                    Viewport,
                    channel);
                SetFlags(channel, false, VisualProxyFlags.Viewport3DVisual_IsViewportDirty);               
            }


            //we only want to recurse in the children if the visual does not have a bitmap effect
            //or we are in the BitmapVisualManager render pass
        
            // Visit children of this node -----------------------------------------------------------------------
        
            Debug.Assert(!CheckFlagsAnd(channel, VisualProxyFlags.IsContentNodeConnected),
                "Only HostVisuals are expected to have a content node.");
            
            if (_children != null)
            {
                for (uint i = 0; i < _children.InternalCount; i++)
                {
                    Visual3D child = _children.InternalGetItem((int) i);
            
                    if (child != null)
                    {
                        if (child.CheckFlagsAnd(channel, VisualProxyFlags.IsSubtreeDirtyForRender) || // or the visual is dirty                                
                            !(child.IsOnChannel(channel))) // or the child has not been marshalled yet.
                        {
                            child.RenderRecursive(ctx);
                        }
            
                        if (child.IsOnChannel(channel))
                        {
                            if (!child.CheckFlagsAnd(channel, VisualProxyFlags.IsConnectedToParent))
                            {
                                DUCE.Visual3DNode.InsertChildAt(
                                    _proxy3D.GetHandle(channel),
                                    ((DUCE.IResource)child).GetHandle(channel),
                                    /* iPosition = */ i,
                                    channel);
            
                                child.SetFlags(channel, true, VisualProxyFlags.IsConnectedToParent);
                            }
                        }
                    }
                }
            }            
        }
Exemplo n.º 12
0
        /// <summary>
        /// Sets the given resources as render targets:
        /// </summary>
        /// <param name="width">width of the target</param>
        /// <param name="height">height of the target</param>
        /// <param name="renderTargetView">the color buffer resource</param>
        /// <param name="depthStencilView">the depth-stencil buffer resource</param>
        //private void SetRenderTargets(int width, int height, RenderTargetView renderTargetView, DepthStencilView depthStencilView)
        //{
        //    this.device.ImmediateContext.OutputMerger.SetTargets(depthStencilView, renderTargetView);
        //    this.device.ImmediateContext.Rasterizer.SetViewports(new Viewport(0, 0, width, height, 0.0f, 1.0f));

        //    this.device.ImmediateContext.ClearRenderTargetView(renderTargetView, this.ClearColor);
        //    this.device.ImmediateContext.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sceneTime"></param>
        private void Render(System.TimeSpan sceneTime)
        {
            var device = this.device;
            if (device == null)
                return;

            var renderTarget = this.renderTarget;
            if (renderTarget == null)
                return;

            if (this.Renderable != null)
            {
                /// ---------------------------------------------------------------------------
                /// this part is done only if the scene is not attached
                /// it is an attach and init pass for all elements in the scene-graph                
                if (!this.sceneAttached)
                {
                    try
                    {
                        Light3D.LightCount = 0;
                        this.sceneAttached = true;
                        this.ClearColor = this.renderRenderable.BackgroundColor;                            
                        this.IsShadowMapEnabled = this.renderRenderable.IsShadowMappingEnabled;                        
                        this.RenderTechnique = this.renderRenderable.RenderTechnique == null ? Techniques.RenderBlinn : this.renderRenderable.RenderTechnique;
                            
                        if (this.renderContext != null)
                        {
                            this.renderContext.Dispose();
                        }
                        this.renderContext = new RenderContext(this, this.effects.GetEffect(this.RenderTechnique));
                        this.renderRenderable.Attach(this);
                        this.SetDefaultRenderTargets();
                        switch (this.RenderTechnique)
                        {
                            default:
                                break;
                            case Techniques.RenderDeferred:                                
                                this.deferredRenderer.CreateBuffers(this, Format.R32G32B32A32_Float);
                                break;
                            case Techniques.RenderGBuffer:
                                this.deferredRenderer.CreateBuffers(this, Format.B8G8R8A8_UNorm);
                                break;
                        }
                    }
                    catch (System.Exception ex)
                    {
                        System.Windows.MessageBox.Show("DPFCanvas: Error attaching element: " + string.Format(ex.Message), "Error");
                    }
                }

                /// ---------------------------------------------------------------------------
                /// this part is per frame                
                if (this.RenderTechnique == Techniques.RenderDeferred)
                {                  
                    /// set G-Buffer                    
                    this.deferredRenderer.SetGBufferTargets();

                    /// render G-Buffer pass                
                    this.renderRenderable.Update(this.renderTimer.Elapsed);
                    this.renderRenderable.Render(this.renderContext);

                    /// reset render targets and run lighting pass
                    this.SetDefaultRenderTargets();
                    /// set the lights                    
                    this.deferredRenderer.RenderLighting(this.renderContext, this.renderRenderable.Items.OfType<ILight3D>());                    
                }
                else if (this.RenderTechnique == Techniques.RenderGBuffer)
                {
                    /// set G-Buffer
                    this.deferredRenderer.SetGBufferTargets(targetWidth / 2, targetHeight / 2);
                    
                    /// render G-Buffer pass                    
                    this.renderRenderable.Update(this.renderTimer.Elapsed);
                    this.renderRenderable.Render(this.renderContext);

                    /// reset render targets and run lighting pass                                         
#if MSAA                    
                    this.deferredRenderer.RenderGBufferOutput(ref this.renderTargetNMS);
#else
                    this.deferredRenderer.RenderGBufferOutput(ref this.renderTarget);
#endif
                }
                else
                {
                    this.device.ImmediateContext.ClearRenderTargetView(this.renderTargetView, this.ClearColor);
                    this.device.ImmediateContext.ClearDepthStencilView(this.depthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
                    
                    this.renderRenderable.Update(this.renderTimer.Elapsed);
                    this.renderRenderable.Render(this.renderContext);
                }
            }

            this.device.ImmediateContext.Flush();
        }
Exemplo n.º 13
0
       void ICyclicBrush.RenderForCyclicBrush(DUCE.Channel channel, bool skipChannelCheck)
       {

            Visual vVisual = Visual;

            // The Visual may have been registered for an asynchronous render, but may have been
            // disconnected from the VisualBrush since then.  If so, don't bother to render here, if
            // the Visual is visible it will be rendered elsewhere.
            if (vVisual != null && vVisual.CheckFlagsAnd(VisualFlags.NodeIsCyclicBrushRoot))
            {
                // ------------------------------------------------------------------------------------
                // 1) Prepare the visual for rendering.
                //
                // Updates bounding boxes.
                //

                vVisual.Precompute();


                // ------------------------------------------------------------------------------------
                // 2) Prepare the render context.
                //

                RenderContext rc = new RenderContext();

                rc.Initialize(channel, DUCE.ResourceHandle.Null);


                // ------------------------------------------------------------------------------------
                // 3) Compile the scene.

                if (channel.IsConnected)
                {
                    vVisual.Render(rc, 0);
                }
                else
                {
                    // We can issue the release here instead of putting it in queue
                    // since we are already in Render walk.
                    ((DUCE.IResource)vVisual).ReleaseOnChannel(channel);
                }
            }

            _isAsyncRenderRegistered = false;
        }
Exemplo n.º 14
0
        /// <summary>
        ///
        /// </summary>
        internal override void RenderContent(RenderContext ctx, bool isOnChannel)
        {
            //
            // Make sure that the visual target is properly hosted.
            //

            EnsureHostedVisualConnected(ctx.Channel);
        }
Exemplo n.º 15
0
        internal void RenderRecursive(RenderContext ctx)
        {
            DUCE.Channel channel = ctx.Channel;
            DUCE.ResourceHandle handle = DUCE.ResourceHandle.Null;
            VisualProxyFlags flags = c_Model3DVisualProxyFlagsDirtyMask;
            
            //
            // Ensure that the resource for this Visual is sent to our current channel.
            //
            bool isOnChannel = IsOnChannel(channel);
            if (isOnChannel)
            {
                //
                // Good, we're already on channel. Get the handle and the flags.
                //

                handle = _proxy.GetHandle(channel);
                flags = _proxy.GetFlags(channel);
            }
            else
            {
                //
                // Create the visual resource on the current channel. 
                // 
                // Note: we need to update all set properties (the dirty 
                //       bit mask is set by default).
                //

                handle = ((DUCE.IResource)this).AddRefOnChannel(channel);
            }

            //
            // Hookup content to the Visual
            //

            if ((flags & VisualProxyFlags.IsContentDirty) != 0)
            {
                RenderContent(ctx, isOnChannel);
            }

            //
            // Update the transform.
            //

            if ((flags & VisualProxyFlags.IsTransformDirty) != 0)
            {
                Transform3D transform = Transform;
                if (transform != null && InternalIsVisible)
                {
                    //
                    // Set the new transform resource for this visual.  If transform is
                    // null we don't need to do this.  Also note that the old transform 
                    // was disconnected in the Transform property setter.
                    //

                    DUCE.Visual3DNode.SetTransform(
                        handle, 
                        ((DUCE.IResource)transform).AddRefOnChannel(channel), 
                        channel);
                }
                else if (!InternalIsVisible)
                {
                    DUCE.Visual3DNode.SetTransform(
                        handle, 
                        ((DUCE.IResource)_zeroScale).AddRefOnChannel(channel), 
                        channel);
                }
                else if (!isOnChannel) /* Transform == null */
                {
                    DUCE.Visual3DNode.SetTransform(
                        handle,
                        DUCE.ResourceHandle.Null, 
                        channel);
                }
            }

            // Visit children of this node -----------------------------------------------------------------------

            Debug.Assert((flags & VisualProxyFlags.IsContentNodeConnected) == 0,
                "Only HostVisuals are expected to have a content node.");

            for (int i = 0; i < Visual3DChildrenCount; i++)
            {
                Visual3D child = GetVisual3DChild(i);

                if (child != null)
                {
                    if (child.CheckFlagsAnd(channel, VisualProxyFlags.IsSubtreeDirtyForRender) || // or the visual is dirty
                        !(child.IsOnChannel(channel))) // or the child has not been marshalled yet.
                    {
                        child.RenderRecursive(ctx);
                    }

                    if (child.IsOnChannel(ctx.Channel))
                    {
                        if (!child.CheckFlagsAnd(channel, VisualProxyFlags.IsConnectedToParent))
                        {
                            DUCE.Visual3DNode.InsertChildAt(
                                handle,
                                ((DUCE.IResource)child).GetHandle(channel),
                                /* iPosition = */ (uint)i,
                                ctx.Channel);

                            child.SetFlags(channel, true, VisualProxyFlags.IsConnectedToParent);
                        }
                    }
                }
            }

            //
            // Finally, reset the dirty flags for this visual (at this point, 
            // we have handled them all).
            //

            SetFlags(channel, false, c_Model3DVisualProxyFlagsDirtyMask);            
        }
Exemplo n.º 16
0
        internal virtual void RenderRecursive(
            RenderContext ctx)
        {
            // Simple loop detection to avoid stack overflow in cyclic Visual
            // scenarios. This fix is only aimed at mitigating a very common
            // VisualBrush scenario.
            bool canEnter = Enter();

            if (canEnter)
            {
                try
                {
                    DUCE.Channel channel = ctx.Channel;
                    DUCE.ResourceHandle handle = DUCE.ResourceHandle.Null;
                    VisualProxyFlags flags = VisualProxyFlags.None;

                    //
                    // See if this visual is already on that channel
                    //

                    bool isOnChannel = IsOnChannel(channel);

                    //
                    // Ensure that the visual resource for this Visual
                    // is being sent to our current channel.
                    //

                    if (isOnChannel)
                    {
                        //
                        // Good, we're already on channel. Get the handle and flags.
                        //

                        handle = _proxy.GetHandle(channel);
                        flags = _proxy.GetFlags(channel);
                    }
                    else
                    {
                        //
                        // Create the visual resource on the current channel.
                        //
                        // Need to update all set properties.
                        //

                        handle = ((DUCE.IResource)this).AddRefOnChannel(channel);

                        // we need to set the Viewport3D flags, if the visual is not
                        // on channel so that the viewport sends all its resources
                        // to the compositor. we need the explicit set, because
                        // the update happens during RenderContent and we have no
                        // other way to pass the flags
                        //
                        // We do that for all visuals. the flags will be ignored
                        // if the visual is not a Viewport3D visual
                        SetFlags(channel, true, c_Viewport3DProxyFlagsDirtyMask);

                        flags = c_ProxyFlagsDirtyMask;
                    }

                    UpdateCacheMode(channel, handle, flags, isOnChannel);
                    UpdateTransform(channel, handle, flags, isOnChannel);
                    UpdateClip(channel, handle, flags, isOnChannel);
                    UpdateOffset(channel, handle, flags, isOnChannel);
                    UpdateEffect(channel, handle, flags, isOnChannel);
                    UpdateGuidelines(channel, handle, flags, isOnChannel);
                    UpdateContent(ctx, flags, isOnChannel);
                    UpdateOpacity(channel, handle, flags, isOnChannel);
                    UpdateOpacityMask(channel, handle, flags, isOnChannel);
                    UpdateRenderOptions(channel, handle, flags, isOnChannel);
                    UpdateChildren(ctx, handle);
                    UpdateScrollableAreaClip(channel, handle, flags, isOnChannel);

                    //
                    // Finally, reset the dirty flags for this visual (at this point,
                    // we have handled them all).
                    SetFlags(channel, false, VisualProxyFlags.IsSubtreeDirtyForRender);
                }
                finally
                {
                    Exit();
                }
            }
        }
Exemplo n.º 17
0
        /// <summary>
        /// RenderContent is implemented to hook up the Visual3Ds content.
        /// The implementer of this function can assert that the _hCompNode
        /// is valid on a channel when the function is executed.
        /// </summary>
        internal void RenderContent(RenderContext ctx, bool isOnChannel)
        {
            DUCE.Channel channel = ctx.Channel;

            Debug.Assert(!CheckFlagsAnd(channel, VisualProxyFlags.IsContentConnected));
            Debug.Assert(IsOnChannel(channel));

            //
            // Create the content on the channel.
            //

            if (_visual3DModel != null)
            {
                //
                // Attach the content to the visual resource
                //

                DUCE.Visual3DNode.SetContent(
                    ((DUCE.IResource)this).GetHandle(channel),
                    ((DUCE.IResource)_visual3DModel).AddRefOnChannel(channel),
                    channel);

                SetFlags(channel, true, VisualProxyFlags.IsContentConnected);
            }
            else if (isOnChannel) /* Model == null */
            {
                DUCE.Visual3DNode.SetContent(
                    ((DUCE.IResource)this).GetHandle(channel), 
                    DUCE.ResourceHandle.Null, 
                    channel);
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// If fRenderForBitmapEffect is true, the method calls special methods on visual
        /// to render it specifically for an effect to be applied to it. It excludes
        /// properties such as transform, clip, offset and guidelines.
        /// </summary>
        static internal void Render(
            IntPtr pRenderTarget,
            DUCE.Channel channel,
            Visual visual,
            int width,
            int height,
            double dpiX,
            double dpiY,
            Matrix worldTransform,
            Rect windowClip
            )
        {
            DUCE.Resource target =
                new DUCE.Resource();
            DUCE.Resource root =
                new DUCE.Resource();

            DUCE.ResourceHandle targetHandle = DUCE.ResourceHandle.Null;
            DUCE.ResourceHandle rootHandle   = DUCE.ResourceHandle.Null;

            Matrix deviceTransform = new Matrix(
                dpiX * (1.0 / 96.0), 0,
                0, dpiY * (1.0 / 96.0),
                0, 0);

            deviceTransform = worldTransform * deviceTransform;
            MatrixTransform mtDeviceTransform = new MatrixTransform(deviceTransform);

            DUCE.ResourceHandle deviceTransformHandle =
                ((DUCE.IResource)mtDeviceTransform).AddRefOnChannel(channel);


            try
            {
                // ------------------------------------------------------------
                //   Create the composition target and root visual resources.

                target.CreateOrAddRefOnChannel(target, channel, DUCE.ResourceType.TYPE_GENERICRENDERTARGET);
                targetHandle = target.Handle;

                DUCE.CompositionTarget.PrintInitialize(
                    targetHandle,
                    pRenderTarget,
                    width,
                    height,
                    channel);

                root.CreateOrAddRefOnChannel(root, channel, DUCE.ResourceType.TYPE_VISUAL);
                rootHandle = root.Handle;

                DUCE.CompositionNode.SetTransform(
                    rootHandle,
                    deviceTransformHandle,
                    channel);

                DUCE.CompositionTarget.SetRoot(
                    targetHandle,
                    rootHandle,
                    channel);

                channel.CloseBatch();
                channel.Commit();


                // ------------------------------------------------------------
                //   Render the freshly created target.

                RenderContext renderContext = new RenderContext();

                renderContext.Initialize(channel, rootHandle);

                visual.Precompute();

                visual.Render(renderContext, 0);

                // ------------------------------------------------------------
                //   Flush the channel and present the composition target.

                channel.CloseBatch();
                channel.Commit();
                channel.Present();

                MediaContext mediaContext = MediaContext.CurrentMediaContext;
                mediaContext.NotifySyncChannelMessage(channel);
            }
            finally
            {
                // ------------------------------------------------------------
                //   Clean up and release the root visual.

                if (!rootHandle.IsNull)
                {
                    DUCE.CompositionNode.RemoveAllChildren(
                        rootHandle,
                        channel);

                    ((DUCE.IResource)visual).ReleaseOnChannel(channel);

                    root.ReleaseOnChannel(channel);
                }


                // ------------------------------------------------------------
                //   Release the world transform.

                if (!deviceTransformHandle.IsNull)
                {
                    ((DUCE.IResource)mtDeviceTransform).ReleaseOnChannel(channel);
                }


                // ------------------------------------------------------------
                //   Clean up and release the composition target.

                if (!targetHandle.IsNull)
                {
                    DUCE.CompositionTarget.SetRoot(
                        targetHandle,
                        DUCE.ResourceHandle.Null,
                        channel);

                    target.ReleaseOnChannel(channel);
                }

                // ------------------------------------------------------------
                //   Flush the channel and present the composition target.

                channel.CloseBatch();
                channel.Commit();
                channel.Present();

                MediaContext mediaContext = MediaContext.CurrentMediaContext;
                mediaContext.NotifySyncChannelMessage(channel);
            }
        }