8 #pragma warning(disable: 4838) 12 #pragma comment(lib, "d3d11.lib") 13 #pragma comment(lib, "d3dx11.lib") 18 using error::throwTrace;
30 struct CBNeverChanges {
48 inline void createCBFromTask(CBChanges *out,
const DrawTask &task)
52 XMVECTORF32 xMirror = { 1.0f, 0.0f, 0.0f, -0.5f };
54 XMVECTORF32 yMirror = { 0.0f, 1.0f, 0.0f, -0.5f };
55 out->lrInv = XMMatrixTranspose(
56 task.lrInv ? XMMatrixReflect(xMirror) : XMMatrixIdentity());
57 out->udInv = XMMatrixTranspose(
58 task.udInv ? XMMatrixReflect(yMirror) : XMMatrixIdentity());
59 out->DestScale = XMMatrixTranspose(XMMatrixScaling(
60 static_cast<float>(task.sw), static_cast<float>(task.sh), 1.0f));
61 out->Centering = XMMatrixTranspose(XMMatrixTranslation(
62 -static_cast<float>(task.cx), -static_cast<float>(task.cy), 0.0f));
63 out->Scale = XMMatrixTranspose(XMMatrixScaling(
64 task.scaleX, task.scaleY, 1.0f));
65 out->Rotation = XMMatrixTranspose(XMMatrixRotationZ(task.angle));
66 out->Translate = XMMatrixTranspose(XMMatrixTranslation(
67 static_cast<float>(task.dx), static_cast<float>(task.dy), 1.0f));
68 out->uvOffset = XMFLOAT2(
69 static_cast<float>(task.sx) / task.texW,
70 static_cast<float>(task.sy) / task.texH);
71 out->uvSize = XMFLOAT2(
72 static_cast<float>(task.sw) / task.texW,
73 static_cast<float>(task.sh) / task.texH);
74 out->FontColor = XMFLOAT4(
75 ((task.fontColor & 0x00ff0000) >> 16) / 255.0f,
76 ((task.fontColor & 0x0000ff00) >> 8) / 255.0f,
77 ((task.fontColor & 0x000000ff) >> 0) / 255.0f,
78 ((task.fontColor & 0xff000000) >> 24) / 255.0f);
79 out->Alpha = task.alpha;
87 m_drawTaskList.reserve(DrawListMax);
92 void DGraphics::initializeD3D()
98 if (!::XMVerifyCPUSupport()) {
99 throwTrace<D3DError>(
"XMVerifyCPUSupport() failed", 0);
104 UINT createDeviceFlags = 0;
106 createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
108 std::array<D3D_DRIVER_TYPE, 2> driverTypes{
109 D3D_DRIVER_TYPE_HARDWARE,
112 std::array<D3D_FEATURE_LEVEL, 3> featureLevels{
113 D3D_FEATURE_LEVEL_11_0,
114 D3D_FEATURE_LEVEL_10_1,
115 D3D_FEATURE_LEVEL_10_0,
118 DXGI_SWAP_CHAIN_DESC sd;
119 ZeroMemory(&sd,
sizeof(sd));
121 sd.BufferDesc.Width = m_param.
w;
122 sd.BufferDesc.Height = m_param.
h;
123 sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
124 sd.BufferDesc.RefreshRate.Numerator = m_param.
refreshRate;
125 sd.BufferDesc.RefreshRate.Denominator = 1;
126 sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
127 sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
128 sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
129 sd.OutputWindow = m_param.
hWnd;
130 sd.SampleDesc.Count = 1;
131 sd.SampleDesc.Quality = 0;
133 sd.Flags = SwapChainFlag;
135 ID3D11Device *ptmpDevice =
nullptr;
136 ID3D11DeviceContext *ptmpContext =
nullptr;
137 IDXGISwapChain *ptmpSwapChain =
nullptr;
138 D3D_FEATURE_LEVEL featureLevel =
static_cast<D3D_FEATURE_LEVEL
>(0);
140 for (
auto driverType : driverTypes) {
141 debug::writef(L
"Creating device and swapchain... (driverType=%d)",
142 static_cast<int>(driverType));
143 hr = ::D3D11CreateDeviceAndSwapChain(
nullptr, driverType,
nullptr,
144 createDeviceFlags, featureLevels.data(),
static_cast<UINT
>(featureLevels.size()),
145 D3D11_SDK_VERSION, &sd,
146 &ptmpSwapChain, &ptmpDevice, &featureLevel, &ptmpContext);
148 debug::writef(L
"Creating device and swapchain OK (Feature level=0x%04x)",
149 static_cast<uint32_t>(featureLevel));
156 checkDXResult<D3DError>(hr,
"D3D11CreateDeviceAndSwapChain() failed");
157 m_pDevice.reset(ptmpDevice);
158 m_pContext.reset(ptmpContext);
159 m_pSwapChain.reset(ptmpSwapChain);
166 IDXGIDevice1 *ptmpDXGIDevice =
nullptr;
167 hr = m_pDevice->QueryInterface(__uuidof(IDXGIDevice1), (
void **)&ptmpDXGIDevice);
168 checkDXResult<D3DError>(hr,
"QueryInterface(IDXGIDevice1) failed");
170 hr = pDXGIDevice->SetMaximumFrameLatency(1);
171 checkDXResult<D3DError>(hr,
"IDXGIDevice1::SetMaximumFrameLatency() failed");
182 ID3D11VertexShader *ptmpVS =
nullptr;
183 hr = m_pDevice->CreateVertexShader(bin.data(), bin.size(),
nullptr, &ptmpVS);
184 checkDXResult<D3DError>(hr,
"ID3D11Device::CreateVertexShader() failed");
185 m_pVertexShader.reset(ptmpVS);
189 D3D11_INPUT_ELEMENT_DESC layout[] = {
190 {
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
191 {
"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
193 ID3D11InputLayout *ptmpInputLayout =
nullptr;
194 hr = m_pDevice->CreateInputLayout(layout, _countof(layout), bin.data(),
195 bin.size(), &ptmpInputLayout);
196 checkDXResult<D3DError>(hr,
"ID3D11Device::CreateInputLayout() failed");
197 m_pInputLayout.reset(ptmpInputLayout);
199 m_pContext->IASetInputLayout(m_pInputLayout.get());
207 ID3D11PixelShader *ptmpPS =
nullptr;
208 hr = m_pDevice->CreatePixelShader(bin.data(), bin.size(),
nullptr, &ptmpPS);
209 checkDXResult<D3DError>(hr,
"ID3D11Device::CreatePixelShader() failed");
210 m_pPixelShader.reset(ptmpPS);
218 SpriteVertex vertices[] = {
219 { XMFLOAT3(0.0f, 1.0f, 0.0f) , XMFLOAT2(0.0f, 1.0f) },
220 { XMFLOAT3(1.0f, 1.0f, 0.0f) , XMFLOAT2(1.0f, 1.0f) },
221 { XMFLOAT3(0.0f, 0.0f, 0.0f) , XMFLOAT2(0.0f, 0.0f) },
222 { XMFLOAT3(1.0f, 0.0f, 0.0f) , XMFLOAT2(1.0f, 0.0f) },
224 D3D11_BUFFER_DESC bd = { 0 };
225 bd.Usage = D3D11_USAGE_DEFAULT;
226 bd.ByteWidth =
sizeof(vertices);
227 bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
228 bd.CPUAccessFlags = 0;
229 D3D11_SUBRESOURCE_DATA initData = { 0 };
230 initData.pSysMem = vertices;
231 ID3D11Buffer *ptmpVertexBuffer =
nullptr;
232 hr = m_pDevice->CreateBuffer(&bd, &initData, &ptmpVertexBuffer);
233 checkDXResult<D3DError>(hr,
"ID3D11Device::CreateBuffer() failed");
234 m_pVertexBuffer.reset(ptmpVertexBuffer);
239 ID3D11Buffer *pVertexBuffer = m_pVertexBuffer.get();
240 UINT stride =
sizeof(SpriteVertex);
242 m_pContext->IASetVertexBuffers(0, 1, &pVertexBuffer, &stride, &offset);
244 m_pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
251 CBNeverChanges buffer;
253 buffer.Projection = XMMatrixIdentity();
254 buffer.Projection._41 = -1.0f;
255 buffer.Projection._42 = 1.0f;
256 buffer.Projection._11 = 2.0f / m_param.
w;
257 buffer.Projection._22 = -2.0f / m_param.
h;
258 buffer.Projection = XMMatrixTranspose(buffer.Projection);
259 D3D11_BUFFER_DESC bd = { 0 };
260 bd.Usage = D3D11_USAGE_DEFAULT;
261 bd.ByteWidth =
sizeof(CBNeverChanges);
262 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
263 bd.CPUAccessFlags = 0;
264 D3D11_SUBRESOURCE_DATA initData = { 0 };
265 initData.pSysMem = &buffer;
266 ID3D11Buffer *ptmpCBNeverChanges =
nullptr;
267 hr = m_pDevice->CreateBuffer(&bd, &initData, &ptmpCBNeverChanges);
268 checkDXResult<D3DError>(hr,
"ID3D11Device::CreateBuffer() failed");
269 m_pCBNeverChanges.reset(ptmpCBNeverChanges);
272 D3D11_BUFFER_DESC bd = { 0 };
273 bd.Usage = D3D11_USAGE_DEFAULT;
274 bd.ByteWidth =
sizeof(CBChanges);
275 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
276 bd.CPUAccessFlags = 0;
277 ID3D11Buffer *ptmpCBChanges =
nullptr;
278 hr = m_pDevice->CreateBuffer(&bd,
nullptr, &ptmpCBChanges);
279 checkDXResult<D3DError>(hr,
"ID3D11Device::CreateBuffer() failed");
280 m_pCBChanges.reset(ptmpCBChanges);
287 D3D11_RASTERIZER_DESC rasterDesc;
288 ::ZeroMemory(&rasterDesc,
sizeof(rasterDesc));
289 rasterDesc.FillMode = D3D11_FILL_SOLID;
290 rasterDesc.CullMode = D3D11_CULL_NONE;
291 ID3D11RasterizerState* ptmpRasterizerState =
nullptr;
292 hr = m_pDevice->CreateRasterizerState(&rasterDesc, &ptmpRasterizerState);
293 checkDXResult<D3DError>(hr,
"ID3D11Device::CreateBuffer() failed");
294 m_pRasterizerState.reset(ptmpRasterizerState);
300 D3D11_SAMPLER_DESC sampDesc;
301 ::ZeroMemory(&sampDesc,
sizeof(sampDesc));
302 sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
303 sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
304 sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
305 sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
306 sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
308 sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
309 ID3D11SamplerState *ptmpSamplerState =
nullptr;
310 hr = m_pDevice->CreateSamplerState(&sampDesc, &ptmpSamplerState);
311 checkDXResult<D3DError>(hr,
"ID3D11Device::CreateSamplerState() failed");
312 m_pSamplerState.reset(ptmpSamplerState);
318 D3D11_BLEND_DESC blendDesc;
319 ::ZeroMemory(&blendDesc,
sizeof(blendDesc));
320 blendDesc.AlphaToCoverageEnable = FALSE;
321 blendDesc.IndependentBlendEnable = FALSE;
322 blendDesc.RenderTarget[0].BlendEnable = TRUE;
323 blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
324 blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
325 blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
326 blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
327 blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
328 blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
329 blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
330 ID3D11BlendState* ptmpBlendState =
nullptr;
331 hr = m_pDevice->CreateBlendState(&blendDesc, &ptmpBlendState);
332 checkDXResult<D3DError>(hr,
"ID3D11Device::CreateBlendState() failed");
333 m_pBlendState.reset(ptmpBlendState);
341 ID3D10Multithread *ptmpMt =
nullptr;
342 hr = m_pDevice->QueryInterface(__uuidof(ID3D10Multithread), (
void **)&ptmpMt);
343 checkDXResult<D3DError>(hr,
"QueryInterface(IDXGIDevice1) failed");
345 pMt->SetMultithreadProtected(TRUE);
362 hr = m_pSwapChain->SetFullscreenState(TRUE,
nullptr);
363 if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
368 checkDXResult<D3DError>(hr,
"IDXGISwapChain::SetFullscreenState() failed");
375 void DGraphics::initBackBuffer()
383 ID3D11Texture2D *ptmpBackBuffer =
nullptr;
384 hr = m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (
void **)&ptmpBackBuffer);
385 checkDXResult<D3DError>(hr,
"IDXGISwapChain::GetBuffer() failed");
389 ID3D11RenderTargetView *ptmpRenderTargetView =
nullptr;
390 hr = m_pDevice->CreateRenderTargetView(
391 pBackBuffer.get(),
nullptr, &ptmpRenderTargetView);
392 checkDXResult<D3DError>(hr,
"ID3D11Device::CreateRenderTargetView() failed");
393 m_pContext->OMSetRenderTargets(1, &ptmpRenderTargetView,
nullptr);
394 m_pRenderTargetView.reset(ptmpRenderTargetView);
404 vp.Width =
static_cast<float>(m_param.
w);
405 vp.Height =
static_cast<float>(m_param.
h);
408 m_pContext->RSSetViewports(1, &vp);
418 if (m_pContext !=
nullptr) {
419 m_pContext->ClearState();
421 if (m_pSwapChain !=
nullptr) {
422 m_pSwapChain->SetFullscreenState(FALSE,
nullptr);
429 if (m_pSwapChain ==
nullptr || wParam == SIZE_MINIMIZED) {
433 debug::writef(L
"WM_SIZE %d %d", LOWORD(lParam), HIWORD(lParam));
436 m_pContext->OMSetRenderTargets(0,
nullptr,
nullptr);
437 m_pRenderTargetView.reset();
438 hr = m_pSwapChain->ResizeBuffers(1, 0, 0, BufferFormat, SwapChainFlag);
439 checkDXResult<D3DError>(hr,
"IDXGISwapChain::ResizeBuffers() failed");
443 return DefWindowProc(hWnd, msg, wParam, lParam);
449 m_pContext->ClearRenderTargetView(m_pRenderTargetView.get(), ClearColor);
452 m_pContext->VSSetShader(m_pVertexShader.get(),
nullptr, 0);
453 m_pContext->PSSetShader(m_pPixelShader.get(),
nullptr, 0);
454 ID3D11Buffer *pCBs[2] = { m_pCBNeverChanges.get(), m_pCBChanges.get() };
455 m_pContext->VSSetConstantBuffers(0, 2, pCBs);
457 m_pContext->RSSetState(m_pRasterizerState.get());
458 ID3D11SamplerState *pSamplerState = m_pSamplerState.get();
459 m_pContext->PSSetSamplers(0, 1, &pSamplerState);
460 float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
461 m_pContext->OMSetBlendState(m_pBlendState.get(), blendFactor, 0xffffffff);
464 for (
auto &task : m_drawTaskList) {
467 createCBFromTask(&cbChanges, task);
468 m_pContext->UpdateSubresource(m_pCBChanges.get(), 0,
nullptr, &cbChanges, 0, 0);
470 ID3D11ShaderResourceView *pView = task.pRV.get();
471 m_pContext->PSSetShaderResources(0, 1, &pView);
473 m_pContext->Draw(4, 0);
475 m_drawTaskList.clear();
478 m_pSwapChain->Present(m_param.
vsync ? 1 : 0, 0);
487 D3DX11_IMAGE_INFO imageInfo = { 0 };
488 hr = ::D3DX11GetImageInfoFromMemory(bin.data(), bin.size(),
nullptr,
489 &imageInfo,
nullptr);
490 checkDXResult<D3DError>(hr,
"D3DX11GetImageInfoFromMemory() failed");
491 if (imageInfo.ResourceDimension != D3D11_RESOURCE_DIMENSION_TEXTURE2D) {
492 throwTrace<D3DError>(
"Not 2D Texture", S_OK);
495 ID3D11ShaderResourceView *ptmpRV =
nullptr;
496 hr = ::D3DX11CreateShaderResourceViewFromMemory(m_pDevice.get(), bin.data(), bin.size(),
497 nullptr,
nullptr, &ptmpRV,
nullptr);
498 checkDXResult<D3DError>(hr,
"D3DX11CreateShaderResourceViewFromMemory() failed");
500 return std::make_shared<Texture>(
501 ptmpRV, imageInfo.Width, imageInfo.Height);
506 int sx,
int sy,
int sw,
int sh,
507 int cx,
int cy,
float angle,
float scaleX,
float scaleY,
512 m_drawTaskList.emplace_back(texture->pRV, texture->w, texture->h,
513 dx, dy, lrInv, udInv, sx, sy, sw, sh,
514 cx, cy, scaleX, scaleY, angle, 0x00000000, alpha);
518 uint32_t startChar, uint32_t endChar, uint32_t w, uint32_t h)
523 HFONT htmpFont = ::CreateFont(
524 h, 0, 0, 0, 0, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET,
525 OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
526 FIXED_PITCH | FF_MODERN, fontName);
528 auto fontDel = [](HFONT hFont) { ::DeleteObject(hFont); };
529 std::unique_ptr<std::remove_pointer<HFONT>::type, decltype(fontDel)>
530 hFont(htmpFont, fontDel);
532 HDC htmpDC = ::GetDC(
nullptr);
534 auto dcRel = [](HDC hDC) { ::ReleaseDC(
nullptr, hDC); };
535 std::unique_ptr<std::remove_pointer<HDC>::type, decltype(dcRel)>
538 HFONT tmpOldFont =
static_cast<HFONT
>(::SelectObject(hDC.get(), hFont.get()));
540 auto restoreObj = [&hDC](HFONT oldFont) { ::SelectObject(hDC.get(), oldFont); };
541 std::unique_ptr<std::remove_pointer<HFONT>::type, decltype(restoreObj)>
542 hOldFont(tmpOldFont, restoreObj);
544 TEXTMETRIC tm = { 0 };
546 "GetTextMetrics() failed");
548 std::vector<FontTexture::TexPtr> texList;
549 std::vector<FontTexture::RvPtr> rvList;
550 texList.reserve(endChar - startChar + 1);
551 rvList.reserve(endChar - startChar + 1);
553 for (uint32_t c = startChar; c <= endChar; c++) {
555 GLYPHMETRICS gm = { 0 };
556 const MAT2 mat = { { 0, 1 },{ 0, 0 },{ 0, 0 },{ 0, 1 } };
557 DWORD bufSize = ::GetGlyphOutline(hDC.get(), c, GGO_GRAY8_BITMAP, &gm, 0,
nullptr, &mat);
559 auto buf = std::make_unique<uint8_t[]>(bufSize);
560 DWORD ret = ::GetGlyphOutline(hDC.get(), c, GGO_GRAY8_BITMAP, &gm, bufSize, buf.get(), &mat);
562 uint32_t pitch = (gm.gmBlackBoxX + 3) / 4 * 4;
564 uint32_t destX = gm.gmptGlyphOrigin.x;
565 uint32_t destY = tm.tmAscent - gm.gmptGlyphOrigin.y;
568 D3D11_TEXTURE2D_DESC desc = { 0 };
573 desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
574 desc.SampleDesc.Count = 1;
575 desc.Usage = D3D11_USAGE_DYNAMIC;
576 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
577 desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
578 ID3D11Texture2D *ptmpTex =
nullptr;
579 hr = m_pDevice->CreateTexture2D(&desc,
nullptr, &ptmpTex);
580 checkDXResult<D3DError>(hr,
"ID3D11Device::CreateTexture2D() failed");
582 texList.emplace_back(ptmpTex);
585 D3D11_MAPPED_SUBRESOURCE mapped;
586 UINT subres = ::D3D11CalcSubresource(0, 0, 1);
587 hr = m_pContext->Map(ptmpTex, subres, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
588 checkDXResult<D3DError>(hr,
"ID3D11DeviceContext::Map() failed");
589 uint8_t *pTexels =
static_cast<uint8_t *
>(mapped.pData);
590 ::ZeroMemory(pTexels, w * h * 4);
591 for (uint32_t y = 0; y < gm.gmBlackBoxY; y++) {
592 for (uint32_t x = 0; x < gm.gmBlackBoxX; x++) {
593 if (destX + x >= w || destY + y >= h) {
596 uint32_t alpha = buf[y * pitch + x] * 255 / 64;
597 uint32_t destInd = (((destY + y) * w) + (destX + x)) * 4;
598 pTexels[destInd + 0] = 0;
599 pTexels[destInd + 1] = 0;
600 pTexels[destInd + 2] = 0;
601 pTexels[destInd + 3] = alpha;
604 m_pContext->Unmap(ptmpTex, subres);
607 ID3D11ShaderResourceView *ptmpRV =
nullptr;
608 hr = m_pDevice->CreateShaderResourceView(ptmpTex,
nullptr, &ptmpRV);
609 checkDXResult<D3DError>(hr,
"ID3D11Device::CreateShaderResourceView() failed");
611 rvList.emplace_back(ptmpRV);
615 auto res = std::make_shared<FontTexture>(
616 w, h, startChar, endChar);
617 res->pTexList.swap(texList);
618 res->pRVList.swap(rvList);
623 uint32_t color,
float scaleX,
float scaleY,
float alpha,
624 int *nextx,
int *nexty)
627 if (!::iswspace(c)) {
630 auto &pRV = font->pRVList.at(c - font->startChar);
631 m_drawTaskList.emplace_back(pRV, font->w, font->h,
632 dx, dy,
false,
false, 0, 0, font->w, font->h,
633 0, 0, scaleX, scaleY, 0.0f, color, alpha);
636 if (nextx !=
nullptr) {
637 *nextx = dx + font->w;
639 if (nexty !=
nullptr) {
640 *nexty = dy + font->h;
645 uint32_t color,
int ajustX,
float scaleX,
float scaleY,
float alpha,
646 int *nextx,
int *nexty)
648 while (*str != L
'\0') {
649 drawChar(font, *str, dx, dy, color, scaleX, scaleY, alpha, &dx, nexty);
653 if (nextx !=
nullptr) {
FontResourcePtr loadFont(const wchar_t *fontName, uint32_t startChar, uint32_t endChar, uint32_t w, uint32_t h)
void writef(const wchar_t *fmt,...) noexcept
Write debug message using format string like printf.
std::vector< uint8_t > loadFile(const wchar_t *fileName)
Load file from abstract file system.
void drawTexture(const TextureResourcePtr &texture, int dx, int dy, bool lrInv=false, bool udInv=false, int sx=0, int sy=0, int sw=SrcSizeDefault, int sh=SrcSizeDefault, int cx=0, int cy=0, float angle=0.0f, float scaleX=1.0f, float scaleY=1.0f, float alpha=1.0f)
Draw texture.
void checkDXResult(HRESULT hr, const std::string &msg)
void writeLine(const wchar_t *str=L"") noexcept
Write debug string and new line.
std::shared_ptr< FontResource > FontResourcePtr
LRESULT onSize(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
std::vector< uint8_t > Bytes
File byte sequence. Vector of uint8_t.
char msg[LINE_DATA_SIZE-sizeof(LARGE_INTEGER)-sizeof(uint32_t)]
void drawChar(const FontResourcePtr &font, wchar_t c, int dx, int dy, uint32_t color=0x000000, float scaleX=1.0f, float scaleY=1.0f, float alpha=1.0f, int *nextx=nullptr, int *nexty=nullptr)
std::shared_ptr< TextureResource > TextureResourcePtr
void checkWin32Result(bool cond, const std::string &msg)
void drawString(const FontResourcePtr &font, const wchar_t *str, int dx, int dy, uint32_t color=0x000000, int ajustX=0, float scaleX=1.0f, float scaleY=1.0f, float alpha=1.0f, int *nextx=nullptr, int *nexty=nullptr)
Draw string.
static const int SrcSizeDefault
Use texture size.
TextureResourcePtr loadTexture(const wchar_t *path)
Load a texture.
DGraphics(const GraphicsParam ¶m)
std::unique_ptr< T, ComDeleter > ComPtr
unique_ptr of IUnknown with ComDeleter.