【DX12を学びたい】三角形を表示させる

三角形の表示 DirextX

諸々の設定が終わったら、三角形を表示していきます!

1:ルートシグネチャの作成
2:シェーダーの準備
3:グラフィックスパイプラインステートの作成
4:三角形の表示

スポンサーリンク

ファイルを追加

まずは三角形用のcppとhファイルを追加します。

Triangleとしましたが、好きな名前でOKです。

ヘッダーファイル

DX12を使用するためにヘッダーをインクルードします。

クラスや変数名、関数は自分が理解しやすい形に修正してください。

#pragma once

#include <d3d12.h>
#include <DirectXMath.h>

// 三角形用のクラス
class Triangle
{
public:
	Triangle();
	~Triangle();

	// 初期化
	bool Initialize(const Graphic* pGraphic);
	// 描画
	void Draw(const Graphic* pGraphic);

private:
	// リソースの作成
	bool CreateVertexBuffer(const Graphic* pGraphic);
	// マップ
	bool Map();
	// 頂点バッファービューの設定
	void SetVertexBufferView();

private:
	struct Vertex
	{
		DirectX::XMFLOAT3 Pos;
		DirectX::XMFLOAT4 Color;
	};
	Vertex m_Vertices[3];

	ID3D12Resource* m_pVertexBuffer;
	D3D12_VERTEX_BUFFER_VIEW m_VertexBufferView;
};

 

C++ファイル

用意したヘッダーのインクルード、ライブラリファイルのリンクを追加します。

頂点情報も設定しておきます。

※裏面になると表示されないので注意!
(D3D12_CULL_MODE_BACKをD3D12_CULL_MODE_NONEに変更すれば表裏関係なし)

#include "Triangle.h"

#pragma comment(lib, "d3d12.lib")

// コンストラクタ
Triangle::Triangle()
    : m_pVertexBuffer(nullptr)
{
    // 頂点情報
    m_Vertices[0].Pos = DirectX::XMFLOAT3(0.0f, 0.25f, 0.0f);
    m_Vertices[1].Pos = DirectX::XMFLOAT3(0.25f, -0.25f, 0.0f);
    m_Vertices[2].Pos = DirectX::XMFLOAT3(-0.25f, -0.25f, 0.0f);
    m_Vertices[0].Color = DirectX::XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f);
    m_Vertices[1].Color = DirectX::XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f);
    m_Vertices[2].Color = DirectX::XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f);

    // 頂点バッファービュー
    memset(&m_VertexBufferView, 0, sizeof(m_VertexBufferView));
}

// デストラクタ
Triangle::~Triangle()
{
    SAFE_RELEASE(m_pVertexBuffer);
}

 

余談

ファイルを追加するたび、d3d12.hやd3d12.libを追加するのが面倒…

なので、全ファイルが用意したヘッダーファイルをインクルードするようにしてみました。

 

頂点バッファー

頂点情報を描画で使用するために頂点バッファーの作成です。
CreateCommittedResourceを使用します。

D3D12_HEAP_PROPERTIESD3D12_RESOURCE_DESCを頂点バッファー用に設定し、リソースを作成しています。

