12.Dx11版のウインドウ作成と、共有ライブラリ

今回は、Dx11版のウインドウ作成します。
その前に前項で開いたソリューションを閉じなければなりませんね。
VS2015とか(VS2013でも)、ずっと継続してファイルの追加とか修正を行っていると、いろんな情報が積み重なってしまうんです。そうするとビルド時間が遅くなったり、なんか、「バージョンが違うファイルがある」なんてエラーが出たり、いろいろします。
そんな時は思い切って、これまでVS2015が蓄積したデータを一気に削除してしまうとスッキリすることがあります。
例えば、以下の図は、前項で開いた「SimplSampleTest」ディレクトリ内の「BaseCrossDx12.sln」を閉じたところです。

2016080503

結構いろんなディレクトリやファイルが作られているのがわかりますね。60メガもあるファイルもあります。「そんなの自分は作ったっけ?」て気にもなります。
これまでの設定で「中間ファイル」というのは「Temp」ディレクトリに閉じ込めるよう指定しましたが、それでもこんなにファイルやディレクトリができてしまいます。
例えばこれをこのまま持ち運びするとして、一つ上のディレクトリでzip圧縮したとしても、100メガ超えちゃうzipファイルになることがあります。「ああ、コンパイラって仕事してんだなあ」とつくづく思います。
でもこれでは持ち運びにも不便なので、定期的にいらないファイルは一気に削除してしまいましょう。
このディレクトリで必要なのは「BaseCrossDx11ディレクトリ」「BaseCrossDx12ディレクトリ」前項で作成した「media」ディレクトリと「BaseCrossDx11.sln」「BaseCrossDx11.sln」の2ファイルです。
他は全部削除してしまいましょう。ただし、必ずVS2015は終了させてからこの処理を行ってくださいね。以下は、削除後のディレクトリです。スッキリしましたね。

2016080502

このように、定期的に作業ファイルをクリアすると、コンパイラがストレスなく動くようになります。ただ、履歴とかも削除してしまうのでundoはきかなくなりますし、最初の「ビルド」は必ず「リビルド」になります。

さてそのようにして今度は「BaseCrossDx11.sln」を開きます。前項にならってウインドウを作成するわけですが、記述するコードは、実は、Dx12版と同じです。前項を読み返しDx12となっているところはDx11としていただければウインドウは作成できると思います。
「なら、前項の最後にでも解説してくれたらいいのに」と言われる方もいるかと思います。はい、その通りです。
ただ、記事がGitHubのコミットに合わせて、ってことになっているので、記事をまたいでしまいました。すみません。

今回の記事からは「共有ライブラリの作成」が主な話題です。

この記事は、
コミット「Dx12版のウインドウ作成」
から、
コミット「Dx11版ウインドウ作成と共有ファイルの追加」
の間の作業です。
GitHubサイト

https://github.com/WiZFramework/BaseCross

を参照して下さい。

前回の記事を読み返してみてあらためて思ったのですが、このブログはGitHubサイトと照らし合わせしないと、ホント何書いてあるかわかりませんね。
「SourceTreeによるレポジトリのプル」は必須かと思います。ぜひ、上記サイトのレポジトリにSourceTreeでアクセスして、確認しながら記事を読んでください。
その際、ローカルに自分用のブランチを作成するなどして、該当コミット時の状態で保存して確認するといいと思います。記事は2つのコミット間の話題ではありますが、当然後ろのほうのコミットに向かうので、コード解説は後ろのコミットに近いものになると思います。
この記事時点で、GitHubサイトのコミットは、この記事で話題にしているコミットの5,6ステップ先に進んでおります。
またここからのコミットはコミット間で結構大きな変更があります。
もっと細かくコミットするのもいいかもしれませんが、そうすると実装が中途半端な状態でコミットすることになるので、かえって混乱を招くかと思いそうしています。

