このブログを検索

2019年4月20日土曜日

【C++】 DirectX11の初期化

【C++】 DirectX11の初期化
(2019年4月20日)


■使用ソフト
・Visual Studio Community 2019


■言語
・C/C++


■Windows SDK バージョン
・10.0.17763.0
 ※Windows SDK バージョンの変更方法


■手順
1.基本的には以下の流れ参照
【C++】 メッセージボックスの作成

2.C++ファイル(.cpp)を以下のとおり変更する。

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


//--------------------------------------------------------------------------------------
// グローバル変数
//--------------------------------------------------------------------------------------
HINSTANCE g_hInst = nullptr;
HWND g_hWnd = nullptr;
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device* g_pd3dDevice = nullptr;
ID3D11Device1* g_pd3dDevice1 = nullptr;
ID3D11DeviceContext* g_pImmediateContext = nullptr;
ID3D11DeviceContext1* g_pImmediateContext1 = nullptr;
IDXGISwapChain* g_pSwapChain = nullptr;
IDXGISwapChain1* g_pSwapChain1 = nullptr;
ID3D11RenderTargetView* g_pRenderTargetView = nullptr;


//--------------------------------------------------------------------------------------
// 前方宣言
//--------------------------------------------------------------------------------------
HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow);
HRESULT InitDevice();
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void Render();
void CleanupDevice();


int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    if (FAILED(InitWindow(hInstance, nCmdShow)))
        return 0;

    if (FAILED(InitDevice()))
    {
        CleanupDevice();
        return 0;
    }

    // メインメッセージループ
    MSG msg = { 0 };
    while (WM_QUIT != msg.message)
    {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            Render();
        }
    }

    CleanupDevice();

    return (int)msg.wParam;
}


HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow)
{
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = nullptr;
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = nullptr;
    wcex.lpszClassName = L"WindowClass";
    wcex.hIconSm = nullptr;
    if (!RegisterClassEx(&wcex))
        return E_FAIL;

    g_hInst = hInstance;
    RECT rc = { 0, 0, 800, 600 };
    AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
    g_hWnd = CreateWindow(L"WindowClass", L"DirectX11の初期化",
        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
        CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, hInstance,
        nullptr);
    if (!g_hWnd)
        return E_FAIL;

    ShowWindow(g_hWnd, nCmdShow);

    return S_OK;
}


HRESULT InitDevice()
{
    HRESULT hr = S_OK;

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

    UINT createDeviceFlags = 0;
#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);

    for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
    {
        g_driverType = driverTypes[driverTypeIndex];
        hr = D3D11CreateDevice(nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
            D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext);

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

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

    IDXGIFactory1* dxgiFactory = nullptr;
    {
        IDXGIDevice* dxgiDevice = nullptr;
        hr = g_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 = g_pd3dDevice->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1));
        if (SUCCEEDED(hr))
        {
            (void)g_pImmediateContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_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(g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1);
        if (SUCCEEDED(hr))
        {
            hr = g_pSwapChain1->QueryInterface(__uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_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 = g_hWnd;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.Windowed = TRUE;

        hr = dxgiFactory->CreateSwapChain(g_pd3dDevice, &sd, &g_pSwapChain);
    }

    dxgiFactory->MakeWindowAssociation(g_hWnd, DXGI_MWA_NO_ALT_ENTER);

    dxgiFactory->Release();

    if (FAILED(hr))
        return hr;

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

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

    g_pImmediateContext->OMSetRenderTargets(1, &g_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;
    g_pImmediateContext->RSSetViewports(1, &vp);

    return S_OK;
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }

    return 0;
}


void Render()
{
    g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, DirectX::Colors::Aquamarine);
    g_pSwapChain->Present(0, 0);
}


void CleanupDevice()
{
    if (g_pImmediateContext) g_pImmediateContext->ClearState();

    if (g_pRenderTargetView) g_pRenderTargetView->Release();
    if (g_pSwapChain1) g_pSwapChain1->Release();
    if (g_pSwapChain) g_pSwapChain->Release();
    if (g_pImmediateContext1) g_pImmediateContext1->Release();
    if (g_pImmediateContext) g_pImmediateContext->Release();
    if (g_pd3dDevice1) g_pd3dDevice1->Release();
    if (g_pd3dDevice) g_pd3dDevice->Release();
}

3.ウィンドウが表示される。

【C++】 fputwsファイル書き込み

【C++】 fputwsファイル書き込み
(2019年4月20日)


■使用ソフト
・Visual Studio Community 2019


■言語
・C/C++


■Windows SDK バージョン
・10.0.17763.0
 ※Windows SDK バージョンの変更方法


■手順
1.基本的には以下の流れ参照
【C++】 メッセージボックスの作成

2.C++ファイル(.cpp)を以下のとおり変更する。

#include <windows.h>
#include <wchar.h>
#include <stdio.h>
#include <locale.h>

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    FILE* fp;
    WCHAR wcText[] = L"おはよう";

    setlocale(LC_ALL, "japanese");
    if (_wfopen_s(&fp, L"あいさつ.txt", L"w") != 0) return 0;
    if (fp == 0) return 0;
    fputws(wcText, fp);
    fputws(L"\n", fp);
    fputws(L"こんにちは", fp);
    fclose(fp);

    MessageBox(NULL, L"出力完了しました", L"fputws", MB_OK);

    return 0;
}