// リソースの作成
bool Triangle::CreateVertexBuffer(const Graphic* pGraphic)
{
    ID3D12Device* pDevice = pGraphic->GetDevice();
    if (pDevice == nullptr) return false;

    const UINT vertexBufferSize = sizeof(m_Vertices);

    // ヒープのプロパティ
    D3D12_HEAP_PROPERTIES prop;
    // ヒープの種類
    prop.Type = D3D12_HEAP_TYPE_UPLOAD;     // cpuは書き込み、gpuは読み取り
    // CPUページプロパティ
    prop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; // プロパティ不明
    // メモリプール
    prop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;  // プール不明
    // マルチアダプター関連
    prop.CreationNodeMask = 1;
    prop.VisibleNodeMask = 1;

    // リソースの設定
    D3D12_RESOURCE_DESC desc;
    // リソースのディメンション
    desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
    // 配置の指定
    desc.Alignment = 0;
    // リソースの幅、高さ(今回はバッファーサイズ)
    desc.Width = vertexBufferSize;
    desc.Height = 1;
    // リソース深さ
    desc.DepthOrArraySize = 1;
    // MIPレベル
    desc.MipLevels = 1;
    // リソースデータの形式
    desc.Format = DXGI_FORMAT_UNKNOWN;  // バッファーはこれでいい
    // マルチサンプリングの設定
    desc.SampleDesc.Count = 1;
    desc.SampleDesc.Quality = 0;
    // テクスチャのレイアウト
    desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;   // データを連続して配置する
    // オプション
    desc.Flags = D3D12_RESOURCE_FLAG_NONE;  // なし

    // 頂点バッファーを作成
    HRESULT result = pDevice->CreateCommittedResource(
        &prop,
        D3D12_HEAP_FLAG_NONE,               // オプションなし
        &desc,
        D3D12_RESOURCE_STATE_GENERIC_READ,  // 読み取り状態
        nullptr,                            // クリアカラー
        IID_PPV_ARGS(&m_pVertexBuffer)
    );
    IS_S_FALSE(result);

    return true;
}

 

マップ

作成したバッファーデータへのポインターを取得する。
Mapを使用します。

ポインターを取得したら、情報をコピーしてポインター無効にしておきます。

// マップ
bool Triangle::Map()
{
    const UINT vertexBufferSize = sizeof(m_Vertices);

    // リソースデータのポインターを取得
    UINT8* pVertexDataBegin;
    HRESULT result = m_pVertexBuffer->Map(
        0,          // インデックス番号
        nullptr,    // リソース全体
        reinterpret_cast<void**>(&pVertexDataBegin)
    );
    IS_S_FALSE(result);

    // バッファーに情報をコピー
    memcpy(pVertexDataBegin, m_Vertices, vertexBufferSize);
    // 取得したポインターを無効にする
    m_pVertexBuffer->Unmap(0, nullptr);

    return true;
}

 

頂点バッファービューの設定

頂点の情報をまとめたものが、頂点バッファービューです。

今までの情報をセットするだけでOKです。

// 頂点バッファービューの設定
void Triangle::SetVertexBufferView()
{
    const UINT vertexBufferSize = sizeof(m_Vertices);

    // バッファーの仮想アドレス
    m_VertexBufferView.BufferLocation = m_pVertexBuffer->GetGPUVirtualAddress();
    // 1頂点のバイトサイズ
    m_VertexBufferView.StrideInBytes = sizeof(m_Vertices[0]);
    // バッファーのバイトサイズ
    m_VertexBufferView.SizeInBytes = vertexBufferSize;
}

これで三角形を表示する準備が完了しました。

 

描画処理

描画するには三角形のデータであると設定して、頂点バッファービューを設定します。

設定が終わったら、あとは描画するだけです。

// 描画
void Triangle::Draw(const Graphic* pGraphic)
{
    ID3D12GraphicsCommandList*  pCommandList = pGraphic->GetCommandList();
    if (pCommandList == nullptr) return;

    // 三角形のリストで構成されている
    pCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    // 頂点バッファービューの設定
    pCommandList->IASetVertexBuffers(
        0,                  // インデックス
        1,                  // ビューの数
        &m_VertexBufferView
    );

    // 描画
    pCommandList->DrawInstanced(
        3,      // 描画する頂点の数
        1,      // 描画するインスタンスの数
        0,      // 最初の頂点のインデックス
        0       // 一旦0
    );
}

 

あとは、この処理をコマンド実行の前に呼びます。

エラーが出なければ、これで三角形が出るはずです。

// 三角形
Triangle triangle;
triangle.Initialize(&directX);

// ループ
{
	...
	// 描画
	triangle.Draw(&directX);

	// コマンドを実行
	directX.ExecuteCommand();
}

 

さいごに

やっと何かを表示させることができました!

まだ分かっていない部分も多いですが、次に進みながら理解を深めたい。

かれいど

ゲームをしたり、作ったり
色々な事に挑戦していきたい!

サッカー観戦も趣味で
主にJ1リーグを観ています。

かれいどをフォローする
DirextX
スポンサーリンク
シェアする

コメント