예제 #1
0
        private void RestoreRenderState(ref StateBackup oldState)
        {
            // IA
            _deviceContext.InputAssembler.InputLayout = oldState.InputLayout;
            _deviceContext.InputAssembler.SetIndexBuffer(oldState.IndexBuffer, oldState.IndexBufferFormat, oldState.IndexBufferOffset);
            _deviceContext.InputAssembler.PrimitiveTopology = oldState.PrimitiveTopology;
            _deviceContext.InputAssembler.SetVertexBuffers(0, oldState.VertexBuffers, oldState.VertexBufferStrides, oldState.VertexBufferOffsets);

            // RS
            _deviceContext.Rasterizer.State = oldState.RS;
            _deviceContext.Rasterizer.SetScissorRectangles(oldState.ScissorRects);
            _deviceContext.Rasterizer.SetViewports(oldState.Viewports, oldState.Viewports.Length);

            // OM
            _deviceContext.OutputMerger.SetBlendState(oldState.BlendState, oldState.BlendFactor, oldState.SampleMask);
            _deviceContext.OutputMerger.SetDepthStencilState(oldState.DepthStencilState, oldState.DepthStencilRef);
            _deviceContext.OutputMerger.SetRenderTargets(oldState.DepthStencilView, oldState.RenderTargetViews);

            // VS
            _deviceContext.VertexShader.Set(oldState.VS);
            _deviceContext.VertexShader.SetSamplers(0, oldState.VSSamplers);
            _deviceContext.VertexShader.SetConstantBuffers(0, oldState.VSConstantBuffers);
            _deviceContext.VertexShader.SetShaderResources(0, oldState.VSResourceViews);

            // HS
            _deviceContext.HullShader.Set(oldState.HS);
            _deviceContext.HullShader.SetSamplers(0, oldState.HSSamplers);
            _deviceContext.HullShader.SetConstantBuffers(0, oldState.HSConstantBuffers);
            _deviceContext.HullShader.SetShaderResources(0, oldState.HSResourceViews);

            // DS
            _deviceContext.DomainShader.Set(oldState.DS);
            _deviceContext.DomainShader.SetSamplers(0, oldState.DSSamplers);
            _deviceContext.DomainShader.SetConstantBuffers(0, oldState.DSConstantBuffers);
            _deviceContext.DomainShader.SetShaderResources(0, oldState.DSResourceViews);

            // GS
            _deviceContext.GeometryShader.Set(oldState.GS);
            _deviceContext.GeometryShader.SetSamplers(0, oldState.GSSamplers);
            _deviceContext.GeometryShader.SetConstantBuffers(0, oldState.GSConstantBuffers);
            _deviceContext.GeometryShader.SetShaderResources(0, oldState.GSResourceViews);

            // PS
            _deviceContext.PixelShader.Set(oldState.PS);
            _deviceContext.PixelShader.SetSamplers(0, oldState.PSSamplers);
            _deviceContext.PixelShader.SetConstantBuffers(0, oldState.PSConstantBuffers);
            _deviceContext.PixelShader.SetShaderResources(0, oldState.PSResourceViews);

            // CS
            _deviceContext.ComputeShader.Set(oldState.CS);
            _deviceContext.ComputeShader.SetSamplers(0, oldState.CSSamplers);
            _deviceContext.ComputeShader.SetConstantBuffers(0, oldState.CSConstantBuffers);
            _deviceContext.ComputeShader.SetShaderResources(0, oldState.CSResourceViews);
            _deviceContext.ComputeShader.SetUnorderedAccessViews(0, oldState.CSUAVs);
        }
예제 #2
0
 public void CancelMenu()
 {
     if (menuStack.Count > 0)
     {
         ResetComponents();
         StateBackup backup = menuStack.Pop();
         menu  = backup.menu;
         State = backup.state;
         for (int i = 0; i < backup.components.Count; i++)
         {
             Components.Add(backup.components[i]);
         }
     }
 }
예제 #3
0
        public void StoreState()
        {
            StateBackup backup = new StateBackup();

            backup.menu       = menu;
            backup.components = new GameComponentCollection();
            backup.state      = State;
            foreach (GameComponent gc in Components)
            {
                if (!(gc is InputManager) && !(gc is Plugin))
                {
                    backup.components.Add(gc);
                }
            }
            menuStack.Push(backup);
        }
