0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DirectXTKでAssimp CPP側の補足資料

0
Last updated at Posted at 2026-05-17

前書き

DirectX11のリソースバインディングと三角ポリゴン生成についてフローを理解していること前提の記事です

また、この記事の補足記事でもあります
https://qiita.com/YKVKDX12/items/5a2cc3d175b9f6324422

  1. Assimpの実装概要
    Assimp(Open Asset Import Library)を使用して、FBXやOBJなど複数の3Dモデルフォーマットをインポート

m_importer.ReadFileを呼び出し
→aiProcess_ConvertToLeftHandedなどのポストプロセッシングフラグで、頂点の三角化とUV座標の反転

入力レイアウト(POSITION、NORMAL、TEXCOORD)を定義して頂点フォーマットを定義

パイプラインステートはDirectXTKのCommonStatesを使用
これはラスタライザステートを始めとした、サンプラーステート、ブレンドステート
デプスステンシルステートをパパっと作成できるラッパーとなる

使い方は以下の通り・・・

std::unique_ptr<CommonStates> states;
states = std::make_unique<CommonStates>(device);

今回はCullClockwiseでパイプライン側のラスタライザステージに

deviceContext->RSSetState(states->CullCounterClockwise());

とバインドする
2. XTKのリソース生成の概要
DirectX::CreateStaticBuffer で頂点バッファとインデックスバッファを生成

定数バッファはDirectX::ConstantBufferで管理

CreateとSetDataで管理できる

SceneCB?

スクリーンへの座標変換をシェーダーに送り込むための構造体インスタンスとなる

ワールド行列、ビュー行列、プロジェクション行列を格納して頂点シェーダーへ送り込む
なお、これらを乗算した後は逆行列を投影してやらないといけない
その説明やパイプラインの説明をした記事がこちらになる

ところで・・・なんで逆行列を乗算するの????

モデル空間にあった3DCGと関係するベクトルをスクリーン空間に座標変換して持ってきた際、もう一度ローカル空間やワールド空間、ビュー空間といった『ライティングや当たり判定などの計算がしやすい空間』に引き戻すためになる

リソースバインディング

 Draw関数内で全リソースをパイプラインにバインド。IASetInputLayoutで入力レイアウトを設定し、IASetIndexBufferでインデックスバッファ、IASetVertexBuffersで頂点バッファをバインドしてから、IASetPrimitiveTopologyでD3D11_PRIMITIVE_TOPOLOGY_TRIANGLELISTを指定

void education::Model::Draw(const DX::DeviceResources* DR) {
    if (vertices.empty() || indices.empty()) {
        OutputDebugStringA("Vertex or index buffer is empty.\n");
        return;
    }

    auto context = DR->GetD3DDeviceContext();

    // Input Layout 設定
    context->IASetInputLayout(m_modelInputLayout.Get());
   
    // インデックスバッファの設定
    auto indexBuffer = static_cast<ID3D11Buffer*>(m_indexBuffer.Get());
    context->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0);

    // 頂点バッファの設定
    UINT stride = sizeof(DirectX::VertexPositionNormalColorTexture);
    UINT offset = 0;
    auto vertexBuffer = static_cast<ID3D11Buffer*>(m_vertexBuffer.Get());
    context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);

    // プリミティブトポロジー設定
    context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    auto buffer = m_constantBuffer.GetBuffer();
    context->VSSetConstantBuffers(0, 1, &buffer);
    context->PSSetConstantBuffers(0, 1, &buffer);

    // シェーダー設定
    context->VSSetShader(m_vertexShader.Get(), nullptr, 0);
    context->PSSetShader(m_pixelShader.Get(), nullptr, 0);
    context->PSSetSamplers(0, 1, samplerState.GetAddressOf());

    context->PSSetShaderResources(0, 1, m_modelsrv.GetAddressOf());
    // 描画コール   
    context->DrawIndexed(static_cast<UINT>(indices.size()), 0, 0);
}

VSSetConstantBuffersとPSSetConstantBuffers

定数バッファをシェーダースロットに割り当て VSSetShaderとPSSetShaderでコンパイル済みシェーダーコードをパイプラインにセット

最後にPSSetShaderResourcesでテクスチャビューをサンプラーステート経由でバインド

DrawIndexedで描画コマンドを発行

ドローコールの注意点

DrawIndexedではあくまでGPUにこれまでのパイプラインにて行われる一連の処理
をやってほしいと頼むだけである

つまり、ECサイトで言えば「注文確定ボタンを押した」フェイズ
もっとインタラクティブな例で例えるなら
鍵盤楽器(ピアノ)の鍵盤を弾いた
という事に過ぎないのである。
この命令で即座にCGが出力される。というわけではない
(え?ピアノは鍵盤を弾いたら音が出るって?厳密にはそうじゃないんですよ・・・
ピアノの音が出る仕組み知りたくなったでしょ?知的好奇心満たす意味でヤマハさんのこの記事見ましょう)

https://www.yamaha.com/ja/musical_instrument_guide/piano/
(ピアノって今なお現代の最新技術を投入して作られている繊細な工業品なんですよ・・・・)

あと手前味噌ですがこちらも
https://qiita.com/YKVKDX12/items/bbe6e5f358444a92b22c

コード

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?