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(); }
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); }
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); } }
/// <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); }
/// <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 */ }
/// <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); } }
/// <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); } }
/// <summary> /// Renders the scene. /// </summary> void IRenderable.Render(RenderContext context) { context.Camera = this.Camera; foreach (Element3D e in this.Items) { e.Render(context); } }
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); } }
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; }
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); } } } } } }
/// <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(); }
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; }
/// <summary> /// /// </summary> internal override void RenderContent(RenderContext ctx, bool isOnChannel) { // // Make sure that the visual target is properly hosted. // EnsureHostedVisualConnected(ctx.Channel); }
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); }
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(); } } }
/// <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); } }
/// <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); } }