예제 #4
0
        public void RestoreState()
        {
            if (this.backup is null || this.backup.First is null)
            {
                throw new Exception("No state backup to restore.");
            }

            StateBackup Backup = this.backup.First.Value;

            this.backup.RemoveFirst();

            this.pos            = Backup.Pos;
            this.len            = Backup.Len;
            this.current        = Backup.Current;
            this.currentRow     = Backup.CurrentRow;
            this.lineBreakAfter = Backup.LineBreakAfter;
        }
예제 #5
0
        public void BackupState()
        {
            StateBackup Backup = new StateBackup();

            Backup.Pos            = this.pos;
            Backup.Len            = this.len;
            Backup.Current        = this.current;
            Backup.CurrentRow     = this.currentRow;
            Backup.LineBreakAfter = this.lineBreakAfter;

            if (this.backup == null)
            {
                this.backup = new LinkedList <StateBackup>();
            }

            this.backup.AddFirst(Backup);
        }
예제 #6
0
        public void BackupState()
        {
            StateBackup Backup = new StateBackup()
            {
                Pos            = this.pos,
                Len            = this.len,
                Current        = this.current,
                CurrentRow     = this.currentRow,
                LineBreakAfter = this.lineBreakAfter
            };

            if (this.backup is null)
            {
                this.backup = new LinkedList <StateBackup>();
            }

            this.backup.AddFirst(Backup);
        }
