| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include "imguiGraphD3D11.h" |
| |
|
| | |
| | #include <d3d11.h> |
| |
|
| | #include "../d3d/shaders/imguiVS.hlsl.h" |
| | #include "../d3d/shaders/imguiPS.hlsl.h" |
| |
|
| | namespace |
| | { |
| | template <class T> |
| | void inline COMRelease(T& t) |
| | { |
| | if (t) t->Release(); |
| | t = nullptr; |
| | } |
| | } |
| |
|
| | namespace |
| | { |
| | ID3D11Device* m_device = nullptr; |
| | ID3D11DeviceContext* m_deviceContext = nullptr; |
| | int m_winW = 0; |
| | int m_winH = 0; |
| |
|
| | uint32_t m_maxVertices = 0; |
| |
|
| | struct Vertex |
| | { |
| | float x, y; |
| | float u, v; |
| | uint8_t rgba[4]; |
| | }; |
| |
|
| | ID3D11RasterizerState* m_rasterizerState = nullptr; |
| | ID3D11SamplerState* m_samplerState = nullptr; |
| | ID3D11InputLayout* m_inputLayout = nullptr; |
| | ID3D11BlendState* m_blendState = nullptr; |
| | ID3D11VertexShader* m_imguiVS = nullptr; |
| | ID3D11PixelShader* m_imguiPS = nullptr; |
| | ID3D11Buffer* m_constantBuffer = nullptr; |
| | ID3D11Buffer* m_vertexBuffer = nullptr; |
| | Vertex* m_vertexBufferData = nullptr; |
| |
|
| | struct Scissor |
| | { |
| | int beginIdx; |
| | int stopIdx; |
| | int x; |
| | int y; |
| | int width; |
| | int height; |
| | }; |
| | Scissor m_stateScissor = {}; |
| |
|
| | ID3D11Texture2D* m_texture = nullptr; |
| | ID3D11ShaderResourceView* m_textureSRV = nullptr; |
| |
|
| | Vertex m_stateVert; |
| | uint32_t m_stateVertIdx = 0u; |
| |
|
| | struct Params |
| | { |
| | float projection[16]; |
| |
|
| | float padding[64 - 16]; |
| | }; |
| | } |
| |
|
| | void imguiGraphContextDestroyD3D11() |
| | { |
| | COMRelease(m_rasterizerState); |
| | COMRelease(m_samplerState); |
| | COMRelease(m_inputLayout); |
| | COMRelease(m_blendState); |
| | COMRelease(m_imguiVS); |
| | COMRelease(m_imguiPS); |
| | COMRelease(m_constantBuffer); |
| | COMRelease(m_vertexBuffer); |
| | } |
| |
|
| | void imguiGraphContextInitD3D11(const ImguiGraphDesc* descIn) |
| | { |
| | const auto desc = cast_to_imguiGraphDescD3D11(descIn); |
| |
|
| | m_device = desc->device; |
| | m_deviceContext = desc->deviceContext; |
| | m_winW = desc->winW; |
| | m_winH = desc->winH; |
| |
|
| | m_maxVertices = desc->maxVertices; |
| |
|
| | |
| | { |
| | D3D11_RASTERIZER_DESC desc = {}; |
| | desc.FillMode = D3D11_FILL_SOLID; |
| | desc.CullMode = D3D11_CULL_BACK; |
| | desc.FrontCounterClockwise = TRUE; |
| | desc.DepthBias = 0; |
| | desc.DepthBiasClamp = 0.f; |
| | desc.SlopeScaledDepthBias = 0.f; |
| | desc.DepthClipEnable = TRUE; |
| | desc.ScissorEnable = TRUE; |
| | desc.MultisampleEnable = FALSE; |
| | desc.AntialiasedLineEnable = FALSE; |
| |
|
| | m_device->CreateRasterizerState(&desc, &m_rasterizerState); |
| | } |
| |
|
| | |
| | { |
| | D3D11_SAMPLER_DESC sampler = {}; |
| | sampler.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; |
| | sampler.AddressU = D3D11_TEXTURE_ADDRESS_BORDER; |
| | sampler.AddressV = D3D11_TEXTURE_ADDRESS_BORDER; |
| | sampler.AddressW = D3D11_TEXTURE_ADDRESS_BORDER; |
| | sampler.MipLODBias = 0; |
| | sampler.MaxAnisotropy = 0; |
| | sampler.ComparisonFunc = D3D11_COMPARISON_NEVER; |
| | |
| | sampler.MinLOD = 0.f; |
| | sampler.MaxLOD = D3D11_FLOAT32_MAX; |
| |
|
| | m_device->CreateSamplerState(&sampler, &m_samplerState); |
| | } |
| |
|
| | |
| | { |
| | D3D11_INPUT_ELEMENT_DESC inputElementDescs[] = |
| | { |
| | { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, |
| | { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, |
| | { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, |
| | }; |
| |
|
| | m_device->CreateInputLayout(inputElementDescs, 3, g_imguiVS, sizeof(g_imguiVS), &m_inputLayout); |
| | } |
| |
|
| | |
| | { |
| | D3D11_BLEND_DESC blendDesc = {}; |
| | blendDesc.AlphaToCoverageEnable = false; |
| | blendDesc.IndependentBlendEnable = false; |
| | blendDesc.RenderTarget[0].BlendEnable = true; |
| | blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; |
| | blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; |
| | blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; |
| | blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; |
| | blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; |
| | blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; |
| | blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; |
| |
|
| | m_device->CreateBlendState(&blendDesc, &m_blendState); |
| | } |
| |
|
| | |
| | m_device->CreateVertexShader(g_imguiVS, sizeof(g_imguiVS), nullptr, &m_imguiVS); |
| | m_device->CreatePixelShader(g_imguiPS, sizeof(g_imguiPS), nullptr, &m_imguiPS); |
| |
|
| | |
| | { |
| | Params params = { |
| | 1.f, 0.f, 0.f, 0.f, |
| | 0.f, 1.f, 0.f, 0.f, |
| | 0.f, 0.f, 1.f, 0.f, |
| | 0.f, 0.f, 0.f, 1.f |
| | }; |
| |
|
| | D3D11_BUFFER_DESC bufDesc; |
| | bufDesc.ByteWidth = sizeof(params); |
| | bufDesc.Usage = D3D11_USAGE_DYNAMIC; |
| | bufDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; |
| | bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; |
| | bufDesc.MiscFlags = 0; |
| |
|
| | D3D11_SUBRESOURCE_DATA data = {}; |
| | data.pSysMem = ¶ms; |
| |
|
| | m_device->CreateBuffer(&bufDesc, &data, &m_constantBuffer); |
| | } |
| |
|
| | |
| | { |
| | UINT bufferSize = (UINT)(m_maxVertices) * sizeof(Vertex); |
| |
|
| | D3D11_BUFFER_DESC bufDesc; |
| | bufDesc.ByteWidth = bufferSize; |
| | bufDesc.Usage = D3D11_USAGE_DYNAMIC; |
| | bufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; |
| | bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; |
| | bufDesc.MiscFlags = 0; |
| |
|
| | m_device->CreateBuffer(&bufDesc, nullptr, &m_vertexBuffer); |
| | } |
| | } |
| |
|
| | void imguiGraphContextUpdateD3D11(const ImguiGraphDesc* descIn) |
| | { |
| | const auto desc = cast_to_imguiGraphDescD3D11(descIn); |
| |
|
| | m_device = desc->device; |
| | m_deviceContext = desc->deviceContext; |
| | m_winW = desc->winW; |
| | m_winH = desc->winH; |
| | } |
| |
|
| | void imguiGraphRecordBeginD3D11() |
| | { |
| | Params params = { |
| | 2.f / float(m_winW), 0.f, 0.f, -1.f, |
| | 0.f, 2.f / float(m_winH), 0.f, -1.f, |
| | 0.f, 0.f, 1.f, 0.f, |
| | 0.f, 0.f, 0.f, 1.f |
| | }; |
| |
|
| | ID3D11DeviceContext* context = m_deviceContext; |
| |
|
| | |
| | { |
| | D3D11_MAPPED_SUBRESOURCE mappedResource = {}; |
| | if (S_OK == context->Map(m_constantBuffer, 0u, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource)) |
| | { |
| | memcpy(mappedResource.pData, ¶ms, sizeof(Params)); |
| |
|
| | context->Unmap(m_constantBuffer, 0u); |
| | } |
| | } |
| |
|
| | |
| | m_stateVert = Vertex{ 0.f, 0.f, -1.f, -1.f, 0,0,0,0 }; |
| | m_stateVertIdx = 0u; |
| |
|
| | m_stateScissor = Scissor { 0, 0, 0, 0, m_winW, m_winH }; |
| |
|
| | |
| | context->VSSetShader(m_imguiVS, nullptr, 0u); |
| | context->GSSetShader(nullptr, nullptr, 0u); |
| | context->PSSetShader(m_imguiPS, nullptr, 0u); |
| |
|
| | context->IASetInputLayout(m_inputLayout); |
| | context->OMSetBlendState(m_blendState, nullptr, 0xFFFFFFFF); |
| | context->PSSetSamplers(0, 1, &m_samplerState); |
| |
|
| | context->VSSetConstantBuffers(0, 1, &m_constantBuffer); |
| |
|
| | context->PSSetShaderResources(0, 1, &m_textureSRV); |
| |
|
| | context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); |
| |
|
| | context->RSSetState(m_rasterizerState); |
| |
|
| | |
| | { |
| | D3D11_MAPPED_SUBRESOURCE mappedResource = {}; |
| | if (S_OK == context->Map(m_vertexBuffer, 0u, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource)) |
| | { |
| | context->Unmap(m_vertexBuffer, 0u); |
| | } |
| | } |
| |
|
| | UINT vertexStride = sizeof(Vertex); |
| | UINT offset = 0u; |
| | context->IASetVertexBuffers(0, 1, &m_vertexBuffer, &vertexStride, &offset); |
| |
|
| | |
| | { |
| | D3D11_MAPPED_SUBRESOURCE mappedResource = {}; |
| | if (S_OK == context->Map(m_vertexBuffer, 0u, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource)) |
| | { |
| | m_vertexBufferData = (Vertex*)mappedResource.pData; |
| | } |
| | else |
| | { |
| | m_vertexBufferData = nullptr; |
| | } |
| | } |
| | } |
| |
|
| | static void imguiGraphFlush() |
| | { |
| | ID3D11DeviceContext* context = m_deviceContext; |
| |
|
| | |
| | context->Unmap(m_vertexBuffer, 0u); |
| |
|
| | Scissor& p = m_stateScissor; |
| | if (p.beginIdx < p.stopIdx) |
| | { |
| | int winH = m_winH; |
| | D3D11_RECT rect; |
| | rect.left = p.x; |
| | rect.right = p.x + p.width; |
| | rect.top = (winH) - (p.y + p.height); |
| | rect.bottom = (winH) - (p.y); |
| | context->RSSetScissorRects(1, &rect); |
| |
|
| | UINT vertexCount = (p.stopIdx - p.beginIdx); |
| | UINT startIndex = p.beginIdx; |
| | context->DrawInstanced(vertexCount, 1, startIndex, 0); |
| | } |
| |
|
| | |
| | { |
| | D3D11_MAPPED_SUBRESOURCE mappedResource = {}; |
| | if (S_OK == context->Map(m_vertexBuffer, 0u, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource)) |
| | { |
| | m_vertexBufferData = (Vertex*)mappedResource.pData; |
| | } |
| | else |
| | { |
| | m_vertexBufferData = nullptr; |
| | } |
| | } |
| | } |
| |
|
| | void imguiGraphRecordEndD3D11() |
| | { |
| | ID3D11DeviceContext* context = m_deviceContext; |
| |
|
| | context->OMSetBlendState(nullptr,nullptr,0xFFFFFFFF); |
| |
|
| | |
| | context->Unmap(m_vertexBuffer, 0u); |
| |
|
| | |
| | Scissor& p = m_stateScissor; |
| | int winH = m_winH; |
| | D3D11_RECT rect; |
| | rect.left = p.x; |
| | rect.right = p.x + p.width; |
| | rect.top = (winH) - (p.y + p.height); |
| | rect.bottom = (winH) - (p.y); |
| | context->RSSetScissorRects(1, &rect); |
| |
|
| | context->RSSetState(nullptr); |
| | } |
| |
|
| | void imguiGraphEnableScissorD3D11(int x, int y, int width, int height) |
| | { |
| | |
| | m_stateScissor.stopIdx = m_stateVertIdx; |
| |
|
| | imguiGraphFlush(); |
| |
|
| | m_stateScissor.beginIdx = m_stateVertIdx; |
| | m_stateScissor.stopIdx = m_stateVertIdx; |
| | m_stateScissor.x = x; |
| | m_stateScissor.y = y; |
| | m_stateScissor.width = width; |
| | m_stateScissor.height = height; |
| | } |
| |
|
| | void imguiGraphDisableScissorD3D11() |
| | { |
| | if (m_stateVertIdx == 0) return; |
| |
|
| | |
| | m_stateScissor.stopIdx = m_stateVertIdx; |
| |
|
| | imguiGraphFlush(); |
| |
|
| | m_stateScissor.beginIdx = m_stateVertIdx; |
| | m_stateScissor.stopIdx = m_stateVertIdx; |
| | m_stateScissor.x = 0; |
| | m_stateScissor.y = 0; |
| | m_stateScissor.width = m_winW; |
| | m_stateScissor.height = m_winH; |
| | } |
| |
|
| | void imguiGraphVertex2fD3D11(float x, float y) |
| | { |
| | float v[2] = { x,y }; |
| | imguiGraphVertex2fvD3D11(v); |
| | } |
| |
|
| | void imguiGraphVertex2fvD3D11(const float* v) |
| | { |
| | |
| | m_stateVert.x = v[0]; |
| | m_stateVert.y = v[1]; |
| |
|
| | Vertex* vdata = m_vertexBufferData; |
| |
|
| | |
| | if ((m_stateVertIdx) < m_maxVertices) |
| | { |
| | vdata[m_stateVertIdx++] = m_stateVert; |
| | } |
| | } |
| |
|
| | void imguiGraphTexCoord2fD3D11(float u, float v) |
| | { |
| | m_stateVert.u = u; |
| | m_stateVert.v = v; |
| | } |
| |
|
| | void imguiGraphColor4ubD3D11(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) |
| | { |
| | m_stateVert.rgba[0] = red; |
| | m_stateVert.rgba[1] = green; |
| | m_stateVert.rgba[2] = blue; |
| | m_stateVert.rgba[3] = alpha; |
| | } |
| |
|
| | void imguiGraphColor4ubvD3D11(const uint8_t* v) |
| | { |
| | m_stateVert.rgba[0] = v[0]; |
| | m_stateVert.rgba[1] = v[1]; |
| | m_stateVert.rgba[2] = v[2]; |
| | m_stateVert.rgba[3] = v[3]; |
| | } |
| |
|
| | void imguiGraphFontTextureEnableD3D11() |
| | { |
| |
|
| | } |
| |
|
| | void imguiGraphFontTextureDisableD3D11() |
| | { |
| | m_stateVert.u = -1.f; |
| | m_stateVert.v = -1.f; |
| | } |
| |
|
| | void imguiGraphFontTextureInitD3D11(unsigned char* data) |
| | { |
| | ID3D11DeviceContext* context = m_deviceContext; |
| |
|
| | |
| | { |
| | UINT width = 512; |
| | UINT height = 512; |
| |
|
| | D3D11_TEXTURE2D_DESC texDesc = {}; |
| | texDesc.Width = width; |
| | texDesc.Height = height; |
| | texDesc.MipLevels = 1; |
| | texDesc.ArraySize = 1; |
| | texDesc.Format = DXGI_FORMAT_R8_UNORM; |
| | texDesc.SampleDesc.Count = 1; |
| | texDesc.SampleDesc.Quality = 0u; |
| | texDesc.Usage = D3D11_USAGE_IMMUTABLE; |
| | texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; |
| | texDesc.CPUAccessFlags = 0; |
| | texDesc.MiscFlags = 0; |
| |
|
| | D3D11_SUBRESOURCE_DATA initData = {}; |
| | initData.pSysMem = data; |
| | initData.SysMemPitch = width; |
| |
|
| | if (m_device->CreateTexture2D(&texDesc, &initData, &m_texture)) |
| | { |
| | return; |
| | } |
| |
|
| | if (m_device->CreateShaderResourceView(m_texture, nullptr, &m_textureSRV)) |
| | { |
| | return; |
| | } |
| | } |
| |
|
| | } |
| |
|
| | void imguiGraphFontTextureReleaseD3D11() |
| | { |
| | COMRelease(m_texture); |
| | COMRelease(m_textureSRV); |
| | } |