DIRECT2Dを試す、その2

前回はDirectXの初期化だけでしたが、今回はいよいよDirect2Dを使用していきます。

サンプルコードはこちらを参考。

http://dioltista.blogspot.com/2019/04/c-directx11-direct2ddirectwrite_27.html

前回作成したWindowにテキストを表示します。

※main関数は大して変更していないので省略。

#pragma once

#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"d2d1.lib")
#pragma comment(lib,"dwrite.lib")
#include <d3d11_1.h>
#include <directxcolors.h>
#include <d2d1.h>
#include <dwrite.h>

class DirectX11
{
public:
    DirectX11();
    ~DirectX11();
    HRESULT InitDevice();
    void Render();
private:
    ID3D11Device* pd3dDevice;
    ID3D11Device1* pd3dDevice1;
    ID3D11DeviceContext* pImmediateContext;
    ID3D11DeviceContext1* pImmediateContext1;
    IDXGISwapChain* pSwapChain;
    IDXGISwapChain1* pSwapChain1;
    ID3D11RenderTargetView* pRenderTargetView;

    ID2D1Factory* pD2DFactory;
    IDWriteFactory* pDWriteFactory;
    IDWriteTextFormat* pTextFormat;
    ID2D1RenderTarget* pRT;
    ID2D1SolidColorBrush* pSolidBrush;
    IDXGISurface* pDXGISurface;
};
#include "Main.h"
#include "DirectX.h"

DirectX11::DirectX11()
{
    pd3dDevice = nullptr;
    pd3dDevice1 = nullptr;
    pImmediateContext = nullptr;
    pImmediateContext1 = nullptr;
    pSwapChain = nullptr;
    pSwapChain1 = nullptr;
    pRenderTargetView = nullptr;

    pD2DFactory = nullptr;
    pDWriteFactory = nullptr;
    pTextFormat = nullptr;
    pRT = nullptr;
    pSolidBrush = nullptr;
    pDXGISurface = nullptr;
}

DirectX11::~DirectX11()
{
    if (pDXGISurface) pDXGISurface->Release();
    if (pSolidBrush) pSolidBrush->Release();
    if (pRT) pRT->Release();
    if (pTextFormat) pTextFormat->Release();
    if (pDWriteFactory) pDWriteFactory->Release();
    if (pD2DFactory) pD2DFactory->Release();

    if (pImmediateContext) pImmediateContext->ClearState();

    if (pRenderTargetView) pRenderTargetView->Release();
    if (pSwapChain1) pSwapChain1->Release();
    if (pSwapChain) pSwapChain->Release();
    if (pImmediateContext1) pImmediateContext1->Release();
    if (pImmediateContext) pImmediateContext->Release();
    if (pd3dDevice1) pd3dDevice1->Release();
    if (pd3dDevice) pd3dDevice->Release();
}