さて、いろいろ前置きしましたが、今回作成するのは「共有ファイル」です。いま開いているのは「BaseCrossDx11.sln」なのでそこから見える「DxLib共有アイテムプロジェクト」にファイルを追加していくことになります。
まず、「DxLib」の「フィルター」を作成します「Headers」というフィルターと「Sources」というフィルターです。ヘッダファイルとソースファイルをフィルターで分けています、収納するディレクトリは分けてはいません。
VisualStdioのフィルターはファイル整理に大いに役立つので、皆さんも積極的に使ってみるといいでしょう。フィルタを作成したら早速共有ファイルを作成します。
「Headers」フィルターを右ボタンクリクし、「追加」「新しい項目」で「ヘッダーファイル」「BaseHelper.h」を追加します。追加するディレクトリは「DxLib」のディレクトリ直下でかまいません。
そこで、以下のように記述を開始します。

#pragma once
#include "stdafx.h"

namespace basecross{

}
//end basecross

これは、これから記述するコードは、「basecross」という名前の「namespace」の属する、という指定です。
BaseCrossフレームワークのライブラリはすべて「basecross」に属します。実は作成するゲームも「basecross」に属します。
このように、「namespace」を使用することで、名前の衝突を最小限に抑えることができます(確実ではないですが)
今後、このブログでも特別断りがない限り、「basecross namespace」に属すると考えてください。ただ現時点でも例外はあります。「WinMain,cpp」内の、WinMain関数やウインドウプロシージャです。これらはWindowsから見える必要があるので「basecross namespace」に属しません。

さて、「DxLib」には何を記述するべきでしょうか。ここでじっくり考えてみましょう。「Dx11とDx12とで共通して使えて、さらに言えばより汎用的な関数やクラス」ですね。
どんなものが考えられるでしょう。まず「例外処理」「CSV、バイナリファイルの読み込み」「XMLの読み書き」「数学計算クラス」そんな感じでしょうか。あと「衝突判定」を書けるかもしれません。
実は「衝突判定」は共有エリアに記述することを少し迷いました。と言いますのは、シェーダにCS(計算シェーダ)というのがあり、ひょっとするとこれでかけるかなと思ったのです(すべてではなく、本当に負荷がかかるところだけでも)。そうすると、シェーダはシェーダそのものは共通で使用できるのですが、扱いがDx11とDx12でまるで違います。ですので「共有プロジェクト」ではなく「個別プロジェクト」に入れる必要があります。
結果的にはそれは見送りました。一番大きいのは技術的な問題です。まだ、簡単な衝突判定も自分でCSで実装できてないという現実、それに加え、衝突判定で多用される「数学計算クラス」はこれ自体が内部で最適化(SSE2)処理されているので、ある程度(C++処理だけでガチガチ書くよりは)スピードはある、ということ。

共有すべきもので、忘れてはならないのは「インターフェイス」でしょう。C++11になり、スマートポインタを大々的に活用してます。生ポインタを使用するところはほとんどありません。
しかし、スマートポインタ(shared_ptr)は一つ欠点というか、使いにくいところがあって、というのは、thisポインタをスマート化(shared_ptrにするのが)結構厄介なのです。
オブジェクトのshared_ptrを自分自身で作れると大変便利です。thisポインタのように使えますから。でもそのためには、オブジェクトを

std::enable_shared_from_this<型名>

の派生クラスとして作成する必要があります。OnCreate()などの純粋仮想関数もあったほうがいいでしょう。そんなわけで「ObjectInterface」というインターフェイスを共有エリアに作成することにしました。
そんなこんなあれこれ悩んで、結果的に、共有エリアには、以下の主なクラス、関数群をそれぞれのヘッダファイル、CPPファイルに収めています。
また(MS社サンプル流用)となっているのは、マイクロソフト社、DirectXのサンプル群の中から使用可能なものを流用しています。(ライセンス的には、こうして流用を記すこと含め、問題ないと思ってます)

