DirectX に関してよく寄せられる質問

Microsoft Corporation

2007 年 4 月

ここでは、Microsoft DirectX に関してよく寄せられる質問 (FAQ) をまとめました。

目次

  • DirectX の開発に関する一般的な問題
  • Direct3D に関する質問
  • DirectSound に関する質問
  • DirectX Extensions for Alias Maya
  • XInput に関する質問

DirectX の開発に関する一般的な問題

  • ゲーム開発者は x64 エディションのサポートについて意識する必要がありますか。
  • ゲーム開発者は、Windows 95、Windows 98、または Windows ME 向けのゲームをまだ発行する必要があるでしょうか。
  • ゲーム開発者は Windows 2000 向けのゲームをまだ発行する必要があるでしょうか。
  • Windows Vista の各種エディションの違いは何ですか。各エディションは DirectX アプリケーションにどのように影響しますか。
  • DirectX 10 は Windows XP でも使用できますか。
  • DirectShow はどうなったのでしょうか。DirectX SDK に見あたりません。
  • Windows Vista 用の DirectX ランタイムにはどのような変更が加えられたのですか。
  • ドライバーにバグがあるようです。どうすればよいですか。
  • サンプルをコンパイルしようとするとエラー メッセージが多数表示されるのはなぜですか。
  • グローバル一意識別子 (GUID) のシンボルが複数存在する、または存在しないというリンカー エラーが発生します。どうすればよいですか。
  • ポインターを下位のバージョン番号の DirectX インターフェイスにキャストすることはできますか。
  • 同じアプリケーションで DirectX 9 のコンポーネントと DirectX 8 以前のコンポーネントを併用することはできますか。
  • 同じアプリケーション内で Direct3D 9 と Direct3D 10 を併用することはできますか。
  • Release または AddRef メソッドの戻り値は何を意味しますか。
  • DirectX インターフェイスを解放する順序は重要ですか。
  • スマート ポインターとは何ですか。使用する必要はありますか。
  • DirectX アプリケーションのデバッグで問題が生じています。何かヒントはありますか。
  • リターン コードをチェックする正しい方法を教えてください。
  • Alt + Tab キーおよびその他のタスク切り替えを無効にするにはどうすればよいですか。
  • COM に関するお勧めの解説書はありますか。
  • マネージ コードとは何ですか。
  • 一般的な Windows プログラミングについて書かれた書籍はありますか。
  • Windows シンボル ファイルを使ってデバッグするにはどうすればよいですか。

ゲーム開発者は x64 エディションのサポートについて意識する必要がありますか。

もちろんあります。x64 テクノロジは市場に広く普及しています。ここ数年で新たに発売された CPU の大部分、そして AMD と Intel で開発中のプロセッサ製品のほとんどは、x64 に対応しています。Windows XP Professional x64 Edition には、2005 年 4 月にリリースされた x64 向け OS イネーブリング テクノロジが導入されています。x64 エディションには新世代の 64 ビット ネイティブ ドライバーが必要であるため、この最初のリリースは OEM 配布に限定されていました。

Windows Vista では、ユーザーが Windows ベースのコンピューターを購入する際に、32 ビット エディションと 64 ビット エディションのどちらかを選択できるようになっており、Windows Vista のライセンスは 32 ビットと 64 ビットのどちらのエディションの OS にも有効です。また、多数の 64 ビット ドライバーが同梱されているほか、Windows ロゴ プログラムの一環として、32 ビットと 64 ビット両方のネイティブ ドライバーを提供することがデバイスの製造元に求められています。

以上の要因によって、Windows の 64 ビット エディションの導入は大きく進むでしょう。2 GB を超える物理 RAM を搭載した新しいコンピューターが出荷されるようになったことから、64 ビット エディションの方が選ばれるようになり、32 ビット オペレーティング システムを使用する動機は非常に弱まっています。64 ビット テクノロジは 32 ビットのネイティブ コードを完全にサポートしますが、新しい 64 ビットのメモリー領域を最大限に活用するには、64 ビットをネイティブに実装する必要があります。どの 32 ビット アプリケーションも、64 ビット互換であることを出荷の最低必要条件にする必要があり、その要件を満たすことが Windows Vista との互換性を確保するための基準要件となります。一般に、非互換性の問題が生じるのは、Windows 3.1 オペレーティング システム用に設計された 16 ビット コードを使用している場合や、32 ビット ネイティブと 64 ビット ネイティブの両方の形式で提供されていないドライバーをインストールしている場合です。

64 ビット テクノロジの詳細については、「ゲーム開発者のための 64 ビット プログラミング」を参照してください。

ゲーム開発者は、Windows 95、Windows 98、または Windows ME 向けのゲームをまだ発行する必要があるでしょうか。

その必要はもうないでしょう。理由はパフォーマンスと機能セットにあります。

開発するゲームに必要な最小限の CPU 速度が 1.2GHz 以上である場合 (高性能のゲームでは一般的です)、対象となるコンピューターの圧倒的多数が Windows XP を搭載していることになるでしょう。CPU 速度が 1.2GHz を超えるコンピューターが販売される頃には、ほぼすべての製造元が Windows XP を既定のオペレーティング システムとしてインストールしていました。つまり Windows XP は、今日のゲーム開発者が活用すべき機能を多数備えています。

  • 向上したマルチタスキング。ビデオ、オーディオ、ゲームのエクスペリエンスが向上し、円滑になります。
  • 安定性が向上したビデオ ドライバー モデル。デバッグが容易になり、ゲーム プレイが円滑になり、パフォーマンスが向上します。
  • 容易になったネットワークの構成。マルチプレイヤー ゲームでのアクセス性が向上します。
  • ハード ドライブからの DMA 送信を既定でサポート。アプリケーションがより円滑かつ迅速にロードされるようになります。
  • Windows エラー報告。OS、ドライバー、アプリケーションの安定性が向上します。
  • Unicode のサポート。ローカライズの問題を大幅に単純化します。
  • 向上したセキュリティと安定性。ユーザー エクスペリエンスを高めます。
  • 最新のハードウェアに対するサポートの強化。最新のハードウェアのほとんどは Windows 98 ドライバーを使用しなくなっています。
  • 向上したメモリー管理。安定性とセキュリティが向上します。
  • 向上した NTFS ファイル システム。耐障害性が向上し、セキュリティ機能の性能が強化されています。

ゲーム開発者は Windows 2000 向けのゲームをまだ発行する必要があるでしょうか。

その必要はもうないでしょう。「ゲーム開発者は、Windows 95、Windows 98、または Windows ME 向けのゲームをまだ発行する必要があるでしょうか。」で挙げた理由に加えて、Windows 2000 には以下の機能がありません。

  • Windows XP は、ハイパー スレッディング、マルチコア、x64 などの高度なプロセッサ機能をサポートしています。
  • Windows XP は、アプリケーションでのバージョンの競合を大幅に軽減するサイド バイ サイド コンポーネントをサポートしています。
  • Windows XP は、悪質なプログラムの阻止とデバッグを支援する、実行防止によるメモリー保護をサポートしています。
  • Windows XP では、AGP および PCI Express ベースの高性能ビデオ カードのサポートが強化されました。
  • Windows XP では、製品のサポート コストの削減に役立つユーザーの簡易切り替え、リモート デスクトップ、およびリモート アシスタンスをサポートしています。
  • リファレンス (DirectX Developer SDK で提供) などのパフォーマンス ツールで、Windows 2000 がサポートされなくなりました。

つまり、Windows 2000 はコンシューマー向けオペレーティング システムとして設計または販売されたものではありません。

Windows Vista の各種エディションの違いは何ですか。各エディションは DirectX アプリケーションにどのように影響しますか。

Windows Vista ファミリには 5 つのエディションがあります。

  • Windows Vista Home Basic
  • Windows Vista Home Premium
  • Windows Vista Business
  • Windows Vista Enterprise
  • Windows Vista Ultimate

Home Basic と Home Premium はコンシューマーに的を絞ったバージョンで、家族のための安全設定 (以前の "保護者による制限") などの機能を備えています。Home Premium はメディア センター機能も搭載しています。Business と Enterprise は企業に的を絞ったエディションで、ドメイン参加やリモート デスクトップ/ターミナル サービスなどの機能を備えています。Ultimate エディションは、コンシューマー エディションとコーポレート エディションの全機能を 1 つに統合したバージョンです。いずれのエディションにも 32 ビット (x86) 版と 64 ビット (x64) 版があり、ユーザーは両方のプラットフォームに同じ製品識別子を使用できます。

各エディションの基礎となっているテクノロジは同じであり、使用する DirectX ランタイムおよびその他のコンポーネントのバージョンは、すべてのエディションで同じです。ただし、ゲームに関しては、エディションごとに若干の違いがあります。

  • すべてのエディションにゲーム エクスプローラーが搭載されていますが、[スタート](Start) メニューに [ゲーム](Games) ショートカットが表示されるのは、Home Basic、Home Premium、および Ultimate だけです。ただしゲーム エクスプローラーはすべてのエディションで使用可能であり ([スタート](Start) をクリックし、[すべてのプログラム](All Programs) をポイントして [ゲーム](Games) をクリック)、IGameExplorer インターフェイスはどのエディションでも機能します。

  • Windows 付属のゲームは、Business と Enterprise では既定で使用できないようになっていますが、管理者が使用可能にすることができます。

  • 家族のための安全設定およびゲーム レーティングは、Business と Enterprise では表示されず、その動作にも影響しません。また、Ultimate では、ドメインに参加しているときにこの 2 つの機能が無効になります。

