グリグリ動かすようなときには、3Dの方に描いちゃったほうがいいでしょう、ということで
調べてみました。
前回の
画像表示を含む自分用アプリの雛形(4) Direct2D化-3, DXGI
を修正する形で書いてみました。
ヘッダー、グローバル変数の設定
SpliteBatch が、DirectXTkからのものです。
前回のDXGI利用の描画に対して、USE_DIRECTXTKで追加コードを挿入していきます。
# define USE_DIRECTXTK
# ifdef USE_DIRECTXTK
ID3D11DeviceContext *pD3D_DC;
ID3D11Texture2D *pD3D_RT;
ID3D11RenderTargetView *pD3D_RenderTargetView;
ID3D11ShaderResourceView *pD3D_ShaderResourceView;
# include "DirectXTK/SpriteBatch.h"
# include "DirectXTK/WICTextureLoader.h"
# pragma comment(lib, "DirectXTK.lib")
DirectX::SpriteBatch *pSpriteBatch;
# endif
Initialize
スワップチェーンの設定として、DXGI_SWAP_EFFECT_DISCARDを使用します。
(DXGI描画のときも、DXGI_SWAP_EFFECT_DISCARDのほうがいいんじゃね?と思います。)
pD2D_Device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, reinterpret_cast<ID2D1DeviceContext **>(&pDC));
CreateDXGIFactory2(0, IID_PPV_ARGS(&pDXGI_Factory));
DXGI_SWAP_CHAIN_DESC1 swapChainDesc={};
swapChainDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.SwapEffect=DXGI_SWAP_EFFECT_DISCARD; //DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
swapChainDesc.BufferCount=2;
swapChainDesc.SampleDesc.Count=1;
pDXGI_Factory->CreateSwapChainForHwnd(pDXGI_Device, hDlgImg, &swapChainDesc, NULL, NULL, &pDXGI_SwapChain);
pDXGI_SwapChain->GetBuffer(0, IID_PPV_ARGS(&pDXGI_Surface));
D2D1_BITMAP_PROPERTIES1 bitmapPropsDXGI=D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_NONE, D2D_PixelFormat);
bitmapPropsDXGI.bitmapOptions|=(D2D1_BITMAP_OPTIONS_TARGET|D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
pDC->CreateBitmapFromDxgiSurface(pDXGI_Surface, &bitmapPropsDXGI, &pD2D_BitmapDXGI);
pDC->SetTarget(pD2D_BitmapDXGI);
# ifdef USE_DIRECTXTK
pD3D_Device->GetImmediateContext(&pD3D_DC);
pDXGI_SwapChain->GetBuffer(0, IID_PPV_ARGS(&pD3D_RT));
pD3D_Device->CreateRenderTargetView(pD3D_RT, NULL, &pD3D_RenderTargetView);
pD3D_DC->OMSetRenderTargets(1, &pD3D_RenderTargetView, NULL);
D3D11_VIEWPORT vp;
vp.Width=(float)FrameWidth;
vp.Height=(float)FrameHeight;
vp.MinDepth=0.0f; vp.MaxDepth=1.0f; vp.TopLeftX=0; vp.TopLeftY=0;
pD3D_DC->RSSetViewports(1, &vp);
pSpriteBatch=new DirectX::SpriteBatch(pD3D_DC);
# endif
pngファイル読み込み
pngファイルから、テクスチャを生成します。
char ffilename[MAX_PATH];
sprintf(ffilename, "%s\\%s", HomeFolderName, filename);
IStream *pIStream;
HRESULT hr=SHCreateStreamOnFile(ffilename, STGM_READ, &pIStream);
if(hr==S_OK){
IWICBitmapDecoder *pDecoder=NULL;
IWICBitmapFrameDecode *pDecodedFrame=NULL;
pWIC_Factory->CreateDecoderFromStream(pIStream, NULL, WICDecodeMetadataCacheOnLoad, &pDecoder);
pDecoder->GetFrame(0, &pDecodedFrame);
IWICBitmapSource *pWIC_BS=NULL;
WICPixelFormatGUID WIC_PixelFormat=GUID_WICPixelFormat32bppPBGRA;
WICConvertBitmapSource(WIC_PixelFormat, pDecodedFrame, &pWIC_BS);
pDecodedFrame->Release();
pDecoder->Release();
pIStream->Release();
pWIC_BS->GetSize((UINT *)&ImageWidth1, (UINT *)&ImageHeight1);
if(pD2D_Bitmap!=NULL){ pD2D_Bitmap->Release(); pD2D_Bitmap=NULL; }
if(pRT!=NULL) pRT->CreateBitmapFromWicBitmap(pWIC_BS, (ID2D1Bitmap **)&pD2D_Bitmap);
if(pDC!=NULL) pDC->CreateBitmapFromWicBitmap(pWIC_BS, &pD2D_Bitmap);
pWIC_BS->Release();
}
# ifdef USE_DIRETXTK
wchar_t wbuf[256]; MultiByteToWideChar(CP_ACP, 0, ffilename, -1, wbuf, 256);
if(pD3D_ShaderResourceView!=NULL) pD3D_ShaderResourceView->Release();
ID3D11Resource *pD3D_Resource;
DirectX::CreateWICTextureFromFile(pD3D_Device, wbuf, &pD3D_Resource, &pD3D_ShaderResourceView);
ID3D11Texture2D *pD3D_Texture2D; pD3D_Resource->QueryInterface(IID_PPV_ARGS(&pD3D_Texture2D));
CD3D11_TEXTURE2D_DESC TextureDesc; pD3D_Texture2D->GetDesc(&TextureDesc);
pD3D_Resource->Release();
# endif
描画
D2DDeviceContextのかわりに、SpriteBatchを使用します。
# ifdef USE_DIRECTXTK
pSpriteBatch->Begin();
if(pD3D_ShaderResourceView!=NULL) pSpriteBatch->Draw(pD3D_ShaderResourceView, DirectX::XMFLOAT2(0, 0));
pSpriteBatch->End();
# else
pDC->BeginDraw();
if(pD2D_Bitmap!=NULL){
pDC->DrawBitmap(pD2D_Bitmap, D2D1::RectF(0.f, 0.f, (float)ImageWidth1, (float)ImageHeight1),
1.f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR);
}
# endif
pDXGI_SwapChain->Present(1, 0);