예제 #7
0
        public void RenderDrawData(ImDrawDataPtr drawData)
        {
            // Avoid rendering when minimized
            if (drawData.DisplaySize.X <= 0 || drawData.DisplaySize.Y <= 0)
            {
                return;
            }

            if (!drawData.Valid || drawData.CmdListsCount == 0)
            {
                return;
            }

            // drawData.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale);

            // Create and grow vertex/index buffers if needed
            if (_vertexBuffer == null || _vertexBufferSize < drawData.TotalVtxCount)
            {
                _vertexBuffer?.Dispose();
                _vertexBufferSize = drawData.TotalVtxCount + 5000;

                _vertexBuffer = new Buffer(_device, new BufferDescription
                {
                    Usage          = ResourceUsage.Dynamic,
                    SizeInBytes    = Unsafe.SizeOf <ImDrawVert>() * _vertexBufferSize,
                    BindFlags      = BindFlags.VertexBuffer,
                    CpuAccessFlags = CpuAccessFlags.Write,
                    OptionFlags    = ResourceOptionFlags.None
                });

                // (Re)make this here rather than every frame
                _vertexBinding = new VertexBufferBinding
                {
                    Buffer = _vertexBuffer,
                    Stride = Unsafe.SizeOf <ImDrawVert>(),
                    Offset = 0
                };
            }

            if (_indexBuffer == null || _indexBufferSize < drawData.TotalIdxCount)
            {
                _indexBuffer?.Dispose();
                _indexBufferSize = drawData.TotalIdxCount + 10000;

                _indexBuffer = new Buffer(_device, new BufferDescription
                {
                    Usage          = ResourceUsage.Dynamic,
                    SizeInBytes    = sizeof(ushort) * _indexBufferSize, // ImGui.NET doesn't provide an ImDrawIdx, but their sample uses ushort
                    BindFlags      = BindFlags.IndexBuffer,
                    CpuAccessFlags = CpuAccessFlags.Write
                });
            }

            // Upload vertex/index data into a single contiguous GPU buffer
            int vertexOffset = 0, indexOffset = 0;
            var vertexData = _deviceContext.MapSubresource(_vertexBuffer, 0, MapMode.WriteDiscard, MapFlags.None).DataPointer;
            var indexData  = _deviceContext.MapSubresource(_indexBuffer, 0, MapMode.WriteDiscard, MapFlags.None).DataPointer;

            for (int n = 0; n < drawData.CmdListsCount; n++)
            {
                var cmdList = drawData.CmdListsRange[n];
                unsafe
                {
                    System.Buffer.MemoryCopy(cmdList.VtxBuffer.Data.ToPointer(),
                                             (ImDrawVert *)vertexData + vertexOffset,
                                             Unsafe.SizeOf <ImDrawVert>() * _vertexBufferSize,
                                             Unsafe.SizeOf <ImDrawVert>() * cmdList.VtxBuffer.Size);

                    System.Buffer.MemoryCopy(cmdList.IdxBuffer.Data.ToPointer(),
                                             (ushort *)indexData + indexOffset,
                                             sizeof(ushort) * _indexBufferSize,
                                             sizeof(ushort) * cmdList.IdxBuffer.Size);

                    vertexOffset += cmdList.VtxBuffer.Size;
                    indexOffset  += cmdList.IdxBuffer.Size;
                }
            }
            _deviceContext.UnmapSubresource(_vertexBuffer, 0);
            _deviceContext.UnmapSubresource(_indexBuffer, 0);

            // Setup orthographic projection matrix into our constant buffer
            // Our visible imgui space lies from drawData.DisplayPos (top left) to drawData.DisplayPos+drawData.DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
            var L   = drawData.DisplayPos.X;
            var R   = drawData.DisplayPos.X + drawData.DisplaySize.X;
            var T   = drawData.DisplayPos.Y;
            var B   = drawData.DisplayPos.Y + drawData.DisplaySize.Y;
            var mvp = new float[]
            {
                2f / (R - L), 0, 0, 0,
                0, 2f / (T - B), 0, 0,
                0, 0, 0.5f, 0,
                (R + L) / (L - R), (T + B) / (B - T), 0.5f, 1f
            };

            var constantBuffer = _deviceContext.MapSubresource(_vertexConstantBuffer, 0, MapMode.WriteDiscard, MapFlags.None).DataPointer;

            unsafe
            {
                fixed(void *mvpPtr = mvp)
                {
                    System.Buffer.MemoryCopy(mvpPtr, constantBuffer.ToPointer(), 16 * sizeof(float), 16 * sizeof(float));
                }
            }
            _deviceContext.UnmapSubresource(_vertexConstantBuffer, 0);

            var oldState = new StateBackup(_deviceContext);

            // Setup desired DX state
            SetupRenderState(drawData);

            // Render command lists
            // (Because we merged all buffers into a single one, we maintain our own offset into them)
            vertexOffset = 0;
            indexOffset  = 0;
            var clipOff = drawData.DisplayPos;

            for (int n = 0; n < drawData.CmdListsCount; n++)
            {
                var cmdList = drawData.CmdListsRange[n];
                for (int cmd = 0; cmd < cmdList.CmdBuffer.Size; cmd++)
                {
                    var pcmd = cmdList.CmdBuffer[cmd];
                    if (pcmd.UserCallback != IntPtr.Zero)
                    {
                        // TODO
                        throw new NotImplementedException();
                    }
                    else
                    {
                        // Apply scissor/clipping rectangle
                        _deviceContext.Rasterizer.SetScissorRectangle((int)(pcmd.ClipRect.X - clipOff.X), (int)(pcmd.ClipRect.Y - clipOff.Y), (int)(pcmd.ClipRect.Z - clipOff.X), (int)(pcmd.ClipRect.W - clipOff.Y));

                        // Bind texture, Draw
                        // TODO: might be nice to store samplers for loaded textures so that we can look them up and apply them here
                        // rather than just always using the font sampler
                        var textureSrv = ShaderResourceView.FromPointer <ShaderResourceView>(pcmd.TextureId);
                        _deviceContext.PixelShader.SetShaderResource(0, textureSrv);
                        _deviceContext.DrawIndexed((int)pcmd.ElemCount, (int)(pcmd.IdxOffset + indexOffset), (int)(pcmd.VtxOffset + vertexOffset));
                    }
                }

                indexOffset  += cmdList.IdxBuffer.Size;
                vertexOffset += cmdList.VtxBuffer.Size;
            }

            oldState.Dispose(); // restores the previous state
            oldState = null;
        }