ユーザー アカウント制御の設定には、すべてのエディションで同じ既定値が使用されますが、Business、Enterprise、および Ultimate では、ドメインのグループ ポリシーの設定によってこの既定の設定を上書きできます。たとえば、ビジネス環境でセキュリティを強化するには、ポリシー設定 [ユーザー アカウント制御: 標準ユーザーに対する昇格時のプロンプトの動作](User Account Control:For example, the policy setting) を [昇格の要求を自動的に拒否する](Automatically deny elevation requests) に設定することが考えられます。これでこの環境では、多数のユーザーが標準ユーザーとして実行するようになり、管理者として実行することを選択することすらできなくなります。このような状況では、レガシ セットアップの検出、または必要な実行レベルを "requireAdministrator" と指定しているマニフェストのために管理者権限を必要とするプログラム (インストーラーなど) を一切起動できません。それ以外のポリシー設定 ([ユーザー アカウント制御: 署名され検証された実行ファイルのみを昇格する](User Account Control: Only elevate executables that are signed and validated) など) でも、実行可能ファイルが Authenticode で署名されていない場合にインストーラーが機能しなくなるようにすることができます。

このようなポリシーの変更は、Windows Vista のどのエディションにも適用できますが、ドメインに参加しているコンピューターは特にその対象となります。

DirectX 10 は Windows XP でも使用できますか。

いいえ、できません。DirectX 10 を搭載する Windows Vista 付属の更新された DirectX ランタイムには、Windows XP SP2 のランタイム (DirectX 9.0c) をベースに、新しい Windows Display Driver Model (WDDM) および新しいオーディオ ドライバー スタックを操作するための変更が加えられ、オペレーティング システムでのその他の更新が反映されています。Windows Vista では、Direct3D 9 に加えて、適切なビデオ ハードウェアとドライバーがある場合に、2 つの新しいインターフェイス Direct3D9Ex と Direct3D10 がサポートされます。

この新しいインターフェイスは WDDM テクノロジに依存するため、以前のバージョンの Windows では使用できません。Windows Vista 向けの DirectX テクノロジに加えられたその他の変更も、この新しいバージョンの Windows に固有です。DirectX 10 という名前は、DirectX SDK で提供される多くのテクノロジ (XACT、XINPUT、D3DX) がこのバージョン番号で包括されないという点で、誤解を招くおそれがあります。このため、DirectX ランタイム全体をバージョン番号で呼ぶことにはほとんど意味がなくなりました。これは 9.0c も同様です。Windows Vista の DirectX 診断ツール (DXdiag.exe) では DirectX 10 と報告されますが、これは Direct3D 10 のみを指しています。

DirectShow はどうなったのでしょうか。DirectX SDK に見あたりません。

DirectShow は、2005 年 4 月に DirectX SDK から削除されました。DirectShow のヘッダー、ライブラリ、ツール、およびサンプルは、Windows® Software Development Kit (以前の Platform SDK) で入手できます。DirectX SDK の DirectSetup が、DirectShow のシステム コンポーネントの再配布を引き続きサポートしています。また、最新のコンポーネントは既に次のオペレーティング システムにインストールされています。Microsoft Windows XP Service Pack 2、Windows XP Professional x64 Edition、Windows Server 2003 Service Pack 1、および Windows Vista。

Windows Vista 用の DirectX ランタイムにはどのような変更が加えられたのですか。

主な変更は、新しい Windows Display Driver Model をサポートするために行われたものです。新しいドライバー モデル、Direct3D 9 への影響、および新しいグラフィック インターフェイス Direct3D 9Ex と Direct3D 10 の詳細については、「Windows Vista のグラフィック API」を参照してください。

Windows Vista Service Pack 1 には、DirectX ランタイムの更新版が付属しています。この更新版は、Windows Vista のサポート対象を Direct3D 10.1 に広げて、新しいオプションのハードウェア機能を公開します(Direct3D 10.1 をサポートするハードウェアはいずれも、Direct3D 10 の全機能を完全にサポートします)。

DirectSound は、マルチチャネルのソフトウェア バッファーをサポートする新しい Windows Vista オーディオ ドライバー スタックの機能を公開するように更新されました。Direct3D Retained Mode API は、Windows Vista で完全に削除されました。DirectPlay Voice も、DirectPlay の NAT ヘルパーおよび DirectInput のアクション マッパー UI と共に削除されました。Visual Basic 6.0 用の DirectX 7 インターフェイスと DirectX 8 インターフェイスは、Windows Vista ではサポートされません。

ドライバーにバグがあるようです。どうすればよいですか。

まず、リファレンス ラスタライザーで結果をチェックしてください。次に、最新の WHQL 認証版 IHV ドライバーで結果をチェックします。WHQL のステータスは、プログラムで IDirect3D9 インターフェイスの GetAdapterIdentifier() メソッドに D3DENUM_WHQL_LEVEL フラグを渡すことでチェックできます。WHQL 認証ドライバーの問題である場合は、バグの説明に dxdiag の出力と再現事例を添えて directx@microsoft.com までお送りください。その場合、件名は「WHQL Driver Bug」としてください。

サンプルをコンパイルしようとするとエラー メッセージが多数表示されるのはなぜですか。

インクルード パスを正しく設定していないと思われます。Microsoft Visual C++ をはじめとする多くのコンパイラには、以前のバージョンの SDK が組み込まれています。このため、インクルード パスが標準のコンパイラ インクルード ディレクトリを最初に検索すると、間違ったバージョンのヘッダー ファイルを取得することになります。この問題を解決するには、Microsoft DirectX のインクルード パスとライブラリ パスが最初に検索されるようにインクルード パスとライブラリ パスを設定します。SDK の dxreadmej.txt ファイルも参照してください。Visual C++ を使用している場合は、DirectX SDK をインストールするときに、インストーラーで自動的にインクルード パスを設定することもできます。

グローバル一意識別子 (GUID) のシンボルが複数存在する、または存在しないというリンカー エラーが発生します。どうすればよいですか。

使用する各種 GUID は、一度だけ定義されるようにしなければなりません。DirectX ヘッダー ファイルをインクルードする前に INITGUID シンボルを #define で定義すると、GUID の定義が挿入されます。したがって、これが 1 つのコンパイル ユニットでのみ行われるようにする必要があります。別の方法として、DirectX のすべての GUID の定義を含んだ dxguid.lib ライブラリとリンクすることもできます。この方法 (推奨) を使用する場合は、INITGUID シンボルを #define で定義しないでください。

ポインターを下位のバージョン番号の DirectX インターフェイスにキャストすることはできますか。

いいえ、できません。DirectX インターフェイスは COM インターフェイスです。つまり、上位の番号のインターフェイスが、対応する下位の番号のインターフェイスから派生していなくてはならないという要件はありません。したがって、DirectX オブジェクトへの別のインターフェイスを安全に取得するには、そのインターフェイスの QueryInterface メソッドを使用するしかありません。このメソッドは、すべての COM インターフェイスの派生元である標準の IUnknown インターフェイスの一部です。

同じアプリケーションで DirectX 9 のコンポーネントと DirectX 8 以前のコンポーネントを併用することはできますか。

各種コンポーネントはバージョンが異なっていても自由に併用できます。たとえば、同じアプリケーションで DirectInput 8 と Direct3D 9 を使用できます。ただし、一般には同じアプリケーション内で同じコンポーネントの複数のバージョンを併用することはできません。たとえば、DirectDraw 7 と Direct3D 9 を混在させることはできません (DirectDraw は DirectX 8 で Direct3D に吸収されたため、この 2 つは実質的に同じコンポーネントです)。ただし、これには例外があり、たとえば同じアプリケーションで Direct3D 9 と Direct3D 10 を使用することは可能です。

同じアプリケーション内で Direct3D 9 と Direct3D 10 を併用することはできますか。

はい、できます。Direct3D のこの 2 つのバージョンは、同じアプリケーション内で一緒に使用できます。

Release または AddRef メソッドの戻り値は何を意味しますか。

この戻り値は、オブジェクトの現在のリファレンス カウントです。ただし、COM の仕様ではこの値を信頼しないように明記されており、一般にはこの値はデバッグの目的でのみ使用されます。作成した DirectX オブジェクトへのリファレンスを他のさまざまなシステム オブジェクトが保持している可能性があるので、予期しない値がみられることがあります。このような理由から、リファレンス カウントがゼロになるまで Release を繰り返し呼び出すコードは作成しないでください。別のコンポーネントがまだ参照しているにもかかわらずオブジェクトが解放されるおそれがあるからです

DirectX インターフェイスを解放する順序は重要ですか。

COM インターフェイスではリファレンスがカウントされているので重要ではないはずです。ただし、DirectX の一部のバージョンには、インターフェイスの解放順序に関する既知のバグがあります。安全のために、インターフェイスの解放は、可能な限り作成したときと逆の順序で行うことをお勧めします。

スマート ポインターとは何ですか。使用する必要はありますか。

スマート ポインターは、ポインター機能をカプセル化することを目的とした C++ テンプレート クラスです。特に、COM インターフェイス ポインターをカプセル化することを目的とした標準のスマート ポインター クラスが存在します。このポインターは、キャストの代わりに自動的に QueryInterface を実行し、AddRef と Release を処理してくれます。このポインターを使用するかどうかは、主に好みの問題です。複数の AddRef と Release を使用してインターフェイス ポインターを何度もコピーしているコードでは、スマート ポインターを使用することでコードが簡潔になり、エラーも少なくなるでしょう。それ以外の状況では、スマート ポインターを使用する必要はありません。Visual C++ には標準の Microsoft COM スマート ポインターが組み込まれており、"comdef.h " ヘッダー ファイルで定義されています (ヘルプで com_ptr_t を検索してください)。

DirectX アプリケーションのデバッグで問題が生じています。何かヒントはありますか。

DirectX アプリケーションのデバッグで最もよくある問題は、DirectDraw サーフェスがロックされているときにデバッグしようとすることです。この場合、Microsoft Windows 9x システムでは "Win16 ロック" が発生し、デバッガー ウィンドウがペイントされなくなることがあります。通常は、サーフェスをロックするときに D3DLOCK_NOSYSLOCK フラグを指定することで、この問題を解消できます。Windows 2000 ではこの問題は発生しません。アプリケーションを開発する際に、デバッグ バージョンの DirectX ランタイムを実行するようにすると (SDK をインストールするときに選択)、ある程度のパラメーター検証が実行され、デバッガー出力に有益なメッセージが出力されるので便利です。

リターン コードをチェックする正しい方法を教えてください。

