|
0 |
/* Copyright 2019 Diligent Graphics LLC
|
|
1 |
*
|
|
2 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3 |
* you may not use this file except in compliance with the License.
|
|
4 |
* You may obtain a copy of the License at
|
|
5 |
*
|
|
6 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7 |
*
|
|
8 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
9 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
10 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
|
|
11 |
*
|
|
12 |
* In no event and under no legal theory, whether in tort (including negligence),
|
|
13 |
* contract, or otherwise, unless required by applicable law (such as deliberate
|
|
14 |
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
|
15 |
* liable for any damages, including any direct, indirect, special, incidental,
|
|
16 |
* or consequential damages of any character arising as a result of this License or
|
|
17 |
* out of the use or inability to use the software (including but not limited to damages
|
|
18 |
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
|
|
19 |
* all other commercial damages or losses), even if such Contributor has been advised
|
|
20 |
* of the possibility of such damages.
|
|
21 |
*/
|
|
22 |
|
|
23 |
#include <cstddef>
|
|
24 |
#include "imgui.h"
|
|
25 |
#include "ImGuiImplDiligent.h"
|
|
26 |
#include "RenderDevice.h"
|
|
27 |
#include "DeviceContext.h"
|
|
28 |
#include "RefCntAutoPtr.h"
|
|
29 |
#include "BasicMath.h"
|
|
30 |
#include "MapHelper.h"
|
|
31 |
|
|
32 |
namespace Diligent
|
|
33 |
{
|
|
34 |
|
|
35 |
class ImGuiImplDiligent_Internal
|
|
36 |
{
|
|
37 |
public:
|
|
38 |
ImGuiImplDiligent_Internal(IRenderDevice* pDevice,
|
|
39 |
TEXTURE_FORMAT BackBufferFmt,
|
|
40 |
Uint32 InitialVertexBufferSize,
|
|
41 |
Uint32 InitialIndexBufferSize) :
|
|
42 |
m_pDevice (pDevice),
|
|
43 |
m_BackBufferFmt (BackBufferFmt),
|
|
44 |
m_VertexBufferSize(InitialVertexBufferSize),
|
|
45 |
m_IndexBufferSize (InitialIndexBufferSize)
|
|
46 |
{
|
|
47 |
// Setup back-end capabilities flags
|
|
48 |
IMGUI_CHECKVERSION();
|
|
49 |
ImGui::CreateContext();
|
|
50 |
ImGuiIO& io = ImGui::GetIO();
|
|
51 |
io.BackendRendererName = "ImGuiImplDiligent";
|
|
52 |
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
|
53 |
io.IniFilename = nullptr;
|
|
54 |
|
|
55 |
CreateDeviceObjects();
|
|
56 |
}
|
|
57 |
|
|
58 |
~ImGuiImplDiligent_Internal()
|
|
59 |
{
|
|
60 |
ImGui::DestroyContext();
|
|
61 |
}
|
|
62 |
|
|
63 |
void NewFrame();
|
|
64 |
void RenderDrawData(IDeviceContext* pCtx, ImDrawData* pDrawData);
|
|
65 |
|
|
66 |
// Use if you want to reset your rendering device without losing ImGui state.
|
|
67 |
void InvalidateDeviceObjects();
|
|
68 |
void CreateDeviceObjects();
|
|
69 |
|
|
70 |
private:
|
|
71 |
void CreateFontsTexture();
|
|
72 |
|
|
73 |
RefCntAutoPtr<IRenderDevice> m_pDevice;
|
|
74 |
RefCntAutoPtr<IBuffer> m_pVB;
|
|
75 |
RefCntAutoPtr<IBuffer> m_pIB;
|
|
76 |
RefCntAutoPtr<IBuffer> m_pVertexConstantBuffer;
|
|
77 |
RefCntAutoPtr<IPipelineState> m_pPSO;
|
|
78 |
RefCntAutoPtr<ITextureView> m_pFontSRV;
|
|
79 |
RefCntAutoPtr<IShaderResourceBinding> m_pSRB;
|
|
80 |
const TEXTURE_FORMAT m_BackBufferFmt;
|
|
81 |
Uint32 m_VertexBufferSize = 0;
|
|
82 |
Uint32 m_IndexBufferSize = 0;
|
|
83 |
};
|
|
84 |
|
|
85 |
void ImGuiImplDiligent_Internal::NewFrame()
|
|
86 |
{
|
|
87 |
if (!m_pPSO)
|
|
88 |
CreateDeviceObjects();
|
|
89 |
}
|
|
90 |
|
|
91 |
// Use if you want to reset your rendering device without losing ImGui state.
|
|
92 |
void ImGuiImplDiligent_Internal::InvalidateDeviceObjects()
|
|
93 |
{
|
|
94 |
m_pVB.Release();
|
|
95 |
m_pIB.Release();
|
|
96 |
m_pVertexConstantBuffer.Release();
|
|
97 |
m_pPSO.Release();
|
|
98 |
m_pFontSRV.Release();
|
|
99 |
m_pSRB.Release();
|
|
100 |
}
|
|
101 |
|
|
102 |
static const char* VertexShaderSource = R"(
|
|
103 |
cbuffer Constants
|
|
104 |
{
|
|
105 |
float4x4 ProjectionMatrix;
|
|
106 |
}
|
|
107 |
|
|
108 |
struct VSInput
|
|
109 |
{
|
|
110 |
float2 pos : ATTRIB0;
|
|
111 |
float2 uv : ATTRIB1;
|
|
112 |
float4 col : ATTRIB2;
|
|
113 |
};
|
|
114 |
|
|
115 |
struct PSInput
|
|
116 |
{
|
|
117 |
float4 pos : SV_POSITION;
|
|
118 |
float4 col : COLOR;
|
|
119 |
float2 uv : TEXCOORD;
|
|
120 |
};
|
|
121 |
|
|
122 |
PSInput main(VSInput VSIn)
|
|
123 |
{
|
|
124 |
PSInput PSIn;
|
|
125 |
PSIn.pos = mul(ProjectionMatrix, float4(VSIn.pos.xy, 0.0, 1.0));
|
|
126 |
PSIn.col = VSIn.col;
|
|
127 |
PSIn.uv = VSIn.uv;
|
|
128 |
return PSIn;
|
|
129 |
}
|
|
130 |
)";
|
|
131 |
|
|
132 |
static const char* PixelShaderSource = R"(
|
|
133 |
struct PSInput
|
|
134 |
{
|
|
135 |
float4 pos : SV_POSITION;
|
|
136 |
float4 col : COLOR;
|
|
137 |
float2 uv : TEXCOORD;
|
|
138 |
};
|
|
139 |
|
|
140 |
Texture2D Texture;
|
|
141 |
SamplerState Texture_sampler;
|
|
142 |
|
|
143 |
float4 main(PSInput PSIn) : SV_Target
|
|
144 |
{
|
|
145 |
return PSIn.col * Texture.Sample(Texture_sampler, PSIn.uv);
|
|
146 |
}
|
|
147 |
)";
|
|
148 |
|
|
149 |
void ImGuiImplDiligent_Internal::CreateDeviceObjects()
|
|
150 |
{
|
|
151 |
InvalidateDeviceObjects();
|
|
152 |
|
|
153 |
ShaderCreateInfo ShaderCI;
|
|
154 |
ShaderCI.UseCombinedTextureSamplers = true;
|
|
155 |
ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
|
|
156 |
|
|
157 |
RefCntAutoPtr<IShader> pVS;
|
|
158 |
{
|
|
159 |
ShaderCI.Desc.ShaderType = SHADER_TYPE_VERTEX;
|
|
160 |
ShaderCI.Desc.Name = "Imgui VS";
|
|
161 |
ShaderCI.Source = VertexShaderSource;
|
|
162 |
m_pDevice->CreateShader(ShaderCI, &pVS);
|
|
163 |
}
|
|
164 |
|
|
165 |
RefCntAutoPtr<IShader> pPS;
|
|
166 |
{
|
|
167 |
ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL;
|
|
168 |
ShaderCI.Desc.Name = "Imgui PS";
|
|
169 |
ShaderCI.Source = PixelShaderSource;
|
|
170 |
m_pDevice->CreateShader(ShaderCI, &pPS);
|
|
171 |
}
|
|
172 |
|
|
173 |
PipelineStateDesc PSODesc;
|
|
174 |
PSODesc.Name = "ImGUI PSO";
|
|
175 |
auto& GraphicsPipeline = PSODesc.GraphicsPipeline;
|
|
176 |
|
|
177 |
GraphicsPipeline.NumRenderTargets = 1;
|
|
178 |
GraphicsPipeline.RTVFormats[0] = m_BackBufferFmt;
|
|
179 |
GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
|
180 |
|
|
181 |
GraphicsPipeline.pVS = pVS;
|
|
182 |
GraphicsPipeline.pPS = pPS;
|
|
183 |
|
|
184 |
GraphicsPipeline.RasterizerDesc.CullMode = CULL_MODE_NONE;
|
|
185 |
GraphicsPipeline.RasterizerDesc.ScissorEnable = True;
|
|
186 |
GraphicsPipeline.DepthStencilDesc.DepthEnable = False;
|
|
187 |
|
|
188 |
auto& RT0 = GraphicsPipeline.BlendDesc.RenderTargets[0];
|
|
189 |
RT0.BlendEnable = True;
|
|
190 |
RT0.SrcBlend = BLEND_FACTOR_SRC_ALPHA;
|
|
191 |
RT0.DestBlend = BLEND_FACTOR_INV_SRC_ALPHA;
|
|
192 |
RT0.BlendOp = BLEND_OPERATION_ADD;
|
|
193 |
RT0.SrcBlendAlpha = BLEND_FACTOR_INV_SRC_ALPHA;
|
|
194 |
RT0.DestBlendAlpha = BLEND_FACTOR_ZERO;
|
|
195 |
RT0.BlendOpAlpha = BLEND_OPERATION_ADD;
|
|
196 |
RT0.RenderTargetWriteMask = COLOR_MASK_ALL;
|
|
197 |
|
|
198 |
LayoutElement VSInputs[]
|
|
199 |
{
|
|
200 |
{ 0, 0, 2, VT_FLOAT32}, // pos
|
|
201 |
{ 1, 0, 2, VT_FLOAT32}, // uv
|
|
202 |
{ 2, 0, 4, VT_UINT8, True} // col
|
|
203 |
};
|
|
204 |
GraphicsPipeline.InputLayout.NumElements = _countof(VSInputs);
|
|
205 |
GraphicsPipeline.InputLayout.LayoutElements = VSInputs;
|
|
206 |
|
|
207 |
ShaderResourceVariableDesc Variables[] =
|
|
208 |
{
|
|
209 |
{SHADER_TYPE_PIXEL, "Texture", SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE}
|
|
210 |
};
|
|
211 |
PSODesc.ResourceLayout.Variables = Variables;
|
|
212 |
PSODesc.ResourceLayout.NumVariables = _countof(Variables);
|
|
213 |
|
|
214 |
SamplerDesc SamLinearWrap;
|
|
215 |
SamLinearWrap.AddressU = TEXTURE_ADDRESS_WRAP;
|
|
216 |
SamLinearWrap.AddressV = TEXTURE_ADDRESS_WRAP;
|
|
217 |
SamLinearWrap.AddressW = TEXTURE_ADDRESS_WRAP;
|
|
218 |
StaticSamplerDesc StaticSamplers[] =
|
|
219 |
{
|
|
220 |
{SHADER_TYPE_PIXEL, "Texture", SamLinearWrap}
|
|
221 |
};
|
|
222 |
PSODesc.ResourceLayout.StaticSamplers = StaticSamplers;
|
|
223 |
PSODesc.ResourceLayout.NumStaticSamplers = _countof(StaticSamplers);
|
|
224 |
|
|
225 |
m_pDevice->CreatePipelineState(PSODesc, &m_pPSO);
|
|
226 |
|
|
227 |
{
|
|
228 |
BufferDesc BuffDesc;
|
|
229 |
BuffDesc.uiSizeInBytes = sizeof(float4x4);
|
|
230 |
BuffDesc.Usage = USAGE_DYNAMIC;
|
|
231 |
BuffDesc.BindFlags = BIND_UNIFORM_BUFFER;
|
|
232 |
BuffDesc.CPUAccessFlags = CPU_ACCESS_WRITE;
|
|
233 |
m_pDevice->CreateBuffer(BuffDesc, nullptr, &m_pVertexConstantBuffer);
|
|
234 |
}
|
|
235 |
m_pPSO->GetStaticVariableByName(SHADER_TYPE_VERTEX, "Constants")->Set(m_pVertexConstantBuffer);
|
|
236 |
|
|
237 |
CreateFontsTexture();
|
|
238 |
}
|
|
239 |
|
|
240 |
void ImGuiImplDiligent_Internal::CreateFontsTexture()
|
|
241 |
{
|
|
242 |
// Build texture atlas
|
|
243 |
ImGuiIO& io = ImGui::GetIO();
|
|
244 |
unsigned char* pixels = nullptr;
|
|
245 |
int width = 0, height = 0;
|
|
246 |
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
|
247 |
|
|
248 |
TextureDesc FontTexDesc;
|
|
249 |
FontTexDesc.Name = "Imgui font texture";
|
|
250 |
FontTexDesc.Type = RESOURCE_DIM_TEX_2D;
|
|
251 |
FontTexDesc.Width = static_cast<Uint32>(width);
|
|
252 |
FontTexDesc.Height = static_cast<Uint32>(height);
|
|
253 |
FontTexDesc.Format = TEX_FORMAT_RGBA8_UNORM;
|
|
254 |
FontTexDesc.BindFlags = BIND_SHADER_RESOURCE;
|
|
255 |
FontTexDesc.Usage = USAGE_STATIC;
|
|
256 |
|
|
257 |
TextureSubResData Mip0Data[] = { {pixels, FontTexDesc.Width * 4} };
|
|
258 |
TextureData InitData(Mip0Data, _countof(Mip0Data));
|
|
259 |
|
|
260 |
RefCntAutoPtr<ITexture> pFontTex;
|
|
261 |
m_pDevice->CreateTexture(FontTexDesc, &InitData, &pFontTex);
|
|
262 |
m_pFontSRV = pFontTex->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
|
|
263 |
|
|
264 |
m_pSRB.Release();
|
|
265 |
m_pPSO->CreateShaderResourceBinding(&m_pSRB, true);
|
|
266 |
m_pSRB->GetVariableByName(SHADER_TYPE_PIXEL, "Texture")->Set(m_pFontSRV);
|
|
267 |
|
|
268 |
// Store our identifier
|
|
269 |
io.Fonts->TexID = (ImTextureID)m_pFontSRV;
|
|
270 |
}
|
|
271 |
|
|
272 |
|
|
273 |
void ImGuiImplDiligent_Internal::RenderDrawData(IDeviceContext* pCtx, ImDrawData* pDrawData)
|
|
274 |
{
|
|
275 |
// Avoid rendering when minimized
|
|
276 |
if (pDrawData->DisplaySize.x <= 0.0f || pDrawData->DisplaySize.y <= 0.0f)
|
|
277 |
return;
|
|
278 |
|
|
279 |
// Create and grow vertex/index buffers if needed
|
|
280 |
if (!m_pVB || static_cast<int>(m_VertexBufferSize) < pDrawData->TotalVtxCount)
|
|
281 |
{
|
|
282 |
m_pVB.Release();
|
|
283 |
while(static_cast<int>(m_VertexBufferSize) < pDrawData->TotalVtxCount)
|
|
284 |
m_VertexBufferSize *= 2;
|
|
285 |
|
|
286 |
BufferDesc VBDesc;
|
|
287 |
VBDesc.Name = "Imgui vertex buffer";
|
|
288 |
VBDesc.BindFlags = BIND_VERTEX_BUFFER;
|
|
289 |
VBDesc.uiSizeInBytes = m_VertexBufferSize * sizeof(ImDrawVert);
|
|
290 |
VBDesc.Usage = USAGE_DYNAMIC;
|
|
291 |
VBDesc.CPUAccessFlags = CPU_ACCESS_WRITE;
|
|
292 |
m_pDevice->CreateBuffer(VBDesc, nullptr, &m_pVB);
|
|
293 |
}
|
|
294 |
|
|
295 |
if (!m_pIB || static_cast<int>(m_IndexBufferSize) < pDrawData->TotalIdxCount)
|
|
296 |
{
|
|
297 |
m_pIB.Release();
|
|
298 |
while(static_cast<int>(m_IndexBufferSize) < pDrawData->TotalIdxCount)
|
|
299 |
m_IndexBufferSize *= 2;
|
|
300 |
|
|
301 |
BufferDesc IBDesc;
|
|
302 |
IBDesc.Name = "Imgui index buffer";
|
|
303 |
IBDesc.BindFlags = BIND_INDEX_BUFFER;
|
|
304 |
IBDesc.uiSizeInBytes = m_IndexBufferSize * sizeof(ImDrawIdx);
|
|
305 |
IBDesc.Usage = USAGE_DYNAMIC;
|
|
306 |
IBDesc.CPUAccessFlags = CPU_ACCESS_WRITE;
|
|
307 |
m_pDevice->CreateBuffer(IBDesc, nullptr, &m_pIB);
|
|
308 |
}
|
|
309 |
|
|
310 |
{
|
|
311 |
MapHelper<ImDrawVert> Verices(pCtx, m_pVB, MAP_WRITE, MAP_FLAG_DISCARD);
|
|
312 |
MapHelper<ImDrawIdx> Indices(pCtx, m_pIB, MAP_WRITE, MAP_FLAG_DISCARD);
|
|
313 |
ImDrawVert* vtx_dst = Verices;
|
|
314 |
ImDrawIdx* idx_dst = Indices;
|
|
315 |
for (int n = 0; n < pDrawData->CmdListsCount; n++)
|
|
316 |
{
|
|
317 |
const ImDrawList* cmd_list = pDrawData->CmdLists[n];
|
|
318 |
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
|
319 |
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
|
320 |
vtx_dst += cmd_list->VtxBuffer.Size;
|
|
321 |
idx_dst += cmd_list->IdxBuffer.Size;
|
|
322 |
}
|
|
323 |
}
|
|
324 |
|
|
325 |
|
|
326 |
// Setup orthographic projection matrix into our constant buffer
|
|
327 |
// Our visible imgui space lies from pDrawData->DisplayPos (top left) to pDrawData->DisplayPos+data_data->DisplaySize (bottom right).
|
|
328 |
// DisplayPos is (0,0) for single viewport apps.
|
|
329 |
{
|
|
330 |
MapHelper<float4x4> CBData(pCtx, m_pVertexConstantBuffer, MAP_WRITE, MAP_FLAG_DISCARD);
|
|
331 |
float L = pDrawData->DisplayPos.x;
|
|
332 |
float R = pDrawData->DisplayPos.x + pDrawData->DisplaySize.x;
|
|
333 |
float T = pDrawData->DisplayPos.y;
|
|
334 |
float B = pDrawData->DisplayPos.y + pDrawData->DisplaySize.y;
|
|
335 |
*CBData = float4x4
|
|
336 |
{
|
|
337 |
2.0f/(R-L), 0.0f, 0.0f, 0.0f,
|
|
338 |
0.0f, 2.0f/(T-B), 0.0f, 0.0f,
|
|
339 |
0.0f, 0.0f, 0.5f, 0.0f,
|
|
340 |
(R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f
|
|
341 |
};
|
|
342 |
}
|
|
343 |
|
|
344 |
auto DisplayWidth = static_cast<Uint32>(pDrawData->DisplaySize.x);
|
|
345 |
auto DisplayHeight = static_cast<Uint32>(pDrawData->DisplaySize.y);
|
|
346 |
auto SetupRenderState = [&]()
|
|
347 |
{
|
|
348 |
// Setup shader and vertex buffers
|
|
349 |
Uint32 Offsets[] = {0};
|
|
350 |
IBuffer* pVBs[] = {m_pVB};
|
|
351 |
pCtx->SetVertexBuffers(0, 1, pVBs, Offsets, RESOURCE_STATE_TRANSITION_MODE_TRANSITION, SET_VERTEX_BUFFERS_FLAG_RESET);
|
|
352 |
pCtx->SetIndexBuffer(m_pIB, 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
|
|
353 |
pCtx->SetPipelineState(m_pPSO);
|
|
354 |
pCtx->CommitShaderResources(m_pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
|
|
355 |
|
|
356 |
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
|
357 |
pCtx->SetBlendFactors(blend_factor);
|
|
358 |
|
|
359 |
Viewport vp;
|
|
360 |
vp.Width = pDrawData->DisplaySize.x;
|
|
361 |
vp.Height = pDrawData->DisplaySize.y;
|
|
362 |
vp.MinDepth = 0.0f;
|
|
363 |
vp.MaxDepth = 1.0f;
|
|
364 |
vp.TopLeftX = vp.TopLeftY = 0;
|
|
365 |
pCtx->SetViewports(1, &vp, DisplayWidth, DisplayHeight);
|
|
366 |
};
|
|
367 |
|
|
368 |
SetupRenderState();
|
|
369 |
|
|
370 |
// Render command lists
|
|
371 |
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
|
372 |
int global_idx_offset = 0;
|
|
373 |
int global_vtx_offset = 0;
|
|
374 |
ImVec2 clip_off = pDrawData->DisplayPos;
|
|
375 |
for (int n = 0; n < pDrawData->CmdListsCount; n++)
|
|
376 |
{
|
|
377 |
const ImDrawList* cmd_list = pDrawData->CmdLists[n];
|
|
378 |
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
|
379 |
{
|
|
380 |
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
|
381 |
if (pcmd->UserCallback != NULL)
|
|
382 |
{
|
|
383 |
// User callback, registered via ImDrawList::AddCallback()
|
|
384 |
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
|
385 |
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
|
386 |
SetupRenderState();
|
|
387 |
else
|
|
388 |
pcmd->UserCallback(cmd_list, pcmd);
|
|
389 |
}
|
|
390 |
else
|
|
391 |
{
|
|
392 |
// Apply scissor/clipping rectangle
|
|
393 |
const Rect r =
|
|
394 |
{
|
|
395 |
static_cast<Int32>(pcmd->ClipRect.x - clip_off.x),
|
|
396 |
static_cast<Int32>(pcmd->ClipRect.y - clip_off.y),
|
|
397 |
static_cast<Int32>(pcmd->ClipRect.z - clip_off.x),
|
|
398 |
static_cast<Int32>(pcmd->ClipRect.w - clip_off.y)
|
|
399 |
};
|
|
400 |
pCtx->SetScissorRects(1, &r, DisplayWidth, DisplayHeight);
|
|
401 |
|
|
402 |
// Bind texture, Draw
|
|
403 |
auto* texture_srv = reinterpret_cast<ITextureView*>(pcmd->TextureId);
|
|
404 |
VERIFY_EXPR(texture_srv == m_pFontSRV);
|
|
405 |
//ctx->PSSetShaderResources(0, 1, &texture_srv);
|
|
406 |
DrawAttribs DrawAttrs(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? VT_UINT16 : VT_UINT32, DRAW_FLAG_VERIFY_STATES);
|
|
407 |
DrawAttrs.FirstIndexLocation = pcmd->IdxOffset + global_idx_offset;
|
|
408 |
DrawAttrs.BaseVertex = pcmd->VtxOffset + global_vtx_offset;
|
|
409 |
pCtx->Draw(DrawAttrs);
|
|
410 |
}
|
|
411 |
}
|
|
412 |
global_idx_offset += cmd_list->IdxBuffer.Size;
|
|
413 |
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
|
414 |
}
|
|
415 |
}
|
|
416 |
|
|
417 |
|
|
418 |
|
|
419 |
ImGuiImplDiligent::ImGuiImplDiligent(IRenderDevice* pDevice,
|
|
420 |
TEXTURE_FORMAT BackBufferFmt,
|
|
421 |
Uint32 InitialVertexBufferSize,
|
|
422 |
Uint32 InitialIndexBufferSize) :
|
|
423 |
m_pImpl(new ImGuiImplDiligent_Internal(pDevice, BackBufferFmt, InitialVertexBufferSize, InitialIndexBufferSize))
|
|
424 |
{
|
|
425 |
}
|
|
426 |
|
|
427 |
ImGuiImplDiligent::~ImGuiImplDiligent()
|
|
428 |
{
|
|
429 |
}
|
|
430 |
|
|
431 |
void ImGuiImplDiligent::NewFrame()
|
|
432 |
{
|
|
433 |
m_pImpl->NewFrame();
|
|
434 |
ImGui::NewFrame();
|
|
435 |
}
|
|
436 |
|
|
437 |
void ImGuiImplDiligent::Render(IDeviceContext* pCtx)
|
|
438 |
{
|
|
439 |
ImGui::Render();
|
|
440 |
m_pImpl->RenderDrawData(pCtx, ImGui::GetDrawData());
|
|
441 |
}
|
|
442 |
|
|
443 |
// Use if you want to reset your rendering device without losing ImGui state.
|
|
444 |
void ImGuiImplDiligent::InvalidateDeviceObjects()
|
|
445 |
{
|
|
446 |
m_pImpl->InvalidateDeviceObjects();
|
|
447 |
}
|
|
448 |
|
|
449 |
void ImGuiImplDiligent::CreateDeviceObjects()
|
|
450 |
{
|
|
451 |
m_pImpl->CreateDeviceObjects();
|
|
452 |
}
|
|
453 |
|
|
454 |
}
|
|
455 |
|
|
456 |
|