HRESULT DirectX11::InitDevice()
{
    HRESULT hr = S_OK;

    RECT rc;
    GetClientRect(Window::GethWnd(), &rc);
    UINT width = rc.right - rc.left;
    UINT height = rc.bottom - rc.top;

    UINT createDeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;

#ifdef _DEBUG
    createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    D3D_DRIVER_TYPE driverTypes[] =
    {
        D3D_DRIVER_TYPE_HARDWARE,
        D3D_DRIVER_TYPE_WARP,
        D3D_DRIVER_TYPE_REFERENCE,
    };
    UINT numDriverTypes = ARRAYSIZE(driverTypes);

    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
    };
    UINT numFeatureLevels = ARRAYSIZE(featureLevels);

    D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
    D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
    for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
    {
        g_driverType = driverTypes[driverTypeIndex];
        hr = D3D11CreateDevice(nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
            D3D11_SDK_VERSION, &pd3dDevice, &g_featureLevel, &pImmediateContext);

        if (hr == E_INVALIDARG)
        {
            hr = D3D11CreateDevice(nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1,
                D3D11_SDK_VERSION, &pd3dDevice, &g_featureLevel, &pImmediateContext);
        }

        if (SUCCEEDED(hr))
            break;
    }
    if (FAILED(hr))
        return hr;

    IDXGIFactory1* dxgiFactory = nullptr;
    {
        IDXGIDevice* dxgiDevice = nullptr;
        hr = pd3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));
        if (SUCCEEDED(hr))
        {
            IDXGIAdapter* adapter = nullptr;
            hr = dxgiDevice->GetAdapter(&adapter);
            if (SUCCEEDED(hr))
            {
                hr = adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory));
                adapter->Release();
            }
            dxgiDevice->Release();
        }
    }
    if (FAILED(hr))
        return hr;

    IDXGIFactory2* dxgiFactory2 = nullptr;
    hr = dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2));
    if (dxgiFactory2)
    {
        hr = pd3dDevice->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&pd3dDevice1));
        if (SUCCEEDED(hr))
        {
            (void)pImmediateContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&pImmediateContext1));
        }

        DXGI_SWAP_CHAIN_DESC1 sd = {};
        sd.Width = width;
        sd.Height = height;
        sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.BufferCount = 1;

        hr = dxgiFactory2->CreateSwapChainForHwnd(pd3dDevice, Window::GethWnd(), &sd, nullptr, nullptr, &pSwapChain1);
        if (SUCCEEDED(hr))
        {
            hr = pSwapChain1->QueryInterface(__uuidof(IDXGISwapChain), reinterpret_cast<void**>(&pSwapChain));
        }

        dxgiFactory2->Release();
    }
    else
    {
        DXGI_SWAP_CHAIN_DESC sd = {};
        sd.BufferCount = 1;
        sd.BufferDesc.Width = width;
        sd.BufferDesc.Height = height;
        sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.BufferDesc.RefreshRate.Numerator = 60;
        sd.BufferDesc.RefreshRate.Denominator = 1;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.OutputWindow = Window::GethWnd();
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.Windowed = TRUE;

        hr = dxgiFactory->CreateSwapChain(pd3dDevice, &sd, &pSwapChain);
    }

    dxgiFactory->MakeWindowAssociation(Window::GethWnd(), DXGI_MWA_NO_ALT_ENTER);

    dxgiFactory->Release();

    if (FAILED(hr))
        return hr;

    ID3D11Texture2D* pBackBuffer = nullptr;
    hr = pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pBackBuffer));
    if (FAILED(hr))
        return hr;

    hr = pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &pRenderTargetView);
    pBackBuffer->Release();
    if (FAILED(hr))
        return hr;

    pImmediateContext->OMSetRenderTargets(1, &pRenderTargetView, nullptr);

    D3D11_VIEWPORT vp;
    vp.Width = (FLOAT)width;
    vp.Height = (FLOAT)height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = 0;
    vp.TopLeftY = 0;
    pImmediateContext->RSSetViewports(1, &vp);

    // Direct2D,DirectWriteの初期化
    hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory);
    if (FAILED(hr))
        return hr;

    hr = pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pDXGISurface));
    if (FAILED(hr))
        return hr;

    FLOAT dpiX;
    FLOAT dpiY;
    //pD2DFactory->GetDesktopDpi(&dpiX, &dpiY);★
    dpiX = (FLOAT)GetDpiForWindow(GetDesktopWindow());
    dpiY = dpiX;

    D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), dpiX, dpiY);

    hr = pD2DFactory->CreateDxgiSurfaceRenderTarget(pDXGISurface, &props, &pRT);
    if (FAILED(hr))
        return hr;

    hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&pDWriteFactory));
    if (FAILED(hr))
        return hr;

    //関数CreateTextFormat()
    //第1引数:フォント名(L"メイリオ", L"Arial", L"Meiryo UI"等)
    //第2引数:フォントコレクション(nullptr)
    //第3引数:フォントの太さ(DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_WEIGHT_BOLD等)
    //第4引数:フォントスタイル(DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STYLE_OBLIQUE, DWRITE_FONT_STYLE_ITALIC)
    //第5引数:フォントの幅(DWRITE_FONT_STRETCH_NORMAL,DWRITE_FONT_STRETCH_EXTRA_EXPANDED等)
    //第6引数:フォントサイズ(20, 30等)
    //第7引数:ロケール名(L"")
    //第8引数:テキストフォーマット(&g_pTextFormat)
    hr = pDWriteFactory->CreateTextFormat(L"メイリオ", nullptr, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 20, L"", &pTextFormat);
    if (FAILED(hr))
        return hr;

    //関数SetTextAlignment()
    //第1引数:テキストの配置(DWRITE_TEXT_ALIGNMENT_LEADING:前, DWRITE_TEXT_ALIGNMENT_TRAILING:後, DWRITE_TEXT_ALIGNMENT_CENTER:中央)
    hr = pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);
    if (FAILED(hr))
        return hr;

    //関数CreateSolidColorBrush()
    //第1引数:フォント色(D2D1::ColorF(D2D1::ColorF::Black):黒, D2D1::ColorF(D2D1::ColorF(0.0f, 0.2f, 0.9f, 1.0f)):RGBA指定)
    hr = pRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &pSolidBrush);
    if (FAILED(hr))
        return hr;

    return S_OK;
}