SUCCEEDED マクロと FAILED マクロを使用します。DirectX のメソッドは、複数の成功コードと失敗コードを返すことがあるので、

== D3D_OK

または同様のテストを実行するだけでは必ずしも十分ではありません。

Alt + Tab キーおよびその他のタスク切り替えを無効にするにはどうすればよいですか。

無効にはしないでください。タスクの切り替えは多数の状況で発生するので、ゲームでタスクの切り替えに適切に対応できる必要があります。これには、Alt +Tab キー、リモート デスクトップ接続、ユーザーの簡易切り替え、保護者による制限での使用制限のほか、多数のイベントがあります。

加えて、キーボード中心で制御する方式のゲームでは、Windows ロゴ キーを押したり、Shift キーでアクセシビリティ機能 StickyKeys を有効にしたりして、誤ってタスクを切り替えてしまうことがよくあります。機能を無効にしてこのような状況に対処する方法については、「ゲームでのショートカット キーの無効化」で説明されているテクニックを参照してください。

COM に関するお勧めの解説書はありますか。

Dale Rogerson による『Inside COM』(Microsoft Press 発行、日本語版は『Inside COM』(アスキー出版局発行)) は、COM の優れた入門書です。COM のさらに詳しい解説書として、Don Box による『Essential COM』(Longman 発行、日本語版は『Essential COM』(アスキー出版局発行)) もお勧めします。

マネージ コードとは何ですか。

マネージ コードは、.NET Framework の共通言語ランタイム (CLR) によって実行が管理されるコードです。これは、ネイティブに実行されるコードとランタイムの間の協力契約を示します。この契約では、ランタイムが実行のどの時点でも CPU の実行を停止して、現在の CPU 命令アドレス固有の情報を取得できることが指定されています。照会可能でなければならない情報は、一般にレジスタやスタック メモリーの内容など、実行時ステートに関連しています。

コードが実行される前に、IL (中間言語) がネイティブの実行可能コードにコンパイルされます。このコンパイルは、マネージ実行環境 (正確には、マネージ実行環境をターゲットにする方法を認識しているランタイム対応のコンパイラ) によって行われるので、マネージ実行環境はコードが実行する処理の内容を保証できます。マネージ実行環境では、トラップや適切なガベージ コレクションのフック、例外処理、タイプ セーフ、配列境界とインデックスのチェックなどを挿入できます。たとえば、このようなコンパイラによってスタック フレームなどが確実に正しくレイアウトされるので、ガベージ コレクターを別のスレッドでバックグラウンドに実行して、アクティブなコール スタックを絶えず探索し、すべてのルートを検出し、すべてのライブ オブジェクトを追跡することができます。また、IL にはタイプ セーフという概念があるので、実行エンジンはタイプ セーフの保証を維持して、セキュリティ ホールにつながりやすいあらゆる種類のプログラミング ミスを軽減します。

これとは対照的なのがアンマネージ環境です。アンマネージ実行可能ファイルは、基本的にはメモリーにロードされるバイナリ イメージ、つまり x86 コードです。プログラム カウンターはメモリーに配置され、OS はこのカウンターまでしか把握しません。メモリー管理やポート I/O などは保護されますが、システムはアプリケーションが何を行っているかを実際に認識していません。このため、アプリケーションの実行結果については一切保証されません。

一般的な Windows プログラミングについて書かれた書籍はありますか。

多数ありますが、特にお勧めするのは次の 2 冊です。

  • Charles Petzold による『Programming Windows』(Microsoft Press 発行、日本語版は『プログラミング Windows』(アスキー出版局発行))
  • Jeffrey Richter による『Programming Applications for Windows』(Microsoft Press 発行)

Windows シンボル ファイルを使ってデバッグするにはどうすればよいですか。

Microsoft では、すべてのシステム DLL (およびその他いくつかの DLL) のストリップ シンボルを公開しています。このシンボルにアクセスするには、Visual Studio 内でプロジェクト設定のシンボル パスに以下を追加します。

srv*http://msdl.microsoft.com/download/symbols

シンボルをローカルにキャッシュする場合は、次の構文を使用します。

srv*c:\cache*http://msdl.microsoft.com/download/symbols

c:\cache は、シンボル ファイルをキャッシュするローカル ディレクトリです。

Direct3D に関する質問

  • Direct3D に関する一般的な質問
  • ジオメトリ (頂点) 処理
  • パフォーマンス チューニング
  • D3DX ユーティリティ ライブラリ

Direct3D に関する一般的な質問

  • 3D グラフィックスのテクニックに関する情報はどこで得られますか。
  • Direct3D はハードウェアが提供していない機能をエミュレートしますか。
  • Direct3D にはソフトウェア ラスタライザーが含まれていますか。
  • DirectX グラフィックスでカラー キーイングを行うにはどうすればよいですか。
  • Direct3D ジオメトリ コードは 3DNow! 命令や Pentium III SIMD 命令を利用していますか。
  • Z バッファーに透明なピクセルが書き込まれるのを防ぐ方法はありますか。
  • ステンシル バッファーとは何ですか。
  • ステンシル バッファーを使ってシャドウ ボリュームをレンダリングするにはどうすればよいですか。
  • テクセル アライメント規則とは何ですか。1 対 1 のマッピングを得るにはどうすればいいですか。
  • D3DCREATE_PUREDEVICE フラグの目的は何ですか。
  • マルチモニター システムでディスプレイ デバイスを列挙するにはどうすればよいですか。
  • 固定機能バンプマッピングは D3D9 でどうなったのですか。

3D グラフィックスのテクニックに関する情報はどこで得られますか。

このテーマに関する定番の書籍は、Foley、Van Dam らによる『Computer Graphics: Principles and Practice』 (日本語版は『コンピュータグラフィックス 理論と実践』(オーム社発行)) です。この書籍は、ジオメトリ、ラスタライズ、ライティングの各テクニックの数学的基礎について理解するために役立ちます。Usenet グループ comp.graphics.algorithms の FAQ にも有用な資料が掲載されています。

Direct3D はハードウェアが提供していない機能をエミュレートしますか。

状況によります。Direct3D は、高機能のソフトウェア頂点処理パイプライン (カスタム頂点シェーダーのサポートを含む) を備えています。ただし、ピクセル レベルの演算についてはエミュレーションが行われません。アプリケーションで適切な Caps ビットをチェックし、ValidateDevice API を使って何がサポートされているのかを調べる必要があります。

Direct3D にはソフトウェア ラスタライザーが含まれていますか。

パフォーマンス アプリケーション用のものはありません。ドライバー検証用のリファレンス ラスタライザーは提供されていますが、その実装はパフォーマンスではなく精度を考慮して設計されています。Direct3D はプラグイン ソフトウェア ラスタライザーをサポートしています。

DirectX グラフィックスでカラー キーイングを行うにはどうすればよいですか。

カラー キーイングは直接にはサポートされていないので、アルファ ブレンドを使ってカラー キーイングをエミュレートする必要があります。 これには D3DXCreateTextureFromFileEx() 関数を利用できます。この関数はカラー キー パラメーターを受け取り、ソース イメージ内の指定されたカラーを含んでいるすべてのピクセルを透明な黒のピクセルに置き換えて、新たなテクスチャーを作成します。

Direct3D ジオメトリ コードは 3DNow! 命令や Pentium III SIMD 命令を利用していますか。

はい。Direct3D ジオメトリ パイプラインは、プロセッサ タイプに応じていくつかの異なるコード パスを持っており、3DNow! 命令や Pentium III SIMD 命令を利用できる環境では、それらの命令が提供する特別な浮動小数点演算を利用します。これには、カスタム頂点シェーダーの処理が含まれます。

Z バッファーに透明なピクセルが書き込まれるのを防ぐ方法はありますか。

アルファ値が所定のしきい値より大きいか小さいかによって、ピクセルをフィルタリングすることができます。この動作を制御するには、レンダリング ステートの ALPHATESTENABLE、ALPHAREF、ALPHAFUNC を使用します。

ステンシル バッファーとは何ですか。

ステンシル バッファーは、ピクセル単位の情報を格納する追加のバッファーであり、Z バッファーによく似ています。実際に、このバッファーは Z バッファーのビットの一部として含まれています。一般的なステンシル/Z バッファーの形式は、15 ビットの Z と 1 ビットのステンシル、または 24 ビットの Z と 8 ビットのステンシルです。ポリゴンがレンダリングされるときには、ステンシル バッファーの内容に対してピクセル単位で単純な算術演算を実行することができます。たとえば、ステンシル バッファーのインクリメントやデクリメントを行ったり、ステンシル値が単純な比較テストに合格しなかったときにピクセルを描画しないようにすることができます。これは、フレーム バッファーの領域をマークし、マークした (またはマークしていない) 領域のみをレンダリングするエフェクトに便利です。シャドウ ボリュームなどのボリューム エフェクトはその一例です。

ステンシル バッファーを使ってシャドウ ボリュームをレンダリングするにはどうすればよいですか。

この種のボリュメトリック ステンシル バッファー エフェクトで重要なのは、ステンシル バッファーと Z バッファーの間の相互作用です。シャドウ ボリュームを含んだシーンは、3 段階でレンダリングされます。まず、シャドウのないシーンが通常どおりに Z バッファーを使ってレンダリングされます。次に、シャドウがステンシル バッファー内で次のようにマークされます。シャドウ ボリュームの前面は非表示のポリゴンを使って描画されますが、その際にあらかじめ Z テストを有効に、Z 書き込みを無効にして、Z テストに合格したすべてのピクセルでステンシル バッファーがインクリメントされます。シャドウ ボリュームの背面も同じようにレンダリングされますが、ステンシル値はデクリメントされます。

では、ピクセル単位で考えてみましょう。カメラがシャドウ ボリューム内になければ、シーン内での対応する点には 4 つの可能性があります。カメラから点への光線がシャドウ ボリュームと交差していなければ、シャドウ ポリゴンは描画されないことになり、ステンシル バッファーはゼロのままです。交差していて、点がシャドウ ボリュームの前にあれば、シャドウ ポリゴンは Z バッファーから除外され、ステンシルはやはり変更されません。点がシャドウ ボリュームの後ろにあれば、シャドウの前面と同じ数の背面がレンダリングされることになり、ステンシルはインクリメントとデクリメントが同じ回数だけ行われてゼロになります。

