Help us understand the problem. What is going on with this article?

画像表示を含む自分用アプリの雛形(7) DirectXTk -SpriteBatchの利用

More than 1 year has passed since last update.

グリグリ動かすようなときには、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);
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away