public bool Initialize(SystemConfiguration configuration, IntPtr windowHandle) { try { #region Environment Configuration // Store the vsync setting. VerticalSyncEnabled = SystemConfiguration.VerticalSyncEnabled; // Create a DirectX graphics interface factory. var factory = new Factory(); // Use the factory to create an adapter for the primary graphics interface (video card). var adapter = factory.GetAdapter(0); // Get the primary adapter output (monitor). var monitor = adapter.GetOutput(0); // Get modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). var modes = monitor.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Interlaced); // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the the refresh rate for that monitor, if vertical sync is enabled. // Otherwise we use maximum refresh rate. var rational = new Rational(0, 1); if (VerticalSyncEnabled) { foreach (var mode in modes) { if (mode.Width == configuration.Width && mode.Height == configuration.Height) { rational = new Rational(mode.RefreshRate.Numerator, mode.RefreshRate.Denominator); break; } } } // Get the adapter (video card) description. var adapterDescription = adapter.Description; // Store the dedicated video card memory in megabytes. VideoCardMemory = adapterDescription.DedicatedVideoMemory >> 10 >> 10; // Convert the name of the video card to a character array and store it. VideoCardDescription = adapterDescription.Description; // Release the adapter output. monitor.Dispose(); // Release the adapter. adapter.Dispose(); // Release the factory. factory.Dispose(); #endregion #region Initialize swap chain and d3d device // Initialize the swap chain description. var swapChainDesc = new SwapChainDescription() { // Set to a single back buffer. BufferCount = 1, // Set the width and height of the back buffer. ModeDescription = new ModeDescription(configuration.Width, configuration.Height, rational, Format.R8G8B8A8_UNorm), // Set the usage of the back buffer. Usage = Usage.RenderTargetOutput, // Set the handle for the window to render to. OutputHandle = windowHandle, // Turn multisampling off. SampleDescription = new SampleDescription(1, 0), // Set to full screen or windowed mode. IsWindowed = !SystemConfiguration.FullScreen, // Don't set the advanced flags. Flags = SwapChainFlags.None, // Discard the back buffer content after presenting. SwapEffect = SwapEffect.Discard }; // Create the swap chain, Direct3D device, and Direct3D device context. Device device; SwapChain swapChain; Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, swapChainDesc, out device, out swapChain); Device = device; SwapChain = swapChain; DeviceContext = device.ImmediateContext; #endregion #region Initialize buffers // Get the pointer to the back buffer. var backBuffer = Texture2D.FromSwapChain <Texture2D>(SwapChain, 0); // Create the render target view with the back buffer pointer. RenderTargetView = new RenderTargetView(device, backBuffer); // Release pointer to the back buffer as we no longer need it. backBuffer.Dispose(); // Initialize and set up the description of the depth buffer. var depthBufferDesc = new Texture2DDescription() { Width = configuration.Width, Height = configuration.Height, MipLevels = 1, ArraySize = 1, Format = Format.D24_UNorm_S8_UInt, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; // Create the texture for the depth buffer using the filled out description. DepthStencilBuffer = new Texture2D(device, depthBufferDesc); #endregion #region Initialize Depth Enabled Stencil // Initialize and set up the description of the stencil state. var depthStencilDesc = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xFF, StencilWriteMask = 0xFF, // Stencil operation if pixel front-facing. FrontFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Increment, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always }, // Stencil operation if pixel is back-facing. BackFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Decrement, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always } }; // Create the depth stencil state. DepthStencilState = new DepthStencilState(Device, depthStencilDesc); #endregion #region Initialize Output Merger // Set the depth stencil state. DeviceContext.OutputMerger.SetDepthStencilState(DepthStencilState, 1); // Initialize and set up the depth stencil view. var depthStencilViewDesc = new DepthStencilViewDescription() { Format = Format.D24_UNorm_S8_UInt, Dimension = DepthStencilViewDimension.Texture2D, Texture2D = new DepthStencilViewDescription.Texture2DResource() { MipSlice = 0 } }; // Create the depth stencil view. DepthStencilView = new DepthStencilView(Device, DepthStencilBuffer, depthStencilViewDesc); // Bind the render target view and depth stencil buffer to the output render pipeline. DeviceContext.OutputMerger.SetTargets(DepthStencilView, RenderTargetView); #endregion #region Initialize Raster State // Setup the raster description which will determine how and what polygon will be drawn. var rasterDesc = new RasterizerStateDescription() { IsAntialiasedLineEnabled = false, CullMode = CullMode.Back, DepthBias = 0, DepthBiasClamp = .0f, IsDepthClipEnabled = true, FillMode = FillMode.Solid, IsFrontCounterClockwise = false, IsMultisampleEnabled = false, IsScissorEnabled = false, SlopeScaledDepthBias = .0f }; // Create the rasterizer state from the description we just filled out. RasterState = new RasterizerState(Device, rasterDesc); #endregion #region Initialize Rasterizer // Now set the rasterizer state. DeviceContext.Rasterizer.State = RasterState; // Setup and create the viewport for rendering. DeviceContext.Rasterizer.SetViewport(0, 0, configuration.Width, configuration.Height, 0, 1); #endregion #region Initialize matrices // Setup and create the projection matrix. ProjectionMatrix = Matrix.PerspectiveFovLH((float)(Math.PI / 4f), ((float)configuration.Width / configuration.Height), SystemConfiguration.ScreenNear, SystemConfiguration.ScreenDepth); // Initialize the world matrix to the identity matrix. WorldMatrix = Matrix.Identity; // Create an orthographic projection matrix for 2D rendering. OrthoMatrix = Matrix.OrthoLH(configuration.Width, configuration.Height, SystemConfiguration.ScreenNear, SystemConfiguration.ScreenDepth); #endregion #region Initialize Depth Disabled Stencil // Now create a second depth stencil state which turns off the Z buffer for 2D rendering. // The difference is that DepthEnable is set to false. // All other parameters are the same as the other depth stencil state. var depthDisabledStencilDesc = new DepthStencilStateDescription() { IsDepthEnabled = false, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xFF, StencilWriteMask = 0xFF, // Stencil operation if pixel front-facing. FrontFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Increment, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always }, // Stencil operation if pixel is back-facing. BackFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Decrement, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always } }; // Create the depth stencil state. DepthDisabledStencilState = new DepthStencilState(Device, depthDisabledStencilDesc); #endregion #region Initialize Blend States // Create an alpha enabled blend state description. var blendStateDesc = new BlendStateDescription(); blendStateDesc.RenderTarget[0].IsBlendEnabled = true; blendStateDesc.RenderTarget[0].SourceBlend = BlendOption.One; blendStateDesc.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; blendStateDesc.RenderTarget[0].BlendOperation = BlendOperation.Add; blendStateDesc.RenderTarget[0].SourceAlphaBlend = BlendOption.One; blendStateDesc.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero; blendStateDesc.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add; blendStateDesc.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; // Create the blend state using the description. AlphaEnableBlendingState = new BlendState(device, blendStateDesc); // Modify the description to create an disabled blend state description. blendStateDesc.RenderTarget[0].IsBlendEnabled = false; // Create the blend state using the description. AlphaDisableBlendingState = new BlendState(device, blendStateDesc); #endregion return(true); } catch (Exception) { return(false); } }
public void Shutdown() { // Before shutting down set to windowed mode or when you release the swap chain it will throw an exception. if (SwapChain != null) { SwapChain.SetFullscreenState(false, null); } if (AlphaEnableBlendingState != null) { AlphaEnableBlendingState.Dispose(); AlphaEnableBlendingState = null; } if (AlphaDisableBlendingState != null) { AlphaDisableBlendingState.Dispose(); AlphaDisableBlendingState = null; } if (DepthDisabledStencilState != null) { DepthDisabledStencilState.Dispose(); DepthDisabledStencilState = null; } if (RasterState != null) { RasterState.Dispose(); RasterState = null; } if (DepthStencilView != null) { DepthStencilView.Dispose(); DepthStencilView = null; } if (DepthStencilState != null) { DepthStencilState.Dispose(); DepthStencilState = null; } if (DepthStencilBuffer != null) { DepthStencilBuffer.Dispose(); DepthStencilBuffer = null; } if (RenderTargetView != null) { RenderTargetView.Dispose(); RenderTargetView = null; } if (Device != null) { Device.Dispose(); Device = null; } if (SwapChain != null) { SwapChain.Dispose(); SwapChain = null; } }
private unsafe void RenderImDrawData(DrawData *draw_data, RenderContext rc) { VertexDescriptor descriptor = new VertexDescriptor((byte)sizeof(DrawVert), 3, 0, IntPtr.Zero); int vertexOffsetInVertices = 0; int indexOffsetInElements = 0; if (draw_data->CmdListsCount == 0) { return; } for (int i = 0; i < draw_data->CmdListsCount; i++) { DrawList *cmd_list = draw_data->CmdLists[i]; _vertexBuffer.SetVertexData(new IntPtr(cmd_list->VtxBuffer.Data), descriptor, cmd_list->VtxBuffer.Size, vertexOffsetInVertices); _indexBuffer.SetIndices(new IntPtr(cmd_list->IdxBuffer.Data), IndexFormat.UInt16, sizeof(ushort), cmd_list->IdxBuffer.Size, indexOffsetInElements); vertexOffsetInVertices += cmd_list->VtxBuffer.Size; indexOffsetInElements += cmd_list->IdxBuffer.Size; } // Setup orthographic projection matrix into our constant buffer { var io = ImGui.GetIO(); Matrix4x4 mvp = Matrix4x4.CreateOrthographicOffCenter( 0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); _projectionMatrixProvider.Data = mvp; } BlendState previousBlendState = rc.BlendState; rc.SetBlendState(_blendState); rc.SetDepthStencilState(_depthDisabledState); RasterizerState previousRasterizerState = rc.RasterizerState; rc.SetRasterizerState(_rasterizerState); rc.SetVertexBuffer(_vertexBuffer); rc.SetIndexBuffer(_indexBuffer); rc.SetMaterial(_material); ImGui.ScaleClipRects(draw_data, ImGui.GetIO().DisplayFramebufferScale); // Render command lists int vtx_offset = 0; int idx_offset = 0; for (int n = 0; n < draw_data->CmdListsCount; n++) { DrawList *cmd_list = draw_data->CmdLists[n]; for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { DrawCmd *pcmd = &(((DrawCmd *)cmd_list->CmdBuffer.Data)[cmd_i]); if (pcmd->UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { if (pcmd->TextureId != IntPtr.Zero) { if (pcmd->TextureId == new IntPtr(_fontAtlasID)) { _material.UseTexture(0, _fontTextureBinding); } else { ShaderTextureBinding binding = ImGuiImageHelper.GetShaderTextureBinding(pcmd->TextureId); _material.UseTexture(0, binding); } } // TODO: This doesn't take into account viewport coordinates. rc.SetScissorRectangle( (int)pcmd->ClipRect.X, (int)pcmd->ClipRect.Y, (int)pcmd->ClipRect.Z, (int)pcmd->ClipRect.W); rc.DrawIndexedPrimitives((int)pcmd->ElemCount, idx_offset, vtx_offset); } idx_offset += (int)pcmd->ElemCount; } vtx_offset += cmd_list->VtxBuffer.Size; } rc.ClearScissorRectangle(); rc.SetBlendState(previousBlendState); rc.SetDepthStencilState(rc.DefaultDepthStencilState); rc.SetRasterizerState(previousRasterizerState); }
public FlatBatch3D FlatBatch(int layer = 0, DepthStencilState depthStencilState = null, RasterizerState rasterizerState = null, BlendState blendState = null) { depthStencilState = (depthStencilState ?? DepthStencilState.Default); rasterizerState = (rasterizerState ?? RasterizerState.CullNoneScissor); blendState = (blendState ?? BlendState.AlphaBlend); return(FindFlatBatch(layer, depthStencilState, rasterizerState, blendState)); }
public FontBatch3D FontBatch(BitmapFont font, int layer = 0, DepthStencilState depthStencilState = null, RasterizerState rasterizerState = null, BlendState blendState = null, SamplerState samplerState = null) { depthStencilState = (depthStencilState ?? DepthStencilState.Default); rasterizerState = (rasterizerState ?? RasterizerState.CullNoneScissor); blendState = (blendState ?? BlendState.AlphaBlend); samplerState = (samplerState ?? SamplerState.LinearClamp); return(FindFontBatch(font, layer, depthStencilState, rasterizerState, blendState, samplerState)); }
public TexturedBatch3D TexturedBatch(Texture2D texture, bool useAlphaTest = false, int layer = 0, DepthStencilState depthStencilState = null, RasterizerState rasterizerState = null, BlendState blendState = null, SamplerState samplerState = null) { depthStencilState = (depthStencilState ?? DepthStencilState.Default); rasterizerState = (rasterizerState ?? RasterizerState.CullNoneScissor); blendState = (blendState ?? BlendState.AlphaBlend); samplerState = (samplerState ?? SamplerState.LinearClamp); return(FindTexturedBatch(texture, useAlphaTest, layer, depthStencilState, rasterizerState, blendState, samplerState)); }