1、BaseHelper.h/cpp
「BaseExceptionクラス」 例外クラス
「BaseMBExceptionクラス」 例外クラス(マルチバイト版)
「ThrowIfFailed関数」 インターフェイスの例外
「BinaryReaderクラス」 バイナリ読み込み(MS社サンプル流用)
「CsvFileクラス」 CSV読み込みクラス
「MakeRangeErr関数」 比較のエラーの文字列を作成する関数
「SafeDelete関数」 生ポインタを安全に削除する
「SafeDeleteArr関数」 生ポインタの配列を安全に削除する
「SafeRelease関数」 COMインターフェイスを安全にリリースする
「SefeDeletePointerList関数」 ポインタのリストを安全にクリアする
「SafeDeletePointerVector関数」 ポインタの配列を安全にクリアする
「SefeReleasePointerList関数」 インターフェイスのリストを安全にリリースする
「SafeReleasePointerVector関数」インターフェイスの配列を安全にリリースする
「SharedToVoid関数」 shared_ptrからvoid型のshared_ptrに変換する
「VoidToShared関数」 void型のshared_ptrを型指定のshared_ptrに変換する
「struct Util構造体」 その他のstatic呼び出しをする関数群をまとめたもの
「ThrowBaseException関数」 ランタイム例外をthrowする(wstring版、string版多重定義)
「ThrowIfNullFailed関数」 ポインタがnullだった時のスロー(wstring版、string版多重定義)
「ThrowIfWeakToSharedFailed関数」weak_ptrからshared_ptrに変換をかけ、無効なら例外を投げる
「StepTimerクラス」 タイマー(MS社サンプル一部流用)
「Point2D構造体」 単純な2次元ポイント
「Rect2D構造体」 単純な2次元矩形
「ObjectInterfaceクラス」 オブジェクトのインターフェイス
「ObjectFactoryクラス」 ObjectInterfaceの派生クラスを作成するクラス(ファクトリー)
「ShapeInterfaceクラス」 OnUpdate、OnDraw純粋仮想関数を持つインターフェイスクラス
「SceneInterfaceクラス」 シーンのインターフェイス
「BaseResourceクラス」 リソースのインターフェイス
「ObjStateクラス」 ステートの親クラス
「StateMachineクラス」 ステートマシン

2、MathVector.h
「Vector2構造体」 2Dベクトル。(DirectXMathラッピング構造体)
「Vector3構造体」 3Dベクトル。(DirectXMathラッピング構造体)
「Vector4構造体」 4Dベクトル。(DirectXMathラッピング構造体)
「XMVector構造体」 1次元XMVECTORのラッピング構造体(未完成)

3、MathVector.h
「Vector2EX namespace」 2Dベクトルインライン関数群
「Vector3EX namespace」 3Dベクトルインライン関数群
「Vector4EX namespace」 4Dベクトルインライン関数群

4、MathExt.h
「Plane構造体」 平面構造体。(DirectXMathラッピング構造体)
「Color4構造体」 カラー構造体。(DirectXMathラッピング構造体)
「Quaternion構造体」 クオータニオン構造体。(DirectXMathラッピング構造体)
「Matrix4X4構造体」 4X4行列構造体。(DirectXMathラッピング構造体)

5、MathExtEX.h
「PlaneEX namespace」 平面インライン関数群
「Color4EX namespace」 カラーインライン関数群
「QuaternionEX namespace」 クオータニオンインライン関数群
「Matrix4X4EX namespace」 4X4行列インライン関数群

5、TransHelper.h
「Lerp構造体」 static呼び出しをする補間処理計算
「CollisionVolume構造体」 衝突判定ボリュームの基底構造体
「OBB構造体」 OBBボリューム境界
「AABB構造体」 AABBボリューム境界
「SPHERE構造体」 球体ボリューム境界
「SPHERE_ARR構造体」 球配列データ
「PLANE構造体」 平面ボリューム境界
「CAPSULE構造体」 カプセルボリューム境界
「HitTest構造体」 static呼び出しをする衝突判定関数群

6、XmlDoc.h/cpp
「XmlDocReaderクラス」 XML読み込みオンリークラス
「XmlDocクラス」 XML読み書きクラス

以上が、現時点での「共有化すべき」関数やクラス、構造体と考えてます。
このあたりの設計は、本当に「何が正解か」わかりません。「BaseCrossではこうなってます」としか言いようがない。
それでは次回から上に述べた各クラス、関数について説明していきたいと思います。

カテゴリー

ピックアップ記事

  1. 2016092201
    今回は前回のサンプルを少し機能を追加しまして、いろんなオブジェクトを追加しています。FullTuto…
  2. 2016092001
    前回更新から時間がたってしまいましたが、今回はフルバージョンチュートリアル003をアップしました。内…
  3. eyecatch
    前回更新から時間がたってしまいましたが、今回はフルバージョンチュートリアル002で懸案となっていまし…
PAGE TOP