最後の可能性は、点がシャドウ ボリュームの内部にある場合です。この場合、シャドウ ボリュームの背面は Z バッファー内で除外されますが、前面は除外されず、ステンシル バッファーはゼロ以外の値になります。その結果、フレーム バッファーのシャドウ内にある部分のステンシル値がゼロ以外になります。最後に、実際にシャドウをレンダリングするために、ゼロ以外のステンシル値を持つピクセルだけに作用するように設定されたアルファ ブレンド ポリゴンによって、シーン全体が更新されます。このテクニックの例を、DirectX SDK 付属の "Shadow Volume" サンプルで参照できます。

テクセル アライメント規則とは何ですか。1 対 1 のマッピングを得るにはどうすればいいですか。

これについては Direct3D 9 のドキュメントで詳しく説明されています。簡単にまとめると、テクセルに合わせて正しくアライメントするには、スクリーン座標を ?0.5 ピクセルだけずらす必要があるということです。現在、ほとんどのカードはテクセル アライメント規則に準拠していますが、古いカードやドライバーにはそうでないものもあります。このような場合は、ハードウェア ベンダーに連絡して、更新されたドライバーを要求するか、対策の指示を仰いでください。Direct3D 10 ではこの規則が無効となったので注意してください。

D3DCREATE_PUREDEVICE フラグの目的は何ですか。

デバイス作成時に D3DCREATE_PUREDEVICE フラグを使用すると、ピュア デバイスが作成されます。ピュア デバイスには現在のステートが保存されないため (ステート変更時)、多くの場合パフォーマンスが向上します。また、このデバイスはハードウェア頂点処理を必要とします。一般にピュア デバイスは、開発とデバッグが完了し、最良のパフォーマンスを得ることが必要になった段階で使用します。

ピュア デバイスの欠点は、Get* API 呼び出しがすべてサポートされない点です。つまり、ピュア デバイスを使用してパイプライン ステートを照会することはできません。このため、アプリケーション実行中のデバッグが難しくなります。ピュア デバイスで無効になるメソッドは次のとおりです。

  • ID3D10Device9::GetClipPlane
  • ID3D10Device9::GetClipStatus
  • ID3D10Device9::GetLight
  • ID3D10Device9::GetLightEnable
  • ID3D10Device9::GetMaterial
  • ID3D10Device9::GetPixelShaderConstantF
  • ID3D10Device9::GetPixelShaderConstantI
  • ID3D10Device9::GetPixelShaderConstantB
  • ID3D10Device9::GetRenderState
  • ID3D10Device9::GetSamplerState
  • ID3D10Device9::GetTextureStageState
  • ID3D10Device9::GetTransform
  • ID3D10Device9::GetVertexShaderConstantF
  • ID3D10Device9::GetVertexShaderConstantI
  • ID3D10Device9::GetVertexShaderConstantB

ピュア デバイスのもう 1 つの欠点は、冗長なステート変更がフィルタリングされないことです。ピュア デバイスを使用する場合は、アプリケーションでレンダリング ループでのステート変更の回数を最小限に抑える必要があります。たとえば、ステートが複数回設定されないようにステート変更をフィルタリングします。このトレードオフはアプリケーションによって異なります。フレームあたりの Set 呼び出しが 1000 回を超えている場合は、非ピュア デバイスを使用して冗長性を自動的にフィルタリングすることを検討してください。

他のパフォーマンスの問題と同様に、ピュア デバイスを使用することでアプリケーションのパフォーマンスが改善されるかどうかを確認するには、ピュア デバイスを使用した場合と非ピュア デバイスを使用した場合とでアプリケーションのパフォーマンスを比較するしかありません。ピュア デバイスには、API の CPU オーバーヘッドを軽減してアプリケーションを高速化する可能性があります。ただし注意してください。シナリオによっては、ピュア デバイスを使用するとアプリケーションの速度が低下します (冗長なステート変更が原因で CPU の作業が増えるため)。どちらのタイプのデバイスがアプリケーションに適しているかが不明であり、そのアプリケーションで冗長な変更をフィルタリングしない場合は、非ピュア デバイスを使用してください。

マルチモニター システムでディスプレイ デバイスを列挙するにはどうすればよいですか。

アプリケーションで IDirect3D9 インターフェイスのメソッドを使った単純な繰り返し処理を行うことで、列挙を実行できます。システム内のディスプレイ アダプターの数を確認するには、GetAdapterCount を呼び出します。アダプターの接続先の物理的なモニターを特定するには、GetAdapterMonitor を呼び出します (このメソッドが返す HMONITOR をWin32 API GetMonitorInfo で使うことで、物理的なモニターに関する情報が得られます)。特定のディスプレイ アダプターの特性を確認したり、そのアダプターで Direct3D デバイスを作成したりする場合は、GetDeviceCaps や CreateDevice などのメソッドを呼び出すときに、D3DADAPTER_DEFAULT の代わりに該当するアダプター番号を渡すだけなので簡単です。

固定機能バンプマッピングは D3D9 でどうなったのですか。

Direct3D 9 より、サポート可能な同時テクスチャー数が 2 を超えるカードでの検証が強化されました。一部の古いカードでは、特定のアルファ モジュレート演算を使用する際に、テクスチャー ステージを 3 つしか使用できません。この 3 つのステージは、エンボス バンプマッピングに最もよく使用されます。これは D3D9 でも実行できます。

高さフィールドは、アルファ チャンネルに格納する必要があり、次のようにライト コントリビューションを調整するために使用されます。

// Stage 0 is the base texture, with the height map in the alpha channel
m_pd3dDevice->SetTexture(0, m_pEmbossTexture );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0 );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
if( m_bShowEmbossMethod )
{
 // Stage 1 passes through the RGB channels (SELECTARG2 = CURRENT), and 
 // does a signed add with the inverted alpha channel. 
 // The texture coords associated with Stage 1 are the shifted ones, so 
 // the result is:
 //    (height - shifted_height) * tex.RGB * diffuse.RGB
   m_pd3dDevice->SetTexture( 1, m_pEmbossTexture );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_ADDSIGNED );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE|D3DTA_COMPLEMENT );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );

   // Set up the alpha blender to multiply the alpha channel 
   // (monochrome emboss) with the src color (lighted texture)
   m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
   m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
   m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
}

このサンプルは、他の古いサンプルと同様に、最新の SDK リリースには同梱されておらず、将来の SDK リリースにも同梱されません。

ジオメトリ (頂点) 処理

  • 頂点ストリームのしくみについて教えてください。
  • 頂点シェーダーとは何ですか。
  • 頂点シェーダーはパースペクティブの分割またはクリッピングを実行しますか。
  • 頂点シェーダーでジオメトリを生成することはできますか。
  • 固定機能ジオメトリ パイプラインの結果にカスタム頂点シェーダーを適用すること (またはその逆) は可能ですか。
  • ハードウェアがサポートしていない場合でもカスタム頂点シェーダーを使用できますか。
  • ハードウェアがカスタム頂点シェーダーをサポートするかどうかを確認するにはどうすればよいですか。
  • 頂点シェーダーで利用できる定数レジスタはいくつありますか。
  • テクスチャー座標が異なる頂点間で位置データを共有することはできますか。
  • インデックスが付けられたプリミティブのリストを送信した場合、Direct3D はバッファー内のすべての頂点を処理するのでしょうか、それともインデックスが付けられたものだけを処理するのでしょうか。
  • インデックス バッファーとは何ですか。
  • 32 ビット インデックスが型としてサポートされているようですが、どのデバイスでも使用できますか。
  • ソフトウェア頂点処理は 64 ビットをサポートしますか。

頂点ストリームのしくみについて教えてください。

Direct3D は、1 つまたは複数の頂点ストリームからパイプラインの処理部分に入力された個々の頂点を組み合わせます。頂点ストリームが 1 つしかないケースは、頂点が 1 つのソースからしか入力されなかった DirectX 8 より前の古いモデルに相当します。DirectX 8 では、個々の頂点成分がさまざまなソースから入力される可能性があります。たとえば、1 つの頂点バッファーが位置と法線を保持し、別の頂点バッファーがカラー値とテクスチャー座標を保持しているような場合です。

頂点シェーダーとは何ですか。

頂点シェーダーは、1 つの頂点を処理するためのプロシージャです。これはアセンブリに似た単純な言語を使って定義され、D3DX ユーティリティ ライブラリによってアセンブルされて、Direct3D が受け付けるトークン ストリームへと変換されます。頂点シェーダーは、入力として 1 つの頂点と一組の定数値を受け取り、頂点位置 (クリップ空間内) およびオプションとして一連の色とテクスチャー座標 (いずれもラスタライズに使用) を出力します。カスタム頂点シェーダーを使用する場合は、頂点の成分に Direct3D からセマンティックスが適用されなくなり、頂点は各自で作成した頂点シェーダーが解釈する任意のデータとなるので注意してください。

頂点シェーダーはパースペクティブの分割またはクリッピングを実行しますか。

いいえ。頂点シェーダーは、トランスフォームされた頂点位置の、クリップ空間内での同次座標を出力します。パースペクティブの分割とクリッピングは、シェーダーの後で自動的に実行されます。

頂点シェーダーでジオメトリを生成することはできますか。

頂点シェーダーは、頂点を作成または破棄することはできず、一度に 1 つの頂点に作用し、1 つの未処理の頂点を入力として受け取り、1 つの処理済みの頂点を出力します。このため、既存のジオメトリの処理には使用できますが (変形の適用やスキニング操作の実行)、新しいジオメトリそのものを実際に生成することはできません。

固定機能ジオメトリ パイプラインの結果にカスタム頂点シェーダーを適用すること (またはその逆) は可能ですか。

いいえ。どちらか一方を選ぶ必要があります。カスタム頂点シェーダーを使用する場合は、頂点トランスフォーム全体を実行する必要があります。