3.プロジェクトがあるフォルダに「あいさつ.txt」が作成される。



【C++】 fgetwsファイル読み込み

【C++】 fgetwsファイル読み込み
(2019年4月20日)


■使用ソフト
・Visual Studio Community 2019


■言語
・C/C++


■Windows SDK バージョン
・10.0.17763.0
 ※Windows SDK バージョンの変更方法


■手順
1.基本的には以下の流れ参照
【C++】 メッセージボックスの作成

2.メモ帳で「極秘.txt」ファイルを作成し、プロジェクトがあるフォルダに入れる。
※文字コード「ANSI」で保存

極秘.txt
給与明細
1000円



3.C++ファイル(.cpp)を以下のとおり変更する。

#include <windows.h>
#include <wchar.h>
#include <stdio.h>
#include <locale.h>

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    FILE* fp;
    WCHAR wcText1[256], wcText2[256];

    setlocale(LC_ALL, "japanese");
    if (_wfopen_s(&fp, L"極秘.txt", L"r") != 0) return 0;
    if (fp == 0) return 0;
    fgetws(wcText1, 256, fp);
    fgetws(wcText2, 256, fp);
    fclose(fp);

    MessageBox(NULL, wcText2, wcText1, MB_OK);

    return 0;
}

4.テキストファイルの内容が表示される。

2019年4月16日火曜日

【C++】 std::vector動的3次元配列

【C++】 std::vector動的3次元配列
(2019年4月16日)


■使用ソフト
・Visual Studio Community 2019


■言語
・C/C++


■Windows SDK バージョン
・10.0.17763.0
 ※Windows SDK バージョンの変更方法


■手順

以下の2種類の方法を記載

emplace_back
resize


<emplace_back>

1.基本的には以下の流れ参照
【C++】 メッセージボックスの作成

2.C++ファイル(.cpp)を以下のとおり変更する。

#include <windows.h>
#include <wchar.h>
#include <vector>

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    WCHAR wcText[256];
    /*data[0][0][0]=3, data[1][0][0]=3, data[0][1][0]=3, data[1][1][0]=3,
      data[0][0][1]=3, data[1][0][1]=3, data[0][1][1]=3, data[1][1][1]=3で初期化

      data(X, std::vector<std::vector<int> >(Y, std::vector<int>(Z, S)))→data[X][Y][Z]全てSで初期化*/
    std::vector<std::vector<std::vector<int> > > data(2, std::vector<std::vector<int> >(2, std::vector<int>(2, 3)));

    data[0][0].emplace_back(6);//data[0][0][2]=6を追加
    data[0][0].emplace_back(7);//data[0][0][3]=7を追加
    data[0].emplace_back(1, 4);//data[0][2][0]=4を追加
    data[0].emplace_back(1, 5);//data[0][3][0]=5を追加
    //data[2][0][0]=8, data[2][1][0]=8, data[2][0][1]=8, data[2][1][1]=8を追加
    data.emplace_back(std::vector<std::vector<int> >(2, std::vector<int>(2, 8)));

    swprintf(wcText, 256, L"%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", data[0][0][0], data[1][0][0], data[0][1][0], data[1][1][0],
        data[0][0][1], data[1][0][1], data[0][1][1], data[1][1][1], data[0][0][2], data[0][0][3], data[0][2][0], data[0][3][0],
        data[2][0][0], data[2][1][0], data[2][0][1], data[2][1][1]);

    MessageBox(NULL, wcText, L"vector動的3次元配列", MB_OK);

    return 0;
}

