DirectX12の魔導書 3章
この本
DirectX 12の魔導書 3Dレンダリングの基礎からMMDモデルを踊らせるまで
- 作者:川野 竜一
- 発売日: 2020/02/13
- メディア: 単行本(ソフトカバー)
のコードを参照しながら、少しずつ自分のコードを作っていくというやり方を取りました。
ウィンドウが表示されるまでの流れ
サポート関数の作成
main関数の作成
- ウィンドウクラスの生成&登録
- ウィンドウオブジェクトの生成
- DXGIファクトリ生成
- アダプターの検索(GPU)
- デバイス生成(適応できるフィーチャーレベルを検索しながら)
- コマンドアロケーター
- コマンドリスト
- コマンドキュー
- スワップチェーン
- ディスクリプタヒープ
- ディスクリプタ
- フェンス
- ウィンドウ表示
- Window Message処理
- DirectX処理
- リソースバリア
- レンダーターゲット指定
- 画面クリア
- 命令クローズ
- コマンドリストの実行
- イベントハンドル取得&待機
- コマンドアロケーター&コマンドリストリセット
- フリップ(ダブルバッファの交代)
- 終了時のクラス登録解除
ただウィンドウを出すだけでもこれだけの必要項目があります。
メモ:規格化(数値)とは
t0からt1まで変動する数値について規格化するというのは
対応する数値に変換することで
数式は
サイト「低レイヤを知りたい人のためのCコンパイラ作成入門」をやってみる 1回目
掲題通りです。コンパイラを作成することでコード解析とアセンブラ出力が学習できれば。
参照サイト
環境
想定する実行環境が64bit LinuxということでWSLをインストールします。 Windows側では/User/hoge/ubuntuというフォルダを用意します。 WSL側で/home/hoge/.bashrcの末尾に cd /mnt/c/users/hoge/ubuntu と記載しておき、WSL起動時に開発ディレクトリにアクセスできるようにしています。
簡単な例
int main() { return 42; }
$ gcc -o test1 test1.c $ ./test1 $ echo $? 42
gccして終了コードを$?で見れることが分かる。
次に上記コードに対応するアセンブリプログラムを書いてみる
.intel_syntax noprefix .global main main: mov rax, 42 ret
呼び出し規約で関数の戻り値はレジスタraxに入れる、とのこと。gccして$?を参照すると先ほどと同様終了コードをみることが出来た。
関数呼び出しのコードがアセンブラでどうなるか
関数呼び出しはただのジャンプと違い、呼び出された関数の終了後、元の場所に戻らなければいけない。 そこで元のアドレス「リターンアドレス」をスタックメモリに保存しておく。 なぜスタックなのかは、多段呼び出しに対応するため。
スタックはスタックの一番上のアドレスを記憶しておけばよい。この一番上のアドレスを記憶しているのがスタックポインタ。x86-64には
がサポートされている。ちなみにスタックにデータを積むことを「プッシュ」と言い、データを取り出すことを「ポップ」という(復習)。(キュー構造ではデータ追加がenqueue、データ取り出しがdequeue)
以下、関数呼び出しの実例。引数x, yを足し合わせる関数plusとそれを呼び出して戻り値を終了コードに乗せるmain関数をアセンブラで書いたもの。Cコードは割愛。
.intel_syntax noprefix #アセンブリ文法指定 .global plus, main #plusとmainがプログラム全体から見えることを指示 plus: add rsi, rdi mov rax, rsi ret main: mov rdi, 3 #お約束 mov rsi, 4 #第一引数はrdi、第二引数はrsiレジスタ call plus ret
関数を呼び出す命令callは以下のことを行う。
- callの次の命令のアドレスをスタックにプッシュ(上述の「リターンアドレス」?)
- callの引数アドレスにジャンプ
関数の戻り値はraxに入れておく決まりなので、plus関数のret命令の前にraxレジスタへの格納命令がある。
plus関数の最後にret命令がある。ret命令は以下のことを行う。
- スタックからアドレスを1つポップ(取り出す)
- 取り出したアドレスにジャンプ
mainの中でcall plusの次の命令のアドレスをスタックにプッシュしていたので、plus関数のret命令によりcall plusの次のアドレスに飛ぶことができる。
章の(個人的)まとめ
- 関数戻り値はraxレジスタに格納
- callとretは対。
次章
次は「電卓レベルの言語の作成」をやります。
Blender 練習:歯車
Blender 3DCG モデリング・マスターhttps://www.amazon.co.jp/dp/4800711479/より。 本の内容は歯車1個だけだったので、アニメーションをつけました。
要点
アニメーション
- ドープシートのフレーム選択が右クリックだった。(Ver.2.79。設定で左右クリックは交換済みなのに)
- 何もしないとアニメーションの初めと終わりで速度補完がされてしまうので、ドープシートの channel > Extrapolation mode > Linear Extrapolation。これでループになる。
- キーフレーム挿入のショットカットキーはIキー。
- 左の歯車を回転させる前にShift + S > Cursor to Selectedで左歯車オブジェクトの中心に3Dカーソルを持ってきた後、回転処理&キーフレーム作成を行う。
保存
Outputメニューのformatでmpeg videoを、EncodingメニューでMPEG-4, H-264を選択して、
RenderメニューのAnimationでレンダリング開始。(この場合だとc:/tmpに保存される。)
なお、twitterに動画ファイルを直接上げることが出来ませんでした。 (そのおかげでブログを書く気になった…)
WSL (Windows Subsystem for Linux)導入メモ
www.sigbus.info このサイトでコンパイラを勉強するために、以前導入していたWSLを使ってあれこれ出来るよう、やったことについてメモを残しておきます。 (といっても開始ディレクトリを変更するための.bashrc編集ぐらいですが。)
WSLからWindowsのファイルシステムへのアクセス
my-web-site.iobb.net
WSLからWindowsのファイルシステムのアクセスは /mnt/c/ なので、上記サイトのとおり .bashrc の末尾に
cd /mnt/c/users/[my name]/ubuntu
を追加しました。
viは苦手なのでnanoエディタを使いました。(viのコマンドを毎回検索していて、正直めんどい)
逆にWindowsからWSLの領域に触って編集等することはご法度だそうです。もうそろそろWindowsのアップデートでそれも可能になるとのことですが。 forest.watch.impress.co.jp
アップデートとgccの準備
ubuntuでお約束のsudo apt update
とsudo apt upgrade
を行った後、sudo apt install build-essential
でgcc環境をインストールしました。
hello.c編集(Windows) -> コンパイル(WSL)
WSL側
【Unity】振り子を作る
はじめに
倒立振子(紳士って変換すんのやめーや)をUnity上で再現できないか、と考えていて、その前準備としてHinge Jointの使い方を少し調べてみました。
なお以下のサイトを参考にしています。
(ただ上記記事はHinge Jointコンポーネントをアタッチする先が逆になっているものと思われるので、自分の方では振り子(動体)の方にHinge Jointコンポーネントを当てています。)
単独の振り子を作る場合
単独でぶらぶらさせるのは特に複雑なことはなく、(Rigidbodyのアタッチは当然なので割愛)揺れる対象にHinge Jointをアタッチし、揺れの軸Anchorを(ローカル座標なので)物体からどれだけ離すか設定すればいいだけです。Connected Bodyの設定が空だと動体はグローバル座標(空間?)にピン止めされたようになります。
(左上の小さな矢印のようなものが揺れの軸です)このように動きます。
何か動くものに振り子を繋ぐ場合
振り子が動くものにジョイントされるにはConnected Bodyに対象の動体をアタッチする必要があります。(今回は球の上にあるキューブです。)なおConnected Bodyの選択肢にオブジェクトがリストされるにはRigidbodyを持っていないといけないようで、上部のキューブにはRigidbodyをアタッチし、物理計算で落下しないようIs KinematicをOnにしてあります。
(Connected BodyにPivot(キューブ)をセットし、Anchor位置をPivotと同位置になるようセット。)すると以下のようになります。(動体に留められていることが分かるよう、キューブには左右の移動アニメーションをつけています。)
(ジョイントが1個なのでキューブと球を繋いでいるのが棒に等しい。ジョイントを複数作れば鎖のようにできるのでしょうが。)
終わりに
参考サイトのほぼ丸写しではありますが、ヒンジを持ったオブジェクトの作成ができるようになりました。
Unityのリファレンスでの紹介では犬用ドア付きのドアを例に出していますが、ドアのHingeの軸をY軸に、犬用ドアのそれをX軸にすればいいのだけれど、(犬用ドアの)一部分が欠けたプレートをどうやって作るか頭が回らなくなってきたので、ここまで。
(だいぶ実験用プロジェクトの中身がごちゃごちゃになってきた。)