ハードウェアがサポートしていない場合でもカスタム頂点シェーダーを使用できますか。

はい。Direct3D のソフトウェア頂点処理エンジンは、驚くほど高性能のカスタム頂点シェーダーを完全にサポートしています。

ハードウェアがカスタム頂点シェーダーをサポートするかどうかを確認するにはどうすればよいですか。

ハードウェアで頂点シェーダーをサポートできるデバイスは、自身がサポートしている頂点シェーダーのバージョン レベルを通知するために、D3DCAPS9::VertexShaderVersion フィールドに値を格納することになっています。特定のレベルの頂点シェーダーをサポートしていると主張するデバイスは、そのレベル以下の仕様を満たすすべての有効な頂点シェーダーをサポートする必要があります。

頂点シェーダーで利用できる定数レジスタはいくつありますか。

バージョン 1.0 の頂点シェーダーをサポートするデバイスは、最低でも 96 個の定数レジスタをサポートすることを求められます。デバイスがこの最小数よりも多くの定数レジスタをサポートする場合は、D3DCAPS9::MaxVertexShaderConst フィールドでそれを確認できます。

テクスチャー座標が異なる頂点間で位置データを共有することはできますか。

キューブの各面に異なるテクスチャーを使用したい場合などは、このようなことができると便利でしょう。残念ながら、この質問の答えは "いいえ" です。現時点では、頂点の成分に個別にインデックスを付けることはできません。複数の頂点ストリームがある場合でも、すべてのストリームにまとめてインデックスが付けられます。

インデックスが付けられたプリミティブのリストを送信した場合、Direct3D はバッファー内のすべての頂点を処理するのでしょうか、それともインデックスが付けられたものだけを処理するのでしょうか。

ソフトウェア ジオメトリ パイプラインを使用する場合は、Direct3D が、インデックス付けされた頂点を "オンデマンド" でトランスフォームするのではなく、送信された範囲のすべての頂点をトランスフォームします。高密度にパックされた (ほとんどの頂点が使用されている) データでは、特に SIMD 命令が使用できる場合に、この処理の方が効率的です。データが低密度にパックされている (使用されていない頂点が多い) 場合には、冗長なトランスフォームが多くなりすぎないように、データの再配置を検討するとよいでしょう。ハードウェア ジオメトリ アクセラレーションを使用する場合は、頂点が必要に応じてオンデマンドでトランスフォームされるのが一般的です。

インデックス バッファーとは何ですか。

インデックス バッファーは頂点バッファーに似ていますが、DrawIndexedPrimitive 呼び出しで使用されるインデックスを含んでいます。頂点バッファーと同じ理由から、可能な限り、アプリケーションが割り当てたメモリーではなく、インデックス バッファーを使うことを強くお勧めします。

32 ビット インデックスが型としてサポートされているようですが、どのデバイスでも使用できますか。

いいえ。D3DCAPS9::MaxVertexIndex フィールドをチェックして、デバイスがサポートしている最大インデックス値を調べる必要があります。D3DFMT_INDEX32 型のインデックス バッファーをサポートするには、この値が 2 の 16 乗 -1 (0xffff) よりも大きくなければなりません。また、デバイスによっては、32 ビット インデックスをサポートしていても、サポートしている最大インデックス値が 2 の 32 乗 -1 (0xffffffff) より小さい場合があることに注意してください。この場合、アプリケーションはデバイスから報告された上限を守る必要があります。

ソフトウェア頂点処理は 64 ビットをサポートしますか。

x64 向けに最適化されたソフトウェア頂点パイプラインはありますが、IA 64 向けのものは存在しません。

パフォーマンス チューニング

  • Direct3D アプリケーションのパフォーマンスを改善するにはどうすればよいですか。
  • どのプリミティブ タイプ (ストリップ、ファン、リストなど) を使用すればよいですか。
  • AGP メモリーを除くカードのテクスチャー メモリーの合計を調べるにはどうすればよいですか。
  • 動的なデータを生成する場合は、どのように頂点バッファーを使用すればいいでしょうか。
  • D3DVERTEXELEMENT9 構造体で指定しなければならない情報が増えたのはなぜですか。

Direct3D アプリケーションのパフォーマンスを改善するにはどうすればよいですか。

パフォーマンスを最適化する際に注目する必要のある重要な領域を以下に示します。

バッチ サイズ

Direct3D は、大きなサイズのプリミティブ バッチ向けに最適化されています。1 回の呼び出しで送信できるポリゴンの数が多いほど、パフォーマンスは向上します。1 回のプリミティブ呼び出しで平均 1000 個の頂点が目安です。これよりも少ないと最適なパフォーマンスが得られなくなり、これよりも多いとリターンが減少するほか、同時実行を検討する際に (下記参照) 矛盾が生じることになります。

ステート変更

レンダリング ステートの変更は、特にテクスチャーを変更する際に負荷の高い操作となることがあります。このため、1 つのフレームで行われるステート変更の回数を、可能な限り少なくすることが重要です。また、頂点バッファーまたはインデックス バッファーの変更も最小限に抑えるようにしてください。

    DirectX 8 以降は、それまでのバージョンと比べて、頂点バッファーの変更がそれほど負荷の高い操作ではなくなりました。ただし、頂点バッファーの変更を可能な限り抑えるのを習慣としておくとよいでしょう。

同時実行

レンダリングを他の処理と同時に実行できれば、システム パフォーマンスを最大限に活用することになります。この目標は、レンダリング ステートの変更を減らすという目標と矛盾することがあります。ステート変更を減らすためのバッチ処理と、同時実行を実現するためにドライバーに早めにデータを送り出す処理を両立させる必要があります。複数の頂点バッファーをラウンドロビン方式で使用すると、同時実行に役立つ場合があります。

テクスチャーのアップロード

テクスチャーをデバイスにアップロードすると、帯域幅が消費され、頂点データとの間で帯域幅の競合が生じます。このため、テクスチャー メモリーを過度にコミットしないことが重要です。そうしないと、キャッシュ スキームでフレームごとに過剰な量のテクスチャーをアップロードすることになります。

頂点バッファーとインデックス バッファー

アプリケーションが割り当てたプレーンなメモリー ブロックではなく、常に頂点バッファーとインデックス バッファーを使用するようにしてください。少なくとも、頂点バッファーとインデックス バッファーのロック セマンティクスによって冗長なコピー操作を回避できます。ドライバーによっては、頂点バッファーまたはインデックス バッファーをハードウェアからアクセスしやすいメモリー (ビデオ メモリーや AGP メモリー) に配置できる場合があります。

ステート マクロ ブロック

ステート マクロ ブロックは DirectX 7.0 で導入されました。これは一連のステート変更 (ライティング、マテリアル、行列の変更を含む) をマクロに記録し、後に 1 回の呼び出しで再生できるようにするメカニズムを提供します。これには 2 つの利点があります。

  • 多数の呼び出しを 1 つにまとめることで、呼び出しのオーバーヘッドが軽減されます。
  • 対応するドライバーがステート変更を事前に解析してコンパイルできるようになるので、グラフィック ハードウェアへの送信処理がはるかに速くなります。

それでもステート変更には高い負荷がかかりますが、ステート マクロを使用することで少なくとも部分的に負荷を軽減できます。Direct3D デバイスは 1 つだけ使用してください。複数のターゲットにレンダリングする必要がある場合は、SetRenderTarget を使用します。複数の 3D ウィンドウを持つウィンドウ アプリケーションを作成する場合は、CreateAdditionalSwapChain API を使用します。ランタイムは 1 つのデバイスに対して最適化されるので、複数のデバイスを使用すると実行速度がかなり犠牲になります。

どのプリミティブ タイプ (ストリップ、ファン、リストなど) を使用すればよいですか。

現実のデータに含まれるメッシュの多くは、複数のポリゴンが共有する頂点を持っています。パフォーマンスを最大化するには、頂点が重複してトランスフォームされ、バス経由でレンダリング デバイスに送信されることを減らす必要があります。単純なトライアングル リストは、頂点が共有されないことから、最も適していない方法であるのは明らかです。したがって、ストライプかファンのどちらかを使用します。これは、ポリゴン間が特定の接続関係で結ばれ、インデックス付きリストが使用されることを意味します。データが自然にストリップやファンになる場合は、ドライバーに送信されるデータを最小限に抑えられるので、これが最適な方法となります。ただし、メッシュをストリップとファンに分解すると、多数の断片が発生し、DrawPrimitive 呼び出しの回数が多くなってしまうことがよくあります。このため、1 つのトライアングル リストに 1 つの DrawIndexedPrimitive 呼び出しを使用するのが、通常は最も効率的な方法です。インデックス付きリストを使用するもう 1 つの利点は、連続するトライアングルが頂点を 1 つしか共有していなくも有利であるという点です。要約すると、データが自然と大きなストリップやファンになる場合はストリップまたはファンを使用し、それ以外の場合はインデックス付きリストを使用してください。

AGP メモリーを除くカードのテクスチャー メモリーの合計を調べるにはどうすればよいですか。

IDirect3DDevice9::GetAvailableTextureMem() は、AGP を含む利用可能なメモリーの合計を返します。ビデオ メモリーの量を仮定してリソースを割り当てるのは好ましくありません。たとえば、カードがユニファイド メモリー アーキテクチャ (UMA) を採用していたり、テクスチャーを圧縮できたりするとどうなるでしょうか。予想以上のスペースを利用できる可能性があります。 リソースを作成し、"メモリー不足" のエラーをチェックしたうえで、テクスチャーを縮小するようにしてください。たとえば、テクスチャーの上位ミップレベルを削除することが考えられます。

