連載
.NET&Windows Vistaへ広がるDirectXの世界

第2回 DirectXマスターを目指すあなたが持つべき視点

――ソフトウェア開発の視点から見たDirectXの世界――

NyaRuRu
Microsoft MVP Windows - DirectX(Jan 2004 - Dec 2006)
2006/07/22
Page1 Page2 Page3

Back Issue
1
DirectXの真実

 DirectXに限らず、さまざまなライブラリ/フレームワークを習得するうえで、構成要素の変化速度を見極められているかどうかが心理的にも習得効率的にも大きな違いを生むように思う。

 例えば言語仕様やコーディング規約は長期間安定であり、一度習得するとその知識を継続的に役立てることができるだろう。また、CPUやメモリの動作原理、RFCなどのネットワーク・プロトコルも比較的安定な部類に入ると考えられる。しかし、頻繁に変化が起き、数年後には変更されてしまうような仕組みが混ざっていると話はすぐにややこしくなる。

 ウォータフォール型の開発プロセスは、長期間かけて開発したソフトウェアを長期に渡って運用できる分野には有効だが、もっと変化が激しく事前に事態の進行を見通せない分野には適さないとされている。

 DirectXでいえば、今後どのような3D表現が必要とされ、どのようなハードウェアが登場してくるかが不確定要素であり、1995年の時点で2005年の3Dアプリケーション開発に適したAPIセットを作成するのは難しい、というわけだ。

 結果的に、DirectXは反復型開発プロセスを採用し、1〜2年おきにAPIセットを見直すことでハードウェアの変化に対応した。この頻繁なアップデートに対する、COM(Component Object Model)というコンポーネント技術の貢献は非常に大きい。しかし長期的に見れば有利だったCOMの採用も短期的に見るとそうでない場合もある。例えばDirectXの初学者にとっては、COMによってライブラリ呼び出しが間接化されていることが、サンプル・コードの内容の理解を困難にしてしまっているという側面もある。

 さて、しばしば「DirectXは難しい」「習得に時間がかかる」という声を耳にするDirectXであるが、筆者がおすすめしたいのは「変化速度で分類する」という方法である。もちろん簡単なことではない。右も左も分からない状況から、全体をふかんし、さまざまな視点で分類・整理できるようになるまでは長い経験と継続的な努力が必要だが、回り道を避ける程度のコストダウンは可能だと思っている。そのために目標とすべきことの1つが、「変化速度で分類する」ことだ。

 いわゆる入門書ではなかなか強調してくれないが、近年のソフトウェア開発では何かしらの「変化に対する備え」がライブラリや言語仕様そのものに組み込まれていることが常である。これらの仕組みは「勉強を初めて3日目」という人には役に立たないのだが、「3年間使い続けています」というころになると、たいていなくてはならないものになる。

 DirectXをマスターするための条件の1つとして、DirectXのサンプル・コードやライブラリ仕様を、「変化しない部分」「変化に備える部分」「変化しやすい部分」といった要素に分けることができ、それぞれ別個に攻略できるようになることをまずは挙げておく*1

 DirectXによる個々の3Dプログラミング技術についてはさまざまな専門書が存在するため、興味がある方は個別に学習することができるだろう。今回はそれらを補完する意味で、普段語られることのない「変化」という視点からふかんしたDirectXによるソフトウェア開発について見ていきたいと思う。

*1 開発プロセスに、変化のスピードの違いという視点を導入する意味については、以下の記事参照のこと。

次世代開発基盤技術“Software Factories”詳解 第2回 開発手法「ソフトウェア・プロダクトライン」とは?

1. 安定性に基づく分類

遅い変化要素

 まず、DirectX開発で遅い変化要素、つまり長期間に渡って安定なものから見ていこう。いずれも5年から10年のスパンでしか変化せず、ものによってはDirectXが初めて登場したときからずっと変化していないものもある。

  • C++という言語の仕様
  • COMというプログラミング・モデル
  • 「アプリケーション」―「Direct3Dランタイム・ライブラリ」―「ドライバ」という関係
  • Direct3Dランタイム・ライブラリとドライバの間の通信仕様
  • Direct3Dのパフォーマンス戦略/処理手続きの方針

 これらを1枚の図にまとめたのが次のものだ。