配列イメージ

3.std::vector動的3次元配列


<resize>

1.基本的には以下の流れ参照
【C++】 メッセージボックスの作成

2.C++ファイル(.cpp)を以下のとおり変更する。

#include <windows.h>
#include <wchar.h>
#include <vector>

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    WCHAR wcText[256];
    /*data[0][0][0]=3, data[1][0][0]=3, data[0][1][0]=3, data[1][1][0]=3,
      data[0][0][1]=3, data[1][0][1]=3, data[0][1][1]=3, data[1][1][1]=3で初期化

      data(X, std::vector<std::vector<int> >(Y, std::vector<int>(Z, S)))→data[X][Y][Z]全てSで初期化*/
    std::vector<std::vector<std::vector<int> > > data(2, std::vector<std::vector<int> >(2, std::vector<int>(2, 3)));

    //data.resize(X, std::vector<std::vector<int> >(Y, std::vector<int>(Z, T)))→data[X][Y][Z]でサイズ変更し増えた分を全てTで初期化*/
    data.resize(3, std::vector<std::vector<int> >(2, std::vector<int>(2, 9)));

    swprintf(wcText, 256, L"%d %d %d %d %d %d %d %d %d %d %d %d", data[0][0][0], data[1][0][0], data[0][1][0], data[1][1][0],
        data[0][0][1], data[1][0][1], data[0][1][1], data[1][1][1], data[2][0][0], data[2][1][0], data[2][0][1], data[2][1][1]);

    MessageBox(NULL, wcText, L"vector動的3次元配列", MB_OK);

    return 0;
}

配列イメージ

3.std::vector動的3次元配列

2019年4月14日日曜日

【C++】 std::vector動的2次元配列

【C++】 std::vector動的2次元配列
(2019年4月14日)


■使用ソフト
・Visual Studio Community 2019


■言語
・C/C++


■Windows SDK バージョン
・10.0.17763.0
 ※Windows SDK バージョンの変更方法


■手順

以下の2種類の方法を記載

emplace_back
resize


<emplace_back>

1.基本的には以下の流れ参照
【C++】 メッセージボックスの作成

2.C++ファイル(.cpp)を以下のとおり変更する。

#include <windows.h>
#include <wchar.h>
#include <vector>

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    WCHAR wcText[256];
    /*data[0][0]=3, data[1][0]=3, data[0][1]=3, data[1][1]=3で初期化

      data(X, std::vector<int>(Y, S))→data[X][Y]全てSで初期化*/
    std::vector<std::vector<int> > data(2, std::vector<int>(2, 3));

    data[0].emplace_back(4);//data[0][2]=4を追加
    data[0].emplace_back(5);//data[0][3]=5を追加
    //data[2][0]=8, data[2][1]=8を追加
    data.emplace_back(std::vector<int>(2, 8));

    swprintf(wcText, 256, L"%d %d %d %d %d %d %d %d", data[0][0], data[1][0], data[0][1], data[1][1],
        data[0][2], data[0][3], data[2][0], data[2][1]);

    MessageBox(NULL, wcText, L"vector動的2次元配列", MB_OK);

    return 0;
}

配列イメージ


3.std::vector動的2次元配列


<resize>

1.基本的には以下の流れ参照
【C++】 メッセージボックスの作成

2.C++ファイル(.cpp)を以下のとおり変更する。