動的なデータを生成する場合は、どのように頂点バッファーを使用すればいいでしょうか。

  1. D3DUSAGE_DYNAMIC と D3DUSAGE_WRITEONLY の各利用フラグと D3DPOOL_DEFAULT プール フラグを使用して頂点バッファーを作成します(ソフトウェア頂点処理を使用している場合は、D3DUSAGE_SOFTWAREPROCESSING も指定します)。
  2. I = 0。
  3. ステートを設定します (テクスチャー ステート、レンダリング ステートなど)。
  4. バッファーにスペースがあるかどうか、つまり I + M <= N かどうかを確認します(M は新しい頂点の数です)。
  5. スペースがある場合は、D3DLOCK_NOOVERWRITE で頂点バッファーをロックします。これにより、頂点を追加することと、既にバッチ化した頂点を変更しないことが、Direct3D とドライバーに通知されます。このため、DMA 操作が進行中であっても中断されることはありません。スペースがない場合は 11 に進みます。
  6. I で M 個の頂点を入力します。
  7. アンロックします。
  8. Draw[Indexed]Primitive を呼び出します。インデックスのないプリミティブには、StartVertex パラメーターとして I を使用します。インデックス付きプリミティブでは、インデックスが頂点バッファーの正しい部分をポイントしていることを確認します (そのためには、SetIndices 呼び出しの BaseVertexIndex パラメーターを使う方法が最も簡単です)。
  9. I += M。
  10. 3 に戻ります。
  11. スペースが足りなくなったので、新しい頂点バッファーから始めます。DMA 操作が実行されている可能性があるので、同じ頂点バッファーは使用しません。D3DLOCK_DISCARD フラグで同じ頂点バッファーをロックすることで、Direct3D とドライバーに対し、「古いポインターを使い終わって、古い内容はもう不要なので、新しいポインターを渡してほしい」ということを通知します。
  12. I = 0。
  13. 4 (または 6) に戻ります。

D3DVERTEXELEMENT9 構造体で指定しなければならない情報が増えたのはなぜですか。

Direct3D 9 で、頂点ストリーム宣言は単なる DWORD 配列ではなく D3DVERTEXELEMENT9 構造体の配列になりました。ランタイムはこの新たなセマンティクスと使用状況の情報を使用して、頂点ストリームの内容を頂点シェーダーの入力レジスタ/変数にバインドします。Direct3D 9 では、頂点宣言が頂点シェーダーから切り離されているため、ランタイムがシェーダーに必要なデータのみをバインドするので、シェーダーでさまざまな形式のジオメトリを扱いやすくなっています。

新しい頂点宣言は、固定機能パイプラインとシェーダーのどちらでも使用できます。固定機能パイプラインでは、SetVertexShader を呼び出す必要はありません。ただし、以前に頂点シェーダーを使用していて固定機能パイプラインに切り替える場合は、SetVertexShader(NULL) を呼び出します。この作業が完了したら、SetFVF を呼び出して FVF コードを宣言する必要があります。

頂点シェーダーを使用する場合は、頂点シェーダー オブジェクトを指定して SetVertexShader を呼び出します。さらに、SetFVF を呼び出して頂点宣言を設定します。これには、FVF に内在する情報が使用されます。FVF で表現できない頂点宣言をサポートする SetVertexDeclaration を、SetFVF の代わりに呼び出すことができます。

D3DX ユーティリティ ライブラリ

  • D3DX イメージ ファイル ローダー関数でサポートされているファイル形式は何ですか。
  • D3DX のテキスト レンダリング関数が動作しないようです。何が間違っているのでしょうか。
  • サーフェスやテクスチャーの内容をファイルに保存することはできますか。
  • ゲームで上位レベル シェーダー言語 (HLSL) を使用するにはどうすればよいですか。
  • 新しいシェーダー コンパイラ フラグの目的は何ですか。
  • エフェクトからシェーダーを取得する正しい方法を教えてください。
  • HLSL の noise() 組み込み関数は何に使用するのですか。
  • ピクセル シェーダー モデル 2.0 と 2.a のどちらを使用するかを判断するにはどうすればよいですか。
  • プリコンパイルしたエフェクト シェーダーでパラメーターにアクセスするにはどうすればよいですか。
  • エフェクトやその他のリソースにユーザー データを追加する方法はありますか。
  • サブセットを定義した後に ID3DXMesh オブジェクトのレンダリングが非常に遅くなるのはなぜですか。
  • 事前計算済み放射輝度伝播 (PRT) についてよく聞くのですが、詳細はどこで学ぶことができますか。
  • テクスチャーへのレンダリングを行い、アンチ エイリアシングを活用するにはどうすればよいですか。

D3DX イメージ ファイル ローダー関数でサポートされているファイル形式は何ですか。

D3DX イメージ ファイル ローダー関数は、BMP、TGA、JPG、DIB、PPM、DDS の各ファイルをサポートしています。

D3DX のテキスト レンダリング関数が動作しないようです。何が間違っているのでしょうか。

ID3DXFont::DrawText 関数を使用する際によくある間違いは、カラー パラメーターにゼロのアルファ成分を指定したために、テキストが完全に透明になってしまう (つまり見えなくなってしまう) というものです。完全に不透明なテキストにするには、カラー パラメーターのアルファ成分を完全な飽和状態 (255) にしてください。

サーフェスやテクスチャーの内容をファイルに保存することはできますか。

DirectX 8.1 SDK では、D3DX ライブラリに特にこれを目的とした関数D3DXSaveSurfaceToFile() と D3DXSaveTextureToFile() が追加されています。この 2 つの関数では、BMP または DDS 形式のファイルにイメージを保存できます。以前のバージョンでは、サーフェスをロックしてイメージ データを読み込んだうえで、ビットマップ ファイルに書き込む必要がありました。ビットマップを格納する関数の作成については、「Windows GDI: Storing an Image (Windows GDI: イメージの格納)」を参照してください。

あるいは、GDI+ を使用してイメージをさまざまな形式で保存することができます。ただしそのためには、追加のサポート ファイルをアプリケーションと共に配布する必要があります。

ゲームで上位レベル シェーダー言語 (HLSL) を使用するにはどうすればよいですか。

HLSL をゲーム エンジンに組み込む方法は 3 つあります。

  • シェーダー ソースを頂点またはピクセル シェーディング アセンブリにコンパイルし (コマンド ライン ユーティリティ fxc.exe を使用)、実行時に D3DXAssembleShader() を使用します。この方法を使用すると、DirectX 8 ゲームでも HLSL の能力を活用できるようになります。
  • D3DXCompileShader() を使用してシェーダー ソースをトークン ストリームと定数テーブルの形式にコンパイルします。実行時に、トークン ストリームと定数テーブルをロードし、デバイスに対して CreateVertexShader() または CreatePixelShader() を呼び出してシェーダーを作成します。
  • 最も簡単な方法は、エフェクト ファイルを指定して D3DXCreateEffectFromFile() または D3DXCreateEffectFromResource() を呼び出し、D3DX エフェクト システムを利用するというものです。

新しいシェーダー コンパイラ フラグの目的は何ですか。

December 2006 DirectX SDK より、Direct3D 10 向けに開発された新しい HLSL コンパイラを Direct3D 9 ターゲットに使用できるようになりました。新しいコンパイラは ps_1_x ターゲットをサポートせず、すべての Direct3D HLSL シェーダーの既定のコンパイラとなりました。下位互換性確保のために用意されたフラグを使用することで、ps_1_x ターゲットを強制的に ps_2_0 ターゲットとしてコンパイルできます。

アプリケーションで従来のコンパイラを引き続き使用する場合は、実行時にフラグを指定するか (「コンパイラ フラグ」を参照)、fxc を使用するときにスイッチを指定します。

エフェクトからシェーダーを取得する正しい方法を教えてください。

D3DXCreateEffect を使用して ID3DXEffect を作成し、GetPassDesc を使用して D3DXPASS_DESC を取得します。この構造体には、頂点シェーダーとピクセル シェーダーへのポインターが含まれています。

ID3DXEffectCompiler::GetPassDesc は使用しないでください。このメソッドから返される頂点シェーダーとピクセル シェーダーのハンドルは NULL です。

HLSL の noise() 組み込み関数は何に使用するのですか。

noise 組み込み関数は、Ken Perlin 氏によって定義されたパーリン ノイズを生成します。この HLSL 関数は、現時点ではテクスチャー シェーダー内でテクスチャーを塗りつぶすためにのみ使用できます。これは、現在のハードウェアがこのメソッドをネイティブにサポートしていないためです。テクスチャー シェーダーは、便利なヘルパー関数である D3DXFill*Texture() 関数と共に使用されることで、プロシージャで定義されるテクスチャーをロード時に生成します。

ピクセル シェーダー モデル 2.0 と 2.a のどちらを使用するかを判断するにはどうすればよいですか。

D3DXGetPixelShaderProfile() 関数と D3DXGetPixelShaderProfile() 関数を使用すれば、実行中のデバイスに最も適した HLSL プロフィールを特定する文字列が返されます。

プリコンパイルしたエフェクト シェーダーでパラメーターにアクセスするにはどうすればよいですか。

定数テーブルへのアクセスに使用する ID3DXConstantTable インターフェイスを使用します。このテーブルには、上位レベル言語のシェーダーとエフェクトで使用する変数が格納されます。

エフェクトやその他のリソースにユーザー データを追加する方法はありますか。

はい、あります。プライベート データを設定する場合は、SetPrivateData を呼び出します (pReal は D3D テクスチャー オブジェクト、pSpoof はラップされたテクスチャー オブジェクトです)。

hr = pReal->SetPrivateData(IID_Spoof, &pSpoof, 
            sizeof(IDirect3DResource9*), 0)));

ラップされたポインターを検索するには

    IDirect3DResource9* pSpoof;
    DWORD dwSize = sizeof(pSpoof);
    hr = pReal->GetPrivateData(IID_Spoof, (void*) &pSpoof, &dwSize);

サブセットを定義した後に ID3DXMesh オブジェクトのレンダリングが非常に遅くなるのはなぜですか。

