protected override void OnRender(RenderContext context, DeviceContextProxy deviceContext) { var buffer = context.RenderHost.RenderBuffer; #region Initialize textures if (offScreenRenderTargets.Count == 0 || width != (int)(context.ActualWidth) || height != (int)(context.ActualHeight)) { width = (int)(context.ActualWidth); height = (int)(context.ActualHeight); for (int i = 0; i < offScreenRenderTargets.Count; ++i) { var target = offScreenRenderTargets[i]; RemoveAndDispose(ref target); } offScreenRenderTargets.Clear(); int w = width; int h = height; int count = 0; while (w > 1 && h > 1 && count < Math.Max(0, MaximumDownSamplingStep) + 1) { var target = Collect(new PostEffectBlurCore(global::SharpDX.DXGI.Format.B8G8R8A8_UNorm, blurPassVertical, blurPassHorizontal, textureSlot, samplerSlot, DefaultSamplers.LinearSamplerClampAni1, EffectTechnique.EffectsManager)); target.Resize(Device, w, h); offScreenRenderTargets.Add(target); w >>= 2; h >>= 2; ++count; } //Skip this frame to avoid performance hit due to texture creation InvalidateRenderer(); return; } #endregion #region Render objects onto offscreen texture using (var resource2 = offScreenRenderTargets[0].CurrentRTV.Resource) { deviceContext.CopyResource(buffer.FullResPPBuffer.CurrentTexture, resource2); } #endregion #region Do Bloom Pass modelCB.Upload(deviceContext, ref modelStruct); //Extract bloom samples BindTarget(null, offScreenRenderTargets[0].NextRTV, deviceContext, offScreenRenderTargets[0].Width, offScreenRenderTargets[0].Height, false); screenQuadPass.PixelShader.BindTexture(deviceContext, textureSlot, offScreenRenderTargets[0].CurrentSRV); screenQuadPass.PixelShader.BindSampler(deviceContext, samplerSlot, sampler); screenQuadPass.BindShader(deviceContext); screenQuadPass.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState); deviceContext.Draw(4, 0); offScreenRenderTargets[0].SwapTargets(); // Down sampling screenQuadCopy.BindShader(deviceContext); screenQuadCopy.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState); for (int i = 1; i < offScreenRenderTargets.Count; ++i) { BindTarget(null, offScreenRenderTargets[i].CurrentRTV, deviceContext, offScreenRenderTargets[i].Width, offScreenRenderTargets[i].Height, false); screenQuadCopy.PixelShader.BindTexture(deviceContext, textureSlot, offScreenRenderTargets[i - 1].CurrentSRV); deviceContext.Draw(4, 0); } for (int i = offScreenRenderTargets.Count - 1; i >= 1; --i) { //Run blur pass offScreenRenderTargets[i].Run(deviceContext, NumberOfBlurPass); //Up sampling screenOutlinePass.BindShader(deviceContext); screenOutlinePass.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState); BindTarget(null, offScreenRenderTargets[i - 1].CurrentRTV, deviceContext, offScreenRenderTargets[i - 1].Width, offScreenRenderTargets[i - 1].Height, false); screenOutlinePass.PixelShader.BindTexture(deviceContext, textureSlot, offScreenRenderTargets[i].CurrentSRV); deviceContext.Draw(4, 0); } offScreenRenderTargets[0].Run(deviceContext, NumberOfBlurPass); #endregion #region Draw outline onto original target BindTarget(null, buffer.FullResPPBuffer.CurrentRTV, deviceContext, buffer.TargetWidth, buffer.TargetHeight, false); screenOutlinePass.PixelShader.BindTexture(deviceContext, textureSlot, offScreenRenderTargets[0].CurrentSRV); screenOutlinePass.BindShader(deviceContext); screenOutlinePass.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState); deviceContext.Draw(4, 0); screenOutlinePass.PixelShader.BindTexture(deviceContext, textureSlot, null); #endregion }
/// <summary> /// Set model default raster state /// </summary> /// <param name="context"></param> /// <param name="isInvertCullMode"></param> protected virtual void OnBindRasterState(DeviceContextProxy context, bool isInvertCullMode) { }
/// <summary> /// Only used for running compute shader such as in particle system. /// </summary> /// <param name="context"></param> /// <param name="deviceContext"></param> protected virtual void OnUpdate(RenderContext context, DeviceContextProxy deviceContext) { }
/// <summary> /// Called when [create index buffer]. /// </summary> /// <param name="context">The context.</param> /// <param name="buffer">The buffer.</param> /// <param name="geometry">The geometry.</param> /// <param name="deviceResources">The device resources.</param> protected override void OnCreateIndexBuffer(DeviceContextProxy context, IElementsBufferProxy buffer, Geometry3D geometry, IDeviceResources deviceResources) { }
private bool CreateTextureResources(RenderContext context, DeviceContextProxy deviceContext) { var currSampleDesc = context.RenderHost.RenderBuffer.ColorBufferSampleDesc; #if MSAASEPARATE hasMSAA = currSampleDesc.Count > 1 || currSampleDesc.Quality > 0; #endif if (width != (int)context.ActualWidth || height != (int)context.ActualHeight || sampleDesc.Count != currSampleDesc.Count || sampleDesc.Quality != currSampleDesc.Quality) { RemoveAndDispose(ref colorTarget); RemoveAndDispose(ref alphaTarget); RemoveAndDispose(ref colorTargetNoMSAA); RemoveAndDispose(ref alphaTargetNoMSAA); sampleDesc = currSampleDesc; width = (int)context.ActualWidth; height = (int)context.ActualHeight; colorDesc.Width = alphaDesc.Width = width; colorDesc.Height = alphaDesc.Height = height; colorDesc.SampleDescription = alphaDesc.SampleDescription = sampleDesc; #if MSAASEPARATE if (hasMSAA) { colorDesc.BindFlags = alphaDesc.BindFlags = BindFlags.RenderTarget; } else #endif { colorDesc.BindFlags = alphaDesc.BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource; } colorTarget = new ShaderResourceViewProxy(Device, colorDesc); alphaTarget = new ShaderResourceViewProxy(Device, alphaDesc); colorTarget.CreateRenderTargetView(); alphaTarget.CreateRenderTargetView(); #if MSAASEPARATE if (!hasMSAA) #endif { alphaTarget.CreateTextureView(); colorTarget.CreateTextureView(); colorTargetNoMSAA = colorTarget; alphaTargetNoMSAA = alphaTarget; } #if MSAASEPARATE else { colorDesc.SampleDescription = alphaDesc.SampleDescription = new SampleDescription(1, 0); colorDesc.BindFlags = alphaDesc.BindFlags = BindFlags.ShaderResource; colorTargetNoMSAA = new ShaderResourceViewProxy(Device, colorDesc); alphaTargetNoMSAA = new ShaderResourceViewProxy(Device, alphaDesc); colorTargetNoMSAA.CreateTextureView(); alphaTargetNoMSAA.CreateTextureView(); } #endif RaiseInvalidateRender(); return(true); // Skip this frame if texture resized to reduce latency. } return(false); }
public override void Render(RenderContext context, DeviceContextProxy deviceContext) { if (Buffer == null || TextureView == null || spritePass.IsNULL) { return; } var io = ImGui.GetIO(); ImGui.Render(); if (!UpdateBuffer(deviceContext)) { return; } ProjectionMatrix = Matrix.OrthoOffCenterRH( 0f, io.DisplaySize.X / context.DpiScale, io.DisplaySize.Y / context.DpiScale, 0.0f, -1.0f, 1.0f); int slot = 0; if (!Buffer.AttachBuffers(deviceContext, ref slot, EffectTechnique.EffectsManager)) { return; } var globalTrans = context.GlobalTransform; globalTrans.Projection = ProjectionMatrix; globalTransformCB.Upload(deviceContext, ref globalTrans); spritePass.BindShader(deviceContext); spritePass.BindStates(deviceContext, StateType.All); spritePass.PixelShader.BindTexture(deviceContext, texSlot, TextureView); spritePass.PixelShader.BindSampler(deviceContext, samplerSlot, sampler); deviceContext.SetViewport(0, 0, io.DisplaySize.X, io.DisplaySize.Y); #region Render unsafe { var draw_data = ImGui.GetDrawData(); draw_data.ScaleClipRects(new System.Numerics.Vector2(context.DpiScale, context.DpiScale)); int idx_offset = 0; int vtx_offset = 0; for (int n = 0; n < draw_data.CmdListsCount; n++) { var cmd_list = draw_data.CmdListsRange[n]; for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { var pcmd = &(((ImDrawCmd *)cmd_list.CmdBuffer.Data)[cmd_i]); if (pcmd->UserCallback != IntPtr.Zero) { } else { deviceContext.SetScissorRectangle( (int)pcmd->ClipRect.X, (int)pcmd->ClipRect.Y, (int)(pcmd->ClipRect.Z), (int)(pcmd->ClipRect.W)); deviceContext.DrawIndexed((int)pcmd->ElemCount, idx_offset, vtx_offset); } idx_offset += (int)pcmd->ElemCount; } vtx_offset += cmd_list.VtxBuffer.Size; } #endregion } RaiseInvalidateRender(); }
/// <summary> /// Render routine /// </summary> /// <param name="context"></param> /// <param name="deviceContext"></param> public abstract void Render(IRenderContext context, DeviceContextProxy deviceContext);
/// <summary> /// Called when [render]. /// </summary> /// <param name="context">The context.</param> /// <param name="deviceContext">The device context.</param> protected override void OnRender(IRenderContext context, DeviceContextProxy deviceContext) { context.IsCustomPass = true; if (DoublePass) { deviceContext.DeviceContext.ClearDepthStencilView(context.RenderHost.DepthStencilBufferView, DepthStencilClearFlags.Stencil, 0, 0); currentCores.Clear(); for (int i = 0; i < context.RenderHost.PerFrameGeneralCoresWithPostEffect.Count; ++i) { IEffectAttributes effect; var mesh = context.RenderHost.PerFrameGeneralCoresWithPostEffect[i]; if (mesh.TryGetPostEffect(EffectName, out effect)) { currentCores.Add(new KeyValuePair <RenderCore, IEffectAttributes>(mesh, effect)); context.CustomPassName = DefaultPassNames.EffectMeshXRayP1; var pass = mesh.EffectTechnique[DefaultPassNames.EffectMeshXRayP1]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState); deviceContext.SetDepthStencilState(pass.DepthStencilState, 0);//Increment the stencil value mesh.Render(context, deviceContext); } } for (int i = 0; i < currentCores.Count; ++i) { var mesh = currentCores[i]; IEffectAttributes effect = mesh.Value; object attribute; var color = Color; if (effect.TryGetAttribute(EffectAttributeNames.ColorAttributeName, out attribute) && attribute is string colorStr) { color = colorStr.ToColor4(); } if (modelStruct.Color != color) { modelStruct.Color = color; OnUploadPerModelConstantBuffers(deviceContext); } context.CustomPassName = DefaultPassNames.EffectMeshXRayP2; var pass = mesh.Key.EffectTechnique[DefaultPassNames.EffectMeshXRayP2]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState); deviceContext.SetDepthStencilState(pass.DepthStencilState, 1);//Do stencil test only on value = 1. mesh.Key.Render(context, deviceContext); } currentCores.Clear(); } else { for (int i = 0; i < context.RenderHost.PerFrameGeneralCoresWithPostEffect.Count; ++i) { IEffectAttributes effect; var mesh = context.RenderHost.PerFrameGeneralCoresWithPostEffect[i]; if (mesh.TryGetPostEffect(EffectName, out effect)) { object attribute; var color = Color; if (effect.TryGetAttribute(EffectAttributeNames.ColorAttributeName, out attribute) && attribute is string colorStr) { color = colorStr.ToColor4(); } if (modelStruct.Color != color) { modelStruct.Color = color; OnUploadPerModelConstantBuffers(deviceContext); } context.CustomPassName = DefaultPassNames.EffectMeshXRayP2; var pass = mesh.EffectTechnique[DefaultPassNames.EffectMeshXRayP2]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState); deviceContext.SetDepthStencilState(pass.DepthStencilState, 0); mesh.Render(context, deviceContext); } } } context.IsCustomPass = false; }
public override void Draw(DeviceContextProxy deviceContext, IAttachableBufferModel bufferModel, int instanceCount) { DrawIndexed(deviceContext, bufferModel.IndexBuffer.ElementCount, instanceCount); }
protected override void OnRenderShadow(RenderContext context, DeviceContextProxy deviceContext) { }
protected override void OnRenderCustom(RenderContext context, DeviceContextProxy deviceContext, ShaderPass shaderPass) { BindBillboardTexture(deviceContext, DefaultShaderPass.PixelShader); base.OnRenderCustom(context, deviceContext, shaderPass); }
public sealed override void RenderCustom(RenderContext context, DeviceContextProxy deviceContext) { }
public sealed override void RenderShadow(RenderContext context, DeviceContextProxy deviceContext) { }
private static void BindTarget(DepthStencilView dsv, RenderTargetView targetView, DeviceContextProxy context, int width, int height, bool clear = true) { if (clear) { context.ClearRenderTargetView(targetView, global::SharpDX.Color.Transparent); } context.SetRenderTargets(dsv, new RenderTargetView[] { targetView }); context.SetViewport(0, 0, width, height); context.SetScissorRectangle(0, 0, width, height); }
/// <summary> /// Sets the screen spaced coordinates. /// </summary> /// <param name="context">The context.</param> /// <param name="deviceContext">The device context.</param> public void SetScreenSpacedCoordinates(RenderContext context, DeviceContextProxy deviceContext) { SetScreenSpacedCoordinates(context, deviceContext, true); }
/// <summary> /// Puts the specified context back to the pool after use /// </summary> /// <param name="context">The context.</param> public void Put(DeviceContextProxy context) { contextPool.Add(context); }
public override void Render(RenderContext context, DeviceContextProxy deviceContext) { if (!enableReflector) { return; } if (CreateCubeMapResources()) { RaiseInvalidateRender(); return; // Skip this frame if texture resized to reduce latency. } else if (!(IsDynamicScene || context.UpdateSceneGraphRequested || context.UpdatePerFrameRenderableRequested)) { return; } context.IsInvertCullMode = true; var camLook = Vector3.Normalize(context.Camera.LookDirection); Exception exception = null; #if TEST for (int index = 0; index < 6; ++index) #else Parallel.For(0, 6, (index) => #endif { try { var ctx = contextPool.Get(); ctx.ClearRenderTargetView(cubeRTVs[index], context.RenderHost.ClearColor); ctx.ClearDepthStencilView(cubeDSVs[index], DepthStencilClearFlags.Depth, 1, 0); ctx.SetRenderTarget(cubeDSVs[index], cubeRTVs[index]); ctx.SetViewport(ref viewport); ctx.SetScissorRectangle(0, 0, FaceSize, FaceSize); var transforms = new GlobalTransformStruct(); transforms.Projection = cubeFaceCameras.Cameras[index].Projection; transforms.View = cubeFaceCameras.Cameras[index].View; transforms.Viewport = new Vector4(FaceSize, FaceSize, 1 / FaceSize, 1 / FaceSize); transforms.ViewProjection = transforms.View * transforms.Projection; modelCB.Upload(ctx, ref transforms); var frustum = new BoundingFrustum(transforms.ViewProjection); //Render opaque for (var i = 0; i < context.RenderHost.PerFrameOpaqueNodes.Count; ++i) { var node = context.RenderHost.PerFrameOpaqueNodes[i]; if (node.GUID != this.GUID && !IgnoredGuid.Contains(node.GUID) && node.TestViewFrustum(ref frustum)) { node.Render(context, ctx); } } //Render particle for (var i = 0; i < context.RenderHost.PerFrameParticleNodes.Count; ++i) { var node = context.RenderHost.PerFrameParticleNodes[i]; if (node.GUID != this.GUID && !IgnoredGuid.Contains(node.GUID) && node.TestViewFrustum(ref frustum)) { node.Render(context, ctx); } } commands[index] = ctx.FinishCommandList(true); contextPool.Put(ctx); } catch (Exception ex) { exception = ex; } } #if !TEST ); #endif context.IsInvertCullMode = false; if (exception != null) { throw exception; } for (var i = 0; i < commands.Length; ++i) { if (commands[i] != null) { Device.ImmediateContext.ExecuteCommandList(commands[i], true); Disposer.RemoveAndDispose(ref commands[i]); } } deviceContext.GenerateMips(CubeMap); context.UpdatePerFrameData(true, false, deviceContext); }
/// <summary> /// Called when [bind raster state]. /// </summary> /// <param name="context">The context.</param> /// <param name="isInvertCullMode"></param> protected override void OnBindRasterState(DeviceContextProxy context, bool isInvertCullMode) { context.SetRasterState(rasterState); }
public bool UpdateBuffers(DeviceContextProxy context, IDeviceResources deviceResources) { return(true); }
/// <summary> /// Called when [render]. /// </summary> /// <param name="renderContext">The render context.</param> /// <param name="deviceContext">The device context.</param> protected override void OnRender(RenderContext renderContext, DeviceContextProxy deviceContext) { SetScreenSpacedCoordinates(renderContext, deviceContext); }
/// <summary> /// Update routine. Only used to run update computation such as compute shader in particle system. /// <para>Compute shader can be run at the beginning of any other <see cref="Render(IRenderContext, DeviceContextProxy)"/> routine to avoid waiting.</para> /// </summary> /// <param name="context"></param> /// <param name="deviceContext"></param> public virtual void Update(IRenderContext context, DeviceContextProxy deviceContext) { }
/// <summary> /// Called when [render]. /// </summary> /// <param name="context">The context.</param> /// <param name="deviceContext">The device context.</param> public override void Render(RenderContext context, DeviceContextProxy deviceContext) { var succ = duplicationResource.Initialize(); if (!succ) { RaiseInvalidateRender(); return; } context.RenderHost.RenderConfiguration = config; if (duplicationResource.GetFrame(Output, out var data, ref pointer, out var isTimeOut, out var accessLost)) { if (data.FrameInfo.TotalMetadataBufferSize > 0) { frameProcessor.ProcessFrame(ref data, deviceContext); } invalidRender = true; } if (frameProcessor.SharedTexture != null && !accessLost) { if (clearTarget) { clearTarget = false; context.RenderHost.ClearRenderTarget(deviceContext, true, false); } var cursorValid = false; if (pointer.Visible) { if (frameProcessor.ProcessCursor(ref pointer, deviceContext, out var rect)) { GetCursorVertexBound((int)context.ActualWidth, (int)context.ActualHeight, frameProcessor.TextureWidth, frameProcessor.TextureHeight, ref rect); invalidRender = true; cursorValid = true; } } if (invalidRender) { OnUpdatePerModelStruct(context); modelCB.Upload(deviceContext, ref modelStruct); DefaultShaderPass.BindShader(deviceContext); DefaultShaderPass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState | StateType.RasterState); DefaultShaderPass.PixelShader.BindSampler(deviceContext, samplerBindSlot, textureSampler); var left = (int)(context.ActualWidth * Math.Abs(modelStruct.TopLeft.X + 1) / 2); var top = (int)(context.ActualHeight * Math.Abs(modelStruct.TopLeft.Y - 1) / 2); deviceContext.SetScissorRectangle(left, top, (int)context.ActualWidth - left, (int)context.ActualHeight - top); using (var textureView = new global::SharpDX.Direct3D11.ShaderResourceView(deviceContext, frameProcessor.SharedTexture)) { deviceContext.SetShaderResource(PixelShader.Type, textureBindSlot, textureView); deviceContext.Draw(4, 0); } if (ShowMouseCursor && cursorValid) { DrawCursor(ref pointer, deviceContext); } invalidRender = false; } } if (isTimeOut) { } else if (accessLost) { throw new SharpDXException(ResultCode.AccessLost); } else { duplicationResource.ReleaseFrame(); } RaiseInvalidateRender(); }
public void BindShader(DeviceContextProxy context, bool bindConstantBuffer = true) { context.SetShaderPass(this, bindConstantBuffer); }
public bool ProcessCursor(ref PointerInfo pointer, DeviceContextProxy context, out Vector4 rect) { var width = 0; var height = 0; var left = pointer.Position.X; var top = pointer.Position.Y; switch (pointer.ShapeInfo.Type) { case (int)OutputDuplicatePointerShapeType.Color: width = pointer.ShapeInfo.Width; height = pointer.ShapeInfo.Height; break; case (int)OutputDuplicatePointerShapeType.Monochrome: ProcessMonoMask(context, true, ref pointer, out width, out height, out left, out top); break; case (int)OutputDuplicatePointerShapeType.MaskedColor: ProcessMonoMask(context, false, ref pointer, out width, out height, out left, out top); break; default: rect = Vector4.Zero; //Invalid cursor type return(false); } rect = new Vector4(pointer.Position.X, pointer.Position.Y, width, height); var rowPitch = pointer.ShapeInfo.Type == (int)OutputDuplicatePointerShapeType.Color ? pointer.ShapeInfo.Pitch : width * BPP; var slicePitch = 0; if (pointerResource == null || currentType != pointer.ShapeInfo.Type || pointerTexDesc.Width != width || pointerTexDesc.Height != height) { RemoveAndDispose(ref pointerResource); pointerTexDesc.Width = width; pointerTexDesc.Height = height; currentType = pointer.ShapeInfo.Type; global::SharpDX.Utilities.Pin(pointer.ShapeInfo.Type == (int)OutputDuplicatePointerShapeType.Color ? pointer.PtrShapeBuffer : initBuffer, ptr => { pointerResource = new ShaderResourceViewProxy(context, new Texture2D(context, pointerTexDesc, new[] { new DataBox(ptr, rowPitch, slicePitch) })); }); pointerResource.CreateView(pointerSRVDesc); #if OUTPUTDETAIL Console.WriteLine("Create new cursor texture. Type = " + pointer.ShapeInfo.Type); #endif } else { var dataBox = context.MapSubresource(pointerResource.Resource, 0, global::SharpDX.Direct3D11.MapMode.WriteDiscard, global::SharpDX.Direct3D11.MapFlags.None); if (pointer.ShapeInfo.Type == (int)OutputDuplicatePointerShapeType.Color) { #if OUTPUTDETAIL Console.WriteLine("Reuse existing cursor texture for Color."); #endif unsafe { var row = pointer.ShapeInfo.Height; var sourceCounter = 0; var target32 = (byte *)dataBox.DataPointer; for (var i = 0; i < row; ++i) { var targetCounter = i * dataBox.RowPitch; for (var j = 0; j < pointer.ShapeInfo.Pitch; ++j) { target32[targetCounter++] = pointer.PtrShapeBuffer[sourceCounter++]; } } } } else { #if OUTPUTDETAIL Console.WriteLine("Reuse existing cursor texture for Mono and Mask."); #endif unsafe // Call unmanaged code { var target32 = (byte *)dataBox.DataPointer; for (var i = 0; i < initBuffer.Length; ++i) { target32[i] = initBuffer[i]; } } } context.UnmapSubresource(pointerResource.Resource, 0); } return(true); }
/// <summary> /// Called when [render shadow]. /// </summary> /// <param name="context">The context.</param> /// <param name="deviceContext"></param> protected virtual void OnRenderShadow(RenderContext context, DeviceContextProxy deviceContext) { }
private void ProcessMonoMask(DeviceContextProxy context, bool isMono, ref PointerInfo info, out int width, out int height, out int left, out int top) { var deskWidth = sharedDescription.Width; var deskHeight = sharedDescription.Height; var givenLeft = info.Position.X; var givenTop = info.Position.Y; if (givenLeft < 0) { width = givenLeft + info.ShapeInfo.Width; } else if (givenLeft + info.ShapeInfo.Width > deskWidth) { width = deskWidth - givenLeft; } else { width = info.ShapeInfo.Width; } if (isMono) { info.ShapeInfo.Height /= 2; } if (givenTop < 0) { height = givenTop + info.ShapeInfo.Height; } else if (givenTop + info.ShapeInfo.Height > deskHeight) { height = deskHeight - givenTop; } else { height = info.ShapeInfo.Height; } if (isMono) { info.ShapeInfo.Height *= 2; } left = givenLeft < 0 ? 0 : givenLeft; top = givenTop < 0 ? 0 : givenTop; stageTextureDesc.Width = width; stageTextureDesc.Height = height; if (initBuffer.Length != width * height * BPP) { initBuffer = new byte[width * height * BPP]; } if (copyBuffer == null || stageTextureDesc.Width != width || stageTextureDesc.Height != height) { RemoveAndDispose(ref copyBuffer); copyBuffer = new Texture2D(context, stageTextureDesc); } context.CopySubresourceRegion(SharedTexture, 0, new global::SharpDX.Direct3D11.ResourceRegion(left, top, 0, left + width, top + height, 1), copyBuffer, 0); var dataBox = context.MapSubresource(copyBuffer, 0, global::SharpDX.Direct3D11.MapMode.Read, global::SharpDX.Direct3D11.MapFlags.None); #region process unsafe // Call unmanaged code { fixed(byte *initBufferPtr = initBuffer) { var initBuffer32 = (uint *)initBufferPtr; var desktop32 = (uint *)dataBox.DataPointer; var desktopPitchInPixels = dataBox.RowPitch / sizeof(int); var skipX = (givenLeft < 0) ? (uint)(-1 * givenLeft) : 0; var skipY = (givenTop < 0) ? (uint)(-1 * givenTop) : 0; if (isMono) { for (var row = 0; row < stageTextureDesc.Height; ++row) { // Set mask byte Mask = 0x80; Mask = (byte)(Mask >> (byte)(skipX % 8)); for (var col = 0; col < stageTextureDesc.Width; ++col) { // Get masks using appropriate offsets var AndMask = (byte)(info.PtrShapeBuffer[((col + skipX) / 8) + ((row + skipY) * (info.ShapeInfo.Pitch))] & Mask); var XorMask = (byte)(info.PtrShapeBuffer[((col + skipX) / 8) + ((row + skipY + (info.ShapeInfo.Height / 2)) * (info.ShapeInfo.Pitch))] & Mask); var AndMask32 = (AndMask > 0) ? 0xFFFFFFFF : 0xFF000000; var XorMask32 = (XorMask > 0) ? (uint)0x00FFFFFF : 0x00000000; // Set new pixel initBuffer32[(row * stageTextureDesc.Width) + col] = (desktop32[(row * desktopPitchInPixels) + col] & AndMask32) ^ XorMask32; // Adjust mask if (Mask == 0x01) { Mask = 0x80; } else { Mask = (byte)(Mask >> 1); } } } } else { fixed(byte *shapeBufferPtr = info.PtrShapeBuffer) { var Buffer32 = (uint *)shapeBufferPtr; // Iterate through pixels for (var row = 0; row < stageTextureDesc.Height; ++row) { for (var col = 0; col < stageTextureDesc.Width; ++col) { // Set up mask var MaskVal = 0xFF000000 & Buffer32[(col + skipX) + ((row + skipY) * (info.ShapeInfo.Pitch / sizeof(uint)))]; if (MaskVal > 0) { // Mask was 0xFF initBuffer32[(row * stageTextureDesc.Width) + col] = (desktop32[(row * desktopPitchInPixels) + col] ^ Buffer32[(col + skipX) + ((row + skipY) * (info.ShapeInfo.Pitch / sizeof(uint)))]) | 0xFF000000; } else { // Mask was 0x00 initBuffer32[(row * stageTextureDesc.Width) + col] = Buffer32[(col + skipX) + ((row + skipY) * (info.ShapeInfo.Pitch / sizeof(uint)))] | 0xFF000000; } } } } } } } #endregion context.UnmapSubresource(copyBuffer, 0); }
/// <summary> /// Actual render function. Used to attach different render states and call the draw call. /// </summary> protected abstract void OnRender(RenderContext context, DeviceContextProxy deviceContext);
/// <summary> /// Called when [render]. /// </summary> /// <param name="renderContext">The render context.</param> /// <param name="deviceContext">The device context.</param> public override void Render(RenderContext renderContext, DeviceContextProxy deviceContext) { SetScreenSpacedCoordinates(renderContext, deviceContext); }
/// <summary> /// Render function for custom shader pass. Used to do special effects /// </summary> protected virtual void OnRenderCustom(RenderContext context, DeviceContextProxy deviceContext, ShaderPass shaderPass) { }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="shader"></param> /// <returns></returns> public bool BindMaterialTextures(DeviceContextProxy context, ShaderPass shader) { return(MaterialVariables.BindMaterialTextures(context, shader)); }