|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#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); |
|
|
} |