面属性を定義した後にメッシュを最適化していないと思われます。属性を指定して ID3DXMesh::DrawSubset() を呼び出した場合、このメソッドは要求された属性を含んでいるすべての面をメッシュで検索しなくてはなりません。さらに、レンダリングされる面はランダムなアクセス パターンになっていることが多く、頂点キャッシュが利用されません。サブセットの面属性を定義したら、ID3DXMesh::Optimize または ID3DXMesh::OptimizeInPlace メソッドを呼び出して、D3DXMESHOPT_ATTRSORT またはそれより強力な最適化方法を指定します。最適なパフォーマンスを得るには、頂点キャッシュを最適に利用できるように頂点を並べ替える D3DXMESHOPT_VERTEXCACHE フラグを指定して最適化を行ってください。D3DX メッシュに対して生成される隣接性配列には、面ごとに 3 つのエントリがありますが、面によっては 3 つのエッジすべてに隣接面がない場合があります。これはどのようにエンコードされているのでしょうか。隣接面がないエントリは、0xffffffff とエンコードされます。

事前計算済み放射輝度伝播 (PRT) についてよく聞くのですが、詳細はどこで学ぶことができますか。

PRT は Summer 2003 SDK Update で追加された D3DX の新機能です。この機能は、グローバル イルミネーション、ソフト シャドウ処理、リアルタイムでのサブサーフェス スキャッタリングなどの複雑なライティング シナリオのレンダリングを可能にします。SDK には、このテクノロジをゲームに取り入れる方法を示すドキュメントとサンプルが収録されています。PRTDemo サンプルLocalDeformablePRT サンプル のサンプルには、それぞれ頂点単位とピクセル単位のライティング シナリオでシミュレーターを使用する方法が示されています。この機能の詳細とその他のトピックについては、Peter Pike Sloan の Web ページも参照してください。

テクスチャーへのレンダリングを行い、アンチ エイリアシングを活用するにはどうすればよいですか。

Direct3DDevice9::CreateRenderTarget を使用して、マルチサンプリングされたレンダー ターゲットを作成します。このレンダー ターゲットにシーンをレンダリングしたら、そこからレンダー ターゲット テクスチャーに対して StretchRect を実行します。オフスクリーン テクスチャーに変更 (ブラーやブルーミングなど) を加えた場合は、present() を実行する前にそのテクスチャーをバック バッファーにコピーして戻します。

DirectSound に関する質問

  • アプリケーションの起動時に雑音が生じるのはなぜですか。この問題は他のアプリケーションでもみられます。
  • エフェクト パラメーターを変更してからその結果が聞こえるまでに遅れが生じるのはなぜですか。
  • DirectSound がインストールされているかどうかを調べるにはどうすればよいですか。
  • WAVEFORMATEXTENSIBLE を使用してマルチチャンネル オーディオを作成するにはどうすればよいですか。
  • DirectSound ボイス マネージャーを EAX のようなプロパティ セットと共に使用するにはどうすればよいですか。
  • カーソル位置の通知を使用するときの動作が不安定で困っています。正確な情報を得るにはどうすればよいですか。
  • GetCurrentPosition() を使用するとパフォーマンスが低下します。パフォーマンスを上げるにはどうすればよいですか。
  • 作成した DirectSound アプリケーションが CPU 時間を使い過ぎたり、処理が遅くなったりします。コードを最適化するためにできることはありますか。
  • バッファーをストリームする際に、不具合が生じて動作に支障が出ることがよくあります。バッファーをストリームするための最善の方法を教えてください。
  • 同じサウンドを非常に短い時間で頻繁に何度も再生すると、正しく再生されなかったり、Play() の呼び出しに時間がかかったりすることがあります。どうすればよいですか。
  • WAV ファイルを WMA にエンコードするにはどうすればよいですか。
  • MP3 ファイルを DirectSound でデコードするにはどうすればよいですか。

アプリケーションの起動時に雑音が生じるのはなぜですか。この問題は他のアプリケーションでもみられます。

DirectX デバッグ ランタイムをインストールしたと思われます。デバッグ バージョンのランタイムは、初期化されていないバッファーのバグを開発者が見つけられるように、バッファーに雑音を格納します。作成後の DirectSound バッファーの内容は保証できません。特に、バッファーがゼロに初期化されると仮定してはなりません。

エフェクト パラメーターを変更してからその結果が聞こえるまでに遅れが生じるのはなぜですか。

DirectX 8 では、エフェクト パラメーターの変更が直ちに有効になるとは限りません。DirectSound は、効率を高めるために、バッファー内の再生カーソルから始まる 100 ミリ秒のサウンド データを処理してからバッファーを再生します。この前処理は、以下の呼び出しの後に行われます。

IDirectSoundBuffer8::SetCurrentPosition
IDirectSoundBuffer8::SetFX
IDirectSoundBuffer8::Stop
IDirectSoundBuffer8::Unlock

DirectX 9 より、エフェクトをジャストインタイムで処理する新しい FX 処理アルゴリズムでこの問題に対処できるようになり、遅延が減少しました。このアルゴリズムは、書き込みカーソルの先でエフェクトを処理する新たなスレッドと共に、IDirectSoundBuffer8::Play() 呼び出しに追加されています。このため、パラメーターはどのタイミングで設定しても期待どおりに作用します。ただし、再生中のバッファーでは、再生カーソルと書き込みカーソルの間のオーディオ (および若干のパディング) が既に処理されているので、パラメーターの変更が実際に耳に聞こえるまでに多少の遅れ (通常は 100 ミリ秒) が生じることに注意してください。

DirectSound がインストールされているかどうかを調べるにはどうすればよいですか。

DirectSoundEnumerate() を使用して使用可能な DirectSound デバイスを列挙する必要がない場合は、アプリケーションに dsound.lib をリンクせず、代わりに COM の CoCreateInstance(CLSID_DirectSound...) 経由でこのライブラリを使用し、Initialize(NULL) で DirectSound オブジェクトを初期化します。DirectSoundEnumerate() を使用する必要がある場合は、LoadLibrary("dsound.dll") で dsound.dll を動的にロードし、GetProcAddress("DirectSoundEnumerateA/W") や GetProcAddress ("DirectSoundCreateA/W") などを使用してそのメソッドにアクセスできます。

WAVEFORMATEXTENSIBLE を使用してマルチチャンネル オーディオを作成するにはどうすればよいですか。

DirectSound のヘルプ ファイルでこの質問の回答を見つけられない場合は、「Multiple Channel Audio Data and WAVE Files (複数チャンネルのオーディオ データと WAVE ファイル)」という記事で詳細情報を参照できます。

DirectSound ボイス マネージャーを EAX のようなプロパティ セットと共に使用するにはどうすればよいですか。

DirectSound 9.0 では、バッファーを複製する際に、AcquireResources メソッドへのアクセスを可能にする IDirectSoundBuffer8 インターフェイスを複製バッファー上で取得できるようになりました。これにより、DSBCAPS_LOCDEFER フラグが設定されたバッファーをハードウェア リソースに関連付けることができます。そのうえで、Play() を呼び出す前にこのバッファーで EAX パラメーターを設定できます。

カーソル位置の通知を使用するときの動作が不安定で困っています。正確な情報を得るにはどうすればよいですか。

DirectSound の複数のバージョン、コアの Windows オーディオ スタック、およびオーディオ ドライバーに、カーソル位置の通知を不安定にするバグが潜んでいます。通知が適切に動作することがわかっているハードウェア/ソフトウェア構成が対象でない限り、カーソル位置の通知は使用しないでください。位置を追跡する場合は、GetCurrentPosition() を使用した方が安全です。

GetCurrentPosition() を使用するとパフォーマンスが低下します。パフォーマンスを上げるにはどうすればよいですか。

各バッファーで GetCurrentPosition() を呼び出すたびにシステム コールが発生しますが、システム コールは DirectSound が占有する CPU 領域の大きな部分を占めるので、最小化する必要があります。NT (Win2K と XP) では、ソフトウェア バッファー (および一部のデバイスのハードウェア バッファー) 内のカーソルが 10 ミリ秒ずつ移動するため、GetCurrentPosition() は 10 ミリ秒間隔で呼び出すのが理想的です。5 ミリ秒間隔よりも頻繁に呼び出すと、パフォーマンスが低下します。

作成した DirectSound アプリケーションが CPU 時間を使い過ぎたり、処理が遅くなったりします。コードを最適化するためにできることはありますか。

オーディオ コードのパフォーマンスを上げるためにできることはいくつかあります。

  • GetCurrentPosition を頻繁に呼び出さないでください。各バッファーで GetCurrentPosition() を呼び出すたびにシステム コールが発生しますが、システム コールは DirectSound が占有する CPU 領域の大きな部分を占めるので、最小化する必要があります。NT (Win2K と XP) では、ソフトウェア バッファー (および一部のデバイスのハードウェア バッファー) 内のカーソルが 10 ミリ秒ずつ移動するため、GetCurrentPosition() は 10 ミリ秒間隔で呼び出すのが理想的です。5 ミリ秒間隔よりも頻繁に呼び出すと、パフォーマンスが低下します。

  • オーディオには、独立した低めのフレーム レートを使用してください。最近では多くの Windows ゲームが 100 フレーム/秒を超える可能性がありますが、ほとんどの場合 3D オーディオ パラメーターを同じフレーム レートで更新する必要はありません。オーディオを 2、3 のグラフィック フレームに 1 回の割合、つまり 30 ミリ秒程度の間隔で処理すると、オーディオの品質を落とすことなくアプリケーションでオーディオを呼び出す回数を大幅に減らすことができます。

  • 3D オブジェクトには DS3D_DEFERRED を使用してください。ほとんどのサウンド カードは、特にリスナーの位置や方向を変更する場合に、パラメーターの変更に即時に対応し、1 つのフレームで大部分を変更できます。このときに、サウンドカードと CPU で不要な計算が多数実行されるため、一部のパラメーターの変更を遅らせてフレームの最後にコミットすることも、手早く全体的に最適化するための 1 つの方法です。

    あるいは、最低でもバッファーで個別に Set3DParamX を呼び出す代わりに SetAllParameters を使用します。

    同様に 3D バッファーでは、少なくとも Set3DParamX を個別に呼び出すのではなく SetAllParamenters を使用します。システム コールは可能な限り最小化するようにしてください。

  • 冗長な呼び出しを行わないでください。再生呼び出しのリストを保存してソートするようにします。1 つのオーディオ更新フレームで、新しいサウンドの再生が 2 回要求されることがよくあります。この要求が到着して処理される場合、最初の新しいサウンドが開始され、直ちに 2 番目に要求されたサウンドで置き換えられます。その結果、冗長な計算、不要な再生呼び出し、不要な停止呼び出しが行われます。新しいサウンドを再生する要求のリストを保存することをお勧めします。こうすると、リストをソートして、再生を開始する必要がある音声のみを実際に再生できるようになります。

    また、各サウンド ソースの 3D パラメーターと EAX パラメーターのローカル コピーを保存するようにしてください。パラメーターを特定の値に設定する要求が行われた場合、その値が最後に設定された値と本当に異なっているかを確認できます。異なっていなければ呼び出しを行う必要はありません。

    このシナリオはおそらくサウンド カード ドライバーで検出され、(同じ) 計算が再度実行されることはまずありませんが、オーディオ呼び出しは (リング トランジション経由で) オーディオ ドライバーに到達する必要があり、この操作だけでも時間がかかります。