void DirectX11::Render()
{
    pImmediateContext->ClearRenderTargetView(pRenderTargetView, DirectX::Colors::Aquamarine);

    // テキストの描画
    WCHAR wcText1[] = L" 親譲りの無鉄砲で小供の時から損ばかりしている。小学校に居る時分学校の二階から";
    WCHAR wcText2[] = L"飛び降りて一週間ほど腰を抜かした事がある。なぜそんな無闇をしたと聞く人があるか";
    WCHAR wcText3[] = L"も知れぬ。別段深い理由でもない。新築の二階から首を出していたら、同級生の一人が";
    WCHAR wcText4[] = L"冗談に、いくら威張っても、そこから飛び降りる事は出来まい。弱虫やーい。と囃した";
    WCHAR wcText5[] = L"からである。小使に負ぶさって帰って来た時、おやじが大きな眼をして二階ぐらいから";
    WCHAR wcText6[] = L"飛び降りて腰を抜かす奴があるかと云ったから、この次は抜かさずに飛んで見せますと";
    WCHAR wcText7[] = L"答えた。";

    pRT->BeginDraw();
    pSolidBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Blue));//フォント色変更:青
    pRT->DrawText(wcText1, ARRAYSIZE(wcText1) - 1, pTextFormat, D2D1::RectF(0, 0, 800, 20), pSolidBrush, D2D1_DRAW_TEXT_OPTIONS_NONE);
    pRT->DrawText(wcText2, ARRAYSIZE(wcText2) - 1, pTextFormat, D2D1::RectF(0, 20, 800, 40), pSolidBrush, D2D1_DRAW_TEXT_OPTIONS_NONE);
    pSolidBrush->SetOpacity(0.7f);//フォントの透明度変更:70%
    pRT->DrawText(wcText3, ARRAYSIZE(wcText3) - 1, pTextFormat, D2D1::RectF(0, 40, 800, 60), pSolidBrush, D2D1_DRAW_TEXT_OPTIONS_NONE);
    pSolidBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Black));//フォント色変更:黒
    pRT->DrawText(wcText4, ARRAYSIZE(wcText4) - 1, pTextFormat, D2D1::RectF(0, 60, 800, 80), pSolidBrush, D2D1_DRAW_TEXT_OPTIONS_NONE);
    pRT->DrawText(wcText5, ARRAYSIZE(wcText5) - 1, pTextFormat, D2D1::RectF(0, 80, 800, 100), pSolidBrush, D2D1_DRAW_TEXT_OPTIONS_NONE);
    pSolidBrush->SetOpacity(1.0f);//フォントの透明度変更:100%
    pRT->DrawText(wcText6, ARRAYSIZE(wcText6) - 1, pTextFormat, D2D1::RectF(0, 100, 800, 120), pSolidBrush, D2D1_DRAW_TEXT_OPTIONS_NONE);
    pRT->DrawText(wcText7, ARRAYSIZE(wcText7) - 1, pTextFormat, D2D1::RectF(0, 120, 800, 140), pSolidBrush, D2D1_DRAW_TEXT_OPTIONS_NONE);
    pRT->EndDraw();

    pSwapChain->Present(0, 0);
}

サンプルと違うのは★の箇所。

GetDesktopDpi()を使用するのは非推奨らしく、ビルドエラーとなります。

そこで参照したのは以下のページ。

https://learn.microsoft.com/en-us/answers/questions/170411/creating-a-simple-direct2d-application-id2d1factor

    dpiX = (FLOAT)GetDpiForWindow(GetDesktopWindow());
    dpiY = dpiX;

に置き換えることでビルドが通ります。

経済ニュース(01/30)