예제 #8
0
        private StateBackup BackupRenderState()
        {
            var backup = new StateBackup();

            backup.ScissorRects        = new Rectangle[16]; // I couldn't find D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE as a SharpDX enum
            backup.Viewports           = new RawViewportF[16];
            backup.VertexBuffers       = new Buffer[InputAssemblerStage.VertexInputResourceSlotCount];
            backup.VertexBufferStrides = new int[InputAssemblerStage.VertexInputResourceSlotCount];
            backup.VertexBufferOffsets = new int[InputAssemblerStage.VertexInputResourceSlotCount];

            // IA
            backup.InputLayout = _deviceContext.InputAssembler.InputLayout;
            _deviceContext.InputAssembler.GetIndexBuffer(out backup.IndexBuffer, out backup.IndexBufferFormat, out backup.IndexBufferOffset);
            backup.PrimitiveTopology = _deviceContext.InputAssembler.PrimitiveTopology;
            _deviceContext.InputAssembler.GetVertexBuffers(0, InputAssemblerStage.VertexInputResourceSlotCount, backup.VertexBuffers, backup.VertexBufferStrides, backup.VertexBufferOffsets);

            // RS
            backup.RS = _deviceContext.Rasterizer.State;
            _deviceContext.Rasterizer.GetScissorRectangles <Rectangle>(backup.ScissorRects);
            _deviceContext.Rasterizer.GetViewports <RawViewportF>(backup.Viewports);

            // OM
            backup.BlendState        = _deviceContext.OutputMerger.GetBlendState(out backup.BlendFactor, out backup.SampleMask);
            backup.DepthStencilState = _deviceContext.OutputMerger.GetDepthStencilState(out backup.DepthStencilRef);
            backup.RenderTargetViews = _deviceContext.OutputMerger.GetRenderTargets(OutputMergerStage.SimultaneousRenderTargetCount, out backup.DepthStencilView);

            // VS
            backup.VS                = _deviceContext.VertexShader.Get();
            backup.VSSamplers        = _deviceContext.VertexShader.GetSamplers(0, CommonShaderStage.SamplerSlotCount);
            backup.VSConstantBuffers = _deviceContext.VertexShader.GetConstantBuffers(0, CommonShaderStage.ConstantBufferApiSlotCount);
            backup.VSResourceViews   = _deviceContext.VertexShader.GetShaderResources(0, CommonShaderStage.InputResourceSlotCount);

            // HS
            backup.HS                = _deviceContext.HullShader.Get();
            backup.HSSamplers        = _deviceContext.HullShader.GetSamplers(0, CommonShaderStage.SamplerSlotCount);
            backup.HSConstantBuffers = _deviceContext.HullShader.GetConstantBuffers(0, CommonShaderStage.ConstantBufferApiSlotCount);
            backup.HSResourceViews   = _deviceContext.HullShader.GetShaderResources(0, CommonShaderStage.InputResourceSlotCount);

            // DS
            backup.DS                = _deviceContext.DomainShader.Get();
            backup.DSSamplers        = _deviceContext.DomainShader.GetSamplers(0, CommonShaderStage.SamplerSlotCount);
            backup.DSConstantBuffers = _deviceContext.DomainShader.GetConstantBuffers(0, CommonShaderStage.ConstantBufferApiSlotCount);
            backup.DSResourceViews   = _deviceContext.DomainShader.GetShaderResources(0, CommonShaderStage.InputResourceSlotCount);

            // GS
            backup.GS                = _deviceContext.GeometryShader.Get();
            backup.GSSamplers        = _deviceContext.GeometryShader.GetSamplers(0, CommonShaderStage.SamplerSlotCount);
            backup.GSConstantBuffers = _deviceContext.GeometryShader.GetConstantBuffers(0, CommonShaderStage.ConstantBufferApiSlotCount);
            backup.GSResourceViews   = _deviceContext.GeometryShader.GetShaderResources(0, CommonShaderStage.InputResourceSlotCount);

            // PS
            backup.PS                = _deviceContext.PixelShader.Get();
            backup.PSSamplers        = _deviceContext.PixelShader.GetSamplers(0, CommonShaderStage.SamplerSlotCount);
            backup.PSConstantBuffers = _deviceContext.PixelShader.GetConstantBuffers(0, CommonShaderStage.ConstantBufferApiSlotCount);
            backup.PSResourceViews   = _deviceContext.PixelShader.GetShaderResources(0, CommonShaderStage.InputResourceSlotCount);

            // CS
            backup.CS                = _deviceContext.ComputeShader.Get();
            backup.CSSamplers        = _deviceContext.ComputeShader.GetSamplers(0, CommonShaderStage.SamplerSlotCount);
            backup.CSConstantBuffers = _deviceContext.ComputeShader.GetConstantBuffers(0, CommonShaderStage.ConstantBufferApiSlotCount);
            backup.CSResourceViews   = _deviceContext.ComputeShader.GetShaderResources(0, CommonShaderStage.InputResourceSlotCount);
            backup.CSUAVs            = _deviceContext.ComputeShader.GetUnorderedAccessViews(0, ComputeShaderStage.UnorderedAccessViewSlotCount); // should be register count and not slot, but the value is correct

            return(backup);
        }