バッファーをストリームする際に、不具合が生じて動作に支障が出ることがよくあります。バッファーをストリームするための最善の方法を教えてください。

オーディオをバッファーにストリームするときの基本的なアルゴリズムが 2 つあります。After-Write-Cursor (AWC) と Before-Play-Cursor (BPC) です。 AWC は遅延を最小化する代わりに不具合を引き起こすおそれがありますが、BPC はその逆です。通常、ストリームされるサウンドはインタラクティブに変更されないため、ゲームやこれに類するアプリケーションにとってこのような遅延はほとんど問題となりません。したがって、BPC の方がアルゴリズムとして適しています。AWC では、ストリーミング スレッドを実行するたびに、ループするバッファー内でその書き込みカーソルより N ミリ秒先までデータを "補給" します (通常は Windows のスケジューリングのぶれを考慮して N が 40 程度に設定されます)。BPC では、バッファーに常にできる限り多くのデータを書き込んで、再生カーソルまで (あるいは、ドライバーが再生カーソルの進行状況を間違って報告する場合を考慮してそれより 32 バイト手前まで) バッファーを埋めます。

テスト用ハードウェアでゲームが問題なく動作しても、外部のコンピューターでは不具合が出ることがあるので、BPC を使用して不具合の発生を最小限に抑え、100 ミリ秒以上のバッファーを使用するようにしてください。

同じサウンドを非常に短い時間で頻繁に何度も再生すると、正しく再生されなかったり、Play() の呼び出しに時間がかかったりすることがあります。どうすればよいですか。

一部のハードウェアで、起動時の遅延 (前述のストリーミング時の遅延とは異なります) が問題となることがあります (一部のサウンド カードで Play() の呼び出しに時間がかかることがあります)。瞬間的なサウンド (銃声や足音など) でこの遅延を低減する場合の秘訣は、一部のバッファーを常にループ状態にして無音を再生しておくことです。瞬間的なサウンドを再生する必要があるときは、空いているバッファーを見つけ、その書き込みカーソルの場所を確認し、バッファー内の書き込みカーソルの直後にサウンドを挿入します。一部のサウンドカードで、サポート対象であるはずの遅延プロパティに対する QuerySupport が失敗します。対処法はありますか。QuerySupport は非遅延プロパティに対して実行し、遅延設定を使用することができます。最新のサウンドカード ドライバーをインストールすることでこの問題が解決する場合もあります。

WAV ファイルを WMA にエンコードするにはどうすればよいですか。

Windows Media エンコーダー 9 シリーズで Windows Media エンコーダーに関するドキュメントを参照してください。

MP3 ファイルを DirectSound でデコードするにはどうすればよいですか。

DirectSound では MP3 のデコードがネイティブにサポートされていません。事前に手動でデコードするか (DirectShow フィルターの ACM コーデックを使用)、または DirectShow 自体を使用して自動的にデコードし、結果の PCM オーディオ データを DirectSound のバッファーにコピーします。

DirectX Extensions for Alias Maya

  • NURBS が表示されないのはなぜですか。
  • SUBD が表示されないのはなぜですか。
  • X ファイルでのアニメーションの表示がプレビュー ウィンドウのアニメーションと異なるのはなぜですか。
  • リジッド スキンでメッシュをスキニングしましたが、メッシュが (またはその一部) が動きません。なぜなら、
  • X ファイル内に IK が見あたりません。どこに行ったのでしょうか。
  • DirectXShader 以外のマテリアルの色が一切表示されないのはなぜでしょうか。

NURBS が表示されないのはなぜですか。

NURBS はサポートされていません。ポリゴン メッシュに変換してください。

SUBD が表示されないのはなぜですか。

SUBD はサポートされていません。ポリゴン メッシュに変換してください。

X ファイルでのアニメーションの表示がプレビュー ウィンドウのアニメーションと異なるのはなぜですか。

プレビュー ウィンドウでは、厳密にはアニメーション表示が行われていません。アニメーションを再生しているのではなく、Maya のシーンの最新の状態に同期しています。アニメーションがエクスポートされるときに、各トランスフォームでの行列が、スケーリング、回転 (クオータニオン)、平行移動の 3 つの要素 (SRT と呼ばれます) に分解されます。SRT は、適切に補間を行い、データをよりコンパクト化して提供し、個別に圧縮できることから、行列よりも望ましい形式です。すべての行列を SRT に分解できるわけではありません。行列を分解できなかった場合、結果の SRT は不明となり、アニメーションで小さなエラーが検出される可能性があります。分解時に問題を引き起こすことが多い Maya の 2 つの機能が、せん断と、編心回転またはスケーリングです。偏心回転またはスケーリングを使用しているためにこの問題が発生した場合は、トランスフォームを追加して階層のレベルを増やすことを検討してください。

SRT をサポートする D3DX アニメーションでは、SRT が次のようになります。

[S]x[R]x[T]

Maya の行列ははるかに複雑で、かなりの量の追加処理を必要とします。次に例を示します。

[SpInv]x[S]x[Sh]x[Sp]x[St]x[RpInv]x[Ro]x[R]x[Rp]x[Rt]x[T]

リジッド スキンでメッシュをスキニングしましたが、メッシュが (またはその一部) が動きません。なぜなら、

Maya のリジッド スキンは現時点ではサポートされていません。スムース スキンを使用してください。

X ファイル内に IK が見あたりません。どこに行ったのでしょうか。

X ファイルは IK をサポートしていません。IK ソリューションはフレームに変換されて X ファイルに格納されます。

DirectXShader 以外のマテリアルの色が一切表示されないのはなぜでしょうか。

DirectX Extensions for Maya では、現在 DirectXShader マテリアルのプレビューとエクスポートのみがサポートされています。将来のバージョンでは、他のマテリアルもサポートされる予定です。

XInput に関する質問

  • DirectInput を使用してトリガーを読み取ることはできますか。
  • XInput でサポートされるコントローラーの数はいくつですか。
  • XInput は共通コントローラー以外をサポートしていますか。
  • 共通コントローラーは DirectInput から使用できますか。
  • 共通コントローラーでフォース フィードバックを実現するにはどうすればよいですか。
  • 既定のオーディオ デバイスが変更されるのはなぜですか。
  • コントローラー上のライトを制御するにはどうすればよいですか。
  • アプリケーションで Xbox 360 ボタンにアクセスするにはどうすればよいですか。
  • ドライバーはどこで入手できますか。
  • コントローラー ID はどのように決まるのですか。
  • コントローラー用のオーディオ デバイスを取得するにはどうすればよいですか。
  • コントローラーのプラグが抜けた場合はどうすればよいですか。

DirectInput を使用してトリガーを読み取ることはできますか。

できますが、トリガーは同じ軸となります。そのため、DirectInput でトリガーを個別に読み取ることはできません。XInput を使用すると、トリガーから別々の値が返されます。

DirectInput がトリガーを 1 つの軸として解釈する理由については、「DirectInput での Xbox 360 コントローラーの使用」を参照してください。

XInput でサポートされるコントローラーの数はいくつですか。

XInput では一度に 4 つのコントローラーの接続がサポートされます。

XInput は共通コントローラー以外をサポートしていますか。

いいえ。サポートしていません。

共通コントローラーは DirectInput から使用できますか。

はい。共通コントローラーには DirectInput からアクセスできます。

共通コントローラーでフォース フィードバックを実現するにはどうすればよいですか。

XInputSetState 関数を使用します。

既定のオーディオ デバイスが変更されるのはなぜですか。

ヘッドセットを接続すると、コントローラーのヘッドセットは標準の USB オーディオ デバイスとなります。このため、接続した時点で、Windows が自動的にこの USB オーディオ デバイスを既定で使用するように変更します。すべてのオーディオがヘッドセットから聞こえてくることをユーザーが望まないことも考えられるので、手動で元の設定に戻す必要があります。

コントローラー上のライトを制御するにはどうすればよいですか。

コントローラー上のライトはオペレーティング システムであらかじめ設定されており、変更できません。

アプリケーションで Xbox 360 ボタンにアクセスするにはどうすればよいですか。

残念ですが、このボタンは将来の使用のために確保されています。

ドライバーはどこで入手できますか。

ドライバーは Windows Update または windowsgaming.com から入手できます。

コントローラー ID はどのように決まるのですか。

XInput 起動時に、XInput エンジンおよび接続されているコントローラーによって非決定的に ID が決定されます。XInput アプリケーションの実行中にコントローラーが接続された場合は、空いている最も低い番号が新しいコントローラーに割り当てられます。コントローラーの接続が解除されると、その番号が再び空き番号となります。

コントローラー用のオーディオ デバイスを取得するにはどうすればよいですか。

XInputGetDSoundAudioDeviceGuids 関数を使用します。詳細については、AudioController のサンプルを参照してください。

コントローラーのプラグが抜けた場合はどうすればよいですか。

プレイヤーがコントローラーを使用していた場合は、コントローラーが再び接続され、一時停止を解除できる状態になったことを知らせるボタンをプレイヤーが押すまで、ゲームを一時停止してください。