#include <windows.h>
#include <wchar.h>
#include <vector>

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    WCHAR wcText[256];
    /*data[0][0]=3, data[1][0]=3, data[0][1]=3, data[1][1]=3で初期化

      data(X, std::vector<int>(Y, S))→data[X][Y]全てSで初期化*/
    std::vector<std::vector<int> > data(2, std::vector<int>(2, 3));

    //data.resize(X, std::vector<int>(Y, T))→data[X][Y]でサイズ変更し増えた分を全てTで初期化*/
    data.resize(3, std::vector<int>(2, 9));

    swprintf(wcText, 256, L"%d %d %d %d %d %d", data[0][0], data[1][0], data[0][1], data[1][1],
        data[2][0], data[2][1]);

    MessageBox(NULL, wcText, L"vector動的2次元配列", MB_OK);

    return 0;
}

配列イメージ


3.std::vector動的2次元配列

2019年4月13日土曜日

【C++】 std::vector動的配列

【C++】 std::vector動的配列
(2019年4月13日)


■使用ソフト
・Visual Studio Community 2019


■言語
・C/C++


■Windows SDK バージョン
・10.0.17763.0
 ※Windows SDK バージョンの変更方法


■手順
1.基本的には以下の流れ参照
【C++】 メッセージボックスの作成

2.C++ファイル(.cpp)を以下のとおり変更する。

#include <windows.h>
#include <wchar.h>
#include <vector>

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    WCHAR wcText[256];

    std::vector<int> data1(3, 0);//配列data1:0 0 0
    std::vector<int> data2(3, 1);//配列data2:1 1 1

    data1.push_back(6);//配列data1の末尾に6を追加する:0 0 0 6
    data1.push_back(7);//配列data1の末尾に7を追加する:0 0 0 6 7
    data1.pop_back();//配列data1の末尾の1文字を削除する:0 0 0 6
    data1.insert(data1.begin() + 1, 1);//配列data1の最初+1の場所に1を挿入する:0 1 0 0 6
    data1.erase(data1.begin() + 2);//配列data1の最初+2の場所を削除する:0 1 0 6
    data1.insert(data1.end(), data2.begin(), data2.end());//配列data1の最後に配列data2の最初から最後までを挿入する:0 1 0 6 1 1 1

    swprintf(wcText, 256, L"%d %d %d %d %d %d %d", data1[0], data1[1], data1[2], data1[3], data1[4], data1[5], data1[6]);

    MessageBox(NULL, wcText, L"std::vector動的配列", MB_OK);

    return 0;
}

3.std::vector動的配列

2019年4月12日金曜日

【C++】 std::wstringによる文字列の表示

【C++】 std::wstringによる文字列の表示
(2019年4月12日)


■使用ソフト
・Visual Studio Community 2019


■言語
・C/C++


■Windows SDK バージョン
・10.0.17763.0
 ※Windows SDK バージョンの変更方法


■手順
1.基本的には以下の流れ参照
【C++】 メッセージボックスの作成

2.C++ファイル(.cpp)を以下のとおり変更する。

#include <windows.h>
#include <wchar.h>
#include <string>

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    WCHAR wcText[256];
    WCHAR wcText2[256];

    std::wstring str1;//空の文字列で初期化:""
    std::wstring str2(L"よろしく");

    //「よ」を5個つなげる:"よよよよよ"
    for (int i = 0; i < 5; i++)
    {
        str1 += L"よ";
    }
    str1 = str1 + str2;//str1にstr2をつなげる:"よよよよよよろしく"
    str1.pop_back();//末尾の1文字を削除する:"よよよよよよろし"
    str1.pop_back();//末尾の1文字を削除する:"よよよよよよろ"

    swprintf(wcText, 256, L"%s %d", str1.c_str(), static_cast<int>(str1.size()));//str1.size() str1のサイズ:7
    swprintf(wcText2, 256, L"%c%c%c%c", str2[2], str2[3], str2[0], str2[1]);//str2の文字を並び替える:"しくよろ"

    MessageBox(NULL, wcText, wcText2, MB_OK);

    return 0;
}

3.std::wstringによる文字列の表示