諸々の設定が終わったら、三角形を表示していきます!
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_PROPERTIES、D3D12_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();
}
さいごに
やっと何かを表示させることができました!
まだ分かっていない部分も多いですが、次に進みながら理解を深めたい。
コメント