LoginSignup
1
2

More than 5 years have passed since last update.

画像表示を含む自分用アプリの雛形(5) DirectCompositionの使用メモ書きかけ

Posted at

まだまだ続きます。DirectCompositionを絡めた表示に修正してみます。
自分でも未消化なので、まだメモ止まりです。。。
用語が決まっていないと説明しにくいです。

Initialize()

下記3種で比較します。

USE_CONTEXT:
(前回のDXGIスワップチェーン描画)
DXGIスワップチェーンを作成し、そのサーファスをデバイスコンテキストに割り当てる

USE_DCOMP1:
DirectCompositionの、HWND = Target -> Visual -> Content の階層構造において、
新規に作成したサーファスをContentとして割り当てる

USE_DCOMP2:
DXGIスワップチェーンを作成し、そのサーファスをデバイスコンテキストに割り当てるとともに、
DirectCompositionの、HWND = Target -> Visual -> Content の階層構造において、
DXGIスワップチェーンをContentとしても割り当てる

#include <dcomp.h>
#pragma comment(lib, "dcomp.lib")

IDCompositionDesktopDevice *pDComp_Device;
IDCompositionTarget        *pDComp_Target;
IDCompositionVisual2       *pDComp_RootVisual;
IDCompositionSurface       *pDComp_Surface;

//#define  USE_CONTEXT
//#define  USE_DCOMP1
#define    USE_DCOMP2
#ifdef USE_CONTEXT
  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_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);
#endif

#ifdef USE_DCOMP1
  DCompositionCreateDevice2(pD2D_Device, IID_PPV_ARGS(&pDComp_Device));
  pDComp_Device->QueryInterface(IID_PPV_ARGS(&pDComp_DeviceEffect));
  pDComp_Device->CreateTargetForHwnd(hDlgImg, TRUE, &pDComp_Target);
  pDComp_Device->CreateVisual(&pDComp_RootVisual);
  pDComp_Device->CreateSurface(FrameWidth, FrameHeight, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_ALPHA_MODE_IGNORE, &pDComp_Surface);
  pDComp_Target->SetRoot(pDComp_RootVisual);
  pDComp_RootVisual->SetContent(pDComp_Surface);
#endif

#ifdef USE_DCOMP2

  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_FLIP_SEQUENTIAL;
  swapChainDesc.BufferCount=2;
  swapChainDesc.SampleDesc.Count=1;
  swapChainDesc.Width=FrameWidth;
  swapChainDesc.Height=FrameHeight;
  pDXGI_Factory->CreateSwapChainForComposition(pDXGI_Device, &swapChainDesc, 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);

  DCompositionCreateDevice2(pD2D_Device, IID_PPV_ARGS(&pDComp_Device));
  pDComp_Device->QueryInterface(IID_PPV_ARGS(&pDComp_DeviceEffect));
  pDComp_Device->CreateTargetForHwnd(hDlgImg, TRUE, &pDComp_Target);
  pDComp_Device->CreateVisual(&pDComp_RootVisual);
  pDComp_Device->CreateSurface(FrameWidth, FrameHeight, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_ALPHA_MODE_IGNORE, &pDComp_Surface);
  pDComp_Target->SetRoot(pDComp_RootVisual);
  pDComp_RootVisual->SetContent(pDXGI_SwapChain);
  pDComp_Device->Commit();
#endif

描画処理

USE_CONTEXT, USE_DCOMP2:
DXGIスワップチェーンから派生したデバイスコンテキストに対して描画処理し、Presentする

USE_DCOMP1:
DirectCompositionのContentから一時的に作成したデバイスコンテキストに対して描画処理し、Commitする

#if defined USE_CONTEXT
      pDC->BeginDraw();
      pDC->SetTransform(D2D1::Matrix3x2F::Identity());
      pDC->Clear(D2D1::ColorF(D2D1::ColorF::Black));
      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);
      }
      wchar_t wbuf[256]; MultiByteToWideChar(CP_ACP, 0, "test", -1, wbuf, 256);
      pDC->DrawText(wbuf, wcslen(wbuf), pFont, D2D1::RectF(0, 0, 100, 20), pBrush);
      pDC->EndDraw();

#elif defined USE_DCOMP1
      POINT offset={};
      ID2D1DeviceContext *pDCtemp;
      pDComp_Surface->BeginDraw(NULL, IID_PPV_ARGS(&pDCtemp), &offset);
      pDCtemp->SetTransform(D2D1::Matrix3x2F::Translation((float)offset.x, (float)offset.y));
      pDCtemp->Clear(D2D1::ColorF(D2D1::ColorF::Black));
      if(pD2D_Bitmap!=NULL){
        pDCtemp->DrawBitmap(pD2D_Bitmap, D2D1::RectF(0.f, 0.f, (float)ImageWidth1, (float)ImageHeight1),
                            1.f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR);
      }
      wchar_t wbuf[256]; MultiByteToWideChar(CP_ACP, 0, "test", -1, wbuf, 256);
      pDCtemp->DrawText(wbuf, wcslen(wbuf), pFont, D2D1::RectF(0, 0, 100, 20), pBrush);
      pDComp_Surface->EndDraw();
      pDCtemp->Release();

#elif defined USE_DCOMP2
      pDC->BeginDraw();
      pDC->SetTransform(D2D1::Matrix3x2F::Identity());
      pDC->Clear(D2D1::ColorF(D2D1::ColorF::Black));
      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);
      }
      wchar_t wbuf[256]; MultiByteToWideChar(CP_ACP, 0, "test", -1, wbuf, 256);
      pDC->DrawText(wbuf, wcslen(wbuf), pFont, D2D1::RectF(0, 0, 100, 20), pBrush);
      pDC->EndDraw();
#endif

#ifdef defined USE_CONTEXT || defined USE_DCOMP2
      pDXGI_SwapChain->Present(1, 0);
#elif defined USE_DCOMP1
      pDComp_Device->Commit();
#endif
      ValidateRect(hDlgImg, NULL);
    }
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2