DirectXにおける遅い変化要素
ここに挙げた要素・関係は長期間安定である。図中の「処理フロー・最適化戦略」が分かりにくいかもしれないが、第1回で紹介したような「バッチ処理による最適化」や「状態機械による描画方式の制御」といった手続きそのものを指す。例えばDirectXではリソースの読み書きに原則としてロック/アンロックAPIを使用するが、この原則も「処理フロー・最適化戦略」の一種である。その理由は、ランタイム・ライブラリとドライバの間でのやりとりがロック/アンロック方式を用いており、それがAPIでも踏襲されているためである。

 このほかにもWin32ウィンドウ・モデルをはじめとしたWin32 APIも長期安定な部類に入るだろう。これらの要素は、個々のAPIの仕様といったソース・コード・レベルの存在よりは、手続きや戦略といった抽象度が高いものが多い。

中程度の変化要素

 次に中期的に安定な要素を挙げる。

  • Direct3D各バージョンのインターフェイス・セット
  • ハードウェアに新機能として追加された機能
  • 算術クラスなどの基本的なユーティリティ・ライブラリ
  • チュートリアルなどの基礎的なサンプル・コード

 これをまとめると次の図のようになる。

DirectXにおける中程度の変化要素(ここに挙げた「ハードウェア新機能」と「インターフェイス」は一部であり、そのすべてではない)
過去を振り返ると、およそ1〜3年程度でハードウェアに何らかの新機能が搭載され、それを反映する形でインターフェイス・セットも変更が行われる。また、このタイミングでインターフェイス・セットの統廃合や簡素化も行われている。インターフェイス仕様が変化するため、それらを直接使用しているユーティリティ・ライブラリも同様にアップデートが行われる。ハードウェア新機能、インターフェイス・セット、ユーティリティ・ライブラリが、同じタイミングで一斉に変化するという特徴がある。Web上の簡単なサンプル・コードやDirectX解説書の内容は、おおよそこれと同じぐらいの速度で更新を行わないと、内容が古くなってしまうのである。

 この変化を実感するのは、開発中にDirectXのバージョンが上がったり、参考にした書籍やWebページが以前のバージョンを対象に書かれていたりするときだ。また近年登場した言語(例えばC#など)なども、1年から数年で言語仕様が改訂されることが多く、買ってきた本の内容が古くなっていたり、Web上のサンプル・コードが動かなかったりして困った、という体験をされたことがある方も少なくないのではなかろうか。

早い変化要素

 最後に、ごく短い期間で変化しやすい要素について示す。

  • アプリケーション・フレームワークなどの発展的なユーティリティ・ライブラリ
  • プログラマブル・シェーダを用いた新しい描画技法
  • コンテンツ・データ

 次の図はライブラリ/フレームワークの観点で速い変化要素についてまとめたものである。なお「DXUTフレームワーク」とは最近のDirectX SDKに付属するアプリケーション・フレームワークのことのことで、同じく「D3DXライブラリ」とはDirectX SDKに付属するユーティリティ・ライブラリのことである。

DirectXにおける速い変化要素1
最近のDirectX SDKに付属するユーティリティ・ライブラリであるD3DXと、アプリケーション・フレームワークであるDXUTは、それぞれ変化速度が異なる機能が混在したモノリシックなモジュールであるため、全体としては速い変化要素として振る舞う。

ここ数年、DirectX SDKは2カ月ごとにアップデートが行われているため、これらのモジュールに強く依存したソース・コードは2カ月で互換性を失う可能性がある。このことは、SDKや書籍に付属するサンプル・コードにとって大きな問題となっている。Direct3Dの機能レベルでは変化がなくても、依存する中間ライブラリの変化が激しすぎるため、サンプル・コードがすぐに互換性を失ってしまうのだ。どのバージョンのSDKを使用するかは、いまやDirectX開発者の大きな関心事となっている。

 そして次の図が描画技法やコンテンツ・データに関してまとめたものだ。

DirectXにおける速い変化要素2
一般的にいって、3Dアプリケーションの開発開始時に、使用するポリゴン形状データやテクスチャ・データがすべてそろっているということは考えにくい。これらコンテンツ・データは、通常アプリケーション開発と並行して作成される。また、近年新しい描画技法が次々と開発・発表されており、実際にアプリケーションで使用する描画ステートの設定やプログラマブル・シェーダの実装は短いスパンで改良を行っていきたいという需要がある。これらの3要素は互いに絡み合っており、新しい描画技法のためにはポリゴン形状データ・フォーマットの拡張や、テクスチャ・データに拡張的なデータを格納するといったコンテンツ・データの変更だけでなく、アプリケーション内部でのDirect3D API呼び出しにも手を加えなければならない。しかし、このようなプログラム側の変更が開発の中期から末期に発生するのは、リスクが高い。変化の波及を防ぐ方法の1つは、ウォータフォール型の開発プロセスを適用し、あらかじめこれらのコンテンツ・データの仕様を厳密に定めてしまうことだろう。この方法は、すでに仕様の定まっている特定の3Dデータ作成ツールのフォーマットを流用するような場合に有効であると考えられる。一方で、データ・フォーマットの決定タイミングが難しいという問題は、近年のRDBMS開発で求められる可変性と類似しているといえ、同様の複合化技術が適用できる可能性がある(※複合化技術については、前掲の「次世代開発基盤技術“Software Factories”詳解 −『ソフトウェア・プロダクトライン』とは?」を参考にされたい)。ある程度の変化を許容し、フォーマットの最終決定を遅らせる方向の可能性については、後の章で述べる。

変化のスピードに着目した再利用

 DirectX開発におけるソフトウェア資産の再利用では、より安定な性質に注目して整理してみるとよい。

 DirectXのインターフェイス・セットは1〜数年で変更が行われるため、それを直接使用しているソース・コードは、同程度のタイムスパンで定期的に書き直しが必要になる。このとき、処理フローや最適化戦略といった長期的な視点で分類・整理しておくと、その分類自体は変更せずに済む可能性が高い。また、COMに関するサポート・クラスなども継続して利用できるだろう。

 一方、ある時点でのDirectXの機能すべてを抽象化したラッパー・クラスを作ろうという試みは、インターフェイス・セットが変化するタイミングで大きな再設計を要求されることが多く、筆者としてはお勧めしない。これは、Direct3Dの機能はそれ単体では完結せず、コンテンツ・データや描画手法といった外部データともつれ合いを起こすためであり、このもつれ合いの解消に注目すべきである。

 描画機能と描画されるデータのもつれ合いを解消するためには、少なくとも1〜数年は安定なデータ・フォーマットを用意して、プログラマブル・シェーダなどの描画技法そのものの記述をアプリケーション本体の開発から分離してしまい、「インターフェイスによる外部データへの共通操作」と「外部データの記述・作成」が並行して進められるようにするという方法が有効である。

 なお「変化が激しい部分を外部の専用ファイルに分離する」という戦略は、ゲーム開発では「スクリプト」と呼ばれ、ゲーム・シナリオの記述やキャラクタのAI(人工知能)の記述などにしばしば用いられているものだ。さらに変化速度の違いに基づくコード資産の分離という戦略自体が、恐らく長期に渡って安定して使用し続けることができ、安定した構造を取り込めるという意味でも有用である。

 では、このような外部フォーマットはどのように設計し、従来C++などで書かれていた描画処理をどの程度外部ファイルに移動させるのがよいだろうか? 一概には答えられないが、いわゆるDRY原則(Don’t Repeat Yourself)を念頭におくのがよいと思われる。そのようなフォーマットの例として、近年DirectXに導入された描画処理の記述フォーマットについて後ほど紹介しよう。

 ただ、ここで紹介したような指針が、いわゆる初学者の方に当てはまるかというと、若干の無理があるようにも思っている。筆者の経験からいうと、5年程度安定な性質に着目した設計を1人で行うためには、試行錯誤の繰り返しで結局5年程度かかってしまうものだからだ。さらに、1〜2年単位の安定性・変化をじっくり観察する時間の余裕すら、変化のスピードが増した現在の状況は許してくれないかもしれない。ソフトウェア教育という点で、何をどの順序で学ぶかは難しい問題だと思う。

 一方で、第1回で指摘したDirectXとリレーショナル・データベースとの類似性のように、他分野での長期的な経験が、案外とDirectX開発で有益な示唆を与えることも少なくない。その意味でも、時間に余裕を持って幅広く学ぶこと、そして常に対象を観察・分析し、長期的により所とする戦略や方法論を意識的に確立していくことが重要かと思われる。

 最後にもう一度まとめると、DirectX開発にはさまざまなスパンでの変化が存在し、それらの変化をすべて避けて通ることは事実上不可能ということだ。変化を拒否するのではなく、事前に変化の頻度と範囲を想定し、その影響を的確に制御していくことが重要である。


 INDEX
  .NET&Windows Vistaへ広がるDirectXの世界
  第2回 DirectXマスターを目指すあなたが持つべき視点
  1.安定性に基づく分類
    2.COMと反復型開発
    3.DirectX開発の未来
 
インデックス・ページヘ  「.NET&Windows Vistaへ広がるDirectXの世界」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間