東北電力の3月分の電気料金 2年ぶりの低水準続く|NHK 秋田県のニュース – nhk.or.jp

【NHK】東北電力はことし3月分の電気料金を発表し、多くの家庭が利用する国の認可を受けたプランの場合、政府の負担軽減策によって、平均的な家庭の電気料…

富裕層開拓の好機!?金融業界が税制改正の「贈与ニーズ急増」狙い虎視眈々 – ダイヤモンド・オンライン

生前贈与のルール改正時期が2024年に決まり、金融業界が沸いている。23年中の「駆け込み贈与」需要が見込めることに加え、富裕層や事業者向けの「相続時精算課税」制度の使い勝手が向上するからだ。両制度の利用を促すことは顧客資産に食い込む好機。税制改正をビジネスチャンスとして狙う金融業界の動向を追った。

電気代値上げどうなる?30日から本格審査 過去は圧縮も – 日本経済新聞

30日から大手電力会社が申請した家庭向け電気料金の値上げの審査が本格化する。住民などから広く意見を聞く公聴会がまず沖縄電力から始まる。いつ、どれぐらい料金が上がるのか。値上げの背景と今後の見通しをまとめた。・なぜ電気代が上がる?・値上げ幅はどうなる?・政府の電気代への補助金はいつから?

世界最大の純資産国、通貨に底力はあるか – 日本経済新聞

今年の金融市場はここまで、昨年のような大幅な円安進行を見せていない。日銀の緩和修正観測などを反映し、米国と日本の金利差が拡大しにくくなっていることが主因の一つだ。昨年は、世界最大の対外純資産を持つ日本の通貨が一本調子に売られることに疑問の声も上がったが、そもそも純資産国通貨は買われる通貨なのかといった声も聞かれる。最大の純資産国通貨であることは何を意味するのか。日本の対外純資産は、日本の企業や

トヨタ社長の電撃交代!「章男会長マター」として残る日野自の行く末は – ダイヤモンド・オンライン

トヨタの豊田章男社長が交代する。その発表は電撃的なものだった。問題として残るのが、不正問題に揺れる日野自動車の処遇だ。

スタートアップが勘違いしやすい「ブルーオーシャン戦略」の盲点 – ダイヤモンド・オンライン

【日経新聞掲載&有力紙書評続々】話題沸騰! たちまち3刷! 注目著者、初の著書! 創業9年目で売上300億円にしたアンカー・ジャパンCEOの猿渡歩が初めて語る“大逆転の新手法”。誰でも、何歳からでも、後発でも圧倒的速さで成長できるシンプルな習慣を初公開。27歳入社→33歳アンカーグループ最年少役員→34歳アンカー・ジャパンCEOになった著者が、参入したほぼ全製品カテゴリーでオンラインシェア1位になった秘密を解くカギは「6つのシンプルな習慣」──全体最適の習慣/バリューを出す習慣/学ぶ習慣/因数分解の習慣/1%にこ…

新型アルファードに久々ロータリーの復活!! 今年大注目の国内外メーカー5選(ベストカーWeb) | 自動車情報サイト【新車・中古車】 – carview! – carview!

2023年がスタートして、早1カ月。昨年2022年は、話題の新型ミドルクラスミニバンや軽BEVの登場、そして老舗セダンの大改革などが大いに話題となったクルマ業界。今年2023年も新型車の登場は多く計画されているが、なかでも今年注目すべきメ…

「金持ちは長財布も持っている」はもう古い? 最近の金持ちが持ち歩くものって? – Yahoo!ファイナンス

以前、「お金持ちは長財布を持っている」と話題になったことがありますが、それは、旧タイプのお金持ちの話。新タイプのお金持ちは、財布そのものを持ち歩かなくなりつつあります。 旧タイプのお金持ちは「現金」を持ち歩くたとえば、昔のお金持ちが持ち歩いていたものといえば、ルイ・ヴィトンのポー…

【マツダ2 改良新型】メッシュグリルと6MTは健在…スポルト+[詳細写真] – レスポンス

マツダは1月27日、コンパクトカーの『マツダ2』の改良新型を発表し、予約受付を開始した。今回は先代で人気を集めた「ブラックトーンエディション」のスポーティさをさらに高めたディーゼルエンジンモデル『XD SPORT+(クロスディー スポルトプラス)』を紹介する。

これは絶対に予測不可能! バーで見つかった忘れ物のバッグ、その驚きの中身とは – Newsweekjapan

<夜遊びに持っていくバッグには何を入れる? カードやメイク用品などの代わりにぎっしり詰まっていたものとは?> 女性はどこにでも小さなバッグを持って行くことが多いが、泥酔して店にバッグを忘れて帰ってしまうこともある。あるバーテンダーが最近、そんな忘れ物のバッグを発見。中身を確認したところ、衝撃的なものを目にしたという。 ■【動画】絶対に予想できない…バーに置き忘れられたバッグの中に入っていたものとは? 夜に遊びに出かける際、多くの女性がバッグに入れるのが銀行のカードやメイク用品、携帯電話だろう。だがその忘れ物の…

インナーイヤー型のイヤホン、私にとっての正解はコレでした – GIZMODO JAPAN

イヤホンに求める条件、3つ挙げるとしたらなんでしょう。私の場合は完全ワイヤレス・装着感が快適・見た目がカッコいいの3つ。なかなか条件に合ったものがなく、かれこれ4年近く同じイヤホンを愛用していたのですが、ついに出会っちゃいました。クリア×スティック型、絶対カッコいい Nothingから2022年の11月に新しく登場した「Ear (stick) 」というモデル。価格は16,800円(税込)です。

東北新幹線の福島トンネル 天井付近のコンクリート落下|NHK 福島県のニュース – nhk.or.jp

【NHK】29日未明、東北新幹線の福島駅近くのトンネル内で、天井付近のコンクリートの一部がはがれ、線路上に落ちているのが見つかりました。

29日午…

夫は69歳年金受給者、私は58歳無職です。夫と年齢差がある私は年金を繰上げ受給したほうがいい? – Yahoo!ファイナンス

老後のお金や生活費が足りるのか不安ですよね。老後生活の収入の柱になるのが「老齢年金」ですが、年金制度にまつわることは、難しい用語が多くて、ますます不安になってしまう人もいるのではないでしょうか。そんな年金初心者の方の疑問に専門家が回答します。今回は、年金のもらい方についての相談で…

前澤友作氏「シンママ婚活アプリ」炎上の重大盲点 – 東洋経済オンライン

実業家の前澤友作氏が監修したシングルマザーを対象とする婚活・恋活マッチングアプリ「コアリー(coary)」が1月17日リリースされた。ところがその直後に炎上し、翌日の1月18日には配信停止に至った。「#コアリー…

日本企業製の大型EVバス、伊予鉄でついにデビュー 新興EVモーターズ・ジャパン製 全国初 – 乗りものニュース

伊予鉄が広告塔役!

シリーズハイブリッド追加で人気再燃!「ダイハツ・ロッキー」【最新コンパクトカー 車種別解説】 – MotorFan[モーターファン]

トヨタ・ライズとともに売れ行き好調な「ダイハツ・ロッキー」。フロントフェイスがクールなイメージのライズに対して、ロッキーはアクティブで力強いフェイスが特徴だ。室内と荷室の広さは特筆モノ。どのパワーユニットを選択しても軽量ボディでスムーズで快適な操縦性、新たに追加された安全機能も併せて、SUV入門車として最適な一台だといえるだろう。 REPORT:岡島裕二(本文)/工藤貴之(写真解説) PHOTO:中野幸次 MODEL:河辺ほのか

47歳、貯金700万円。夫の仕事が安定せず、月収は20万円前後になりそうです – Yahoo!ファイナンス

住宅ローンは夫80歳まであります皆さんから寄せられた家計の悩みにお答えする、その名も「マネープランクリニック」。今回のご相談者は、コロナ禍により夫の仕事が安定せず、収入も少なくなることで悩む47歳の女性です。ファイナンシャル・プランナーの深野康彦さんがアドバイスします。相談者困っ…

おおカッコいい!! イメチェンで新型プリウスが燃費スペシャルをやめたワケとは? – ベストカーWeb

2022年11月に発表された新型プリウスは、これまでとは大きくコンセプトを変更していた。その一番の驚きは、全高を低めたシャープなスタイリングと、2Lエンジンを追加してパワーアップを図ったことだ。なぜプリウスは燃費スペシャルをやめたのだろうか?