プログラミング一覧

ConvertToIndexedBlendedMesh相当品

自力で ID3DXSkinInfo::ConvertToIndexedBlendedMesh相当品を作ってみてます。…が、結構難しい…。

設定したマトリックスパレット数で、モデル全体を描画できるように
ボーンコンビネーションテーブル相当品準備するところまでは出来たのだが、
まだまだバグが入ってる。
とりわけ、複数のサブセット描画で共有される境界の頂点がおかしい。

D3DXの機能では頂点キャッシュへの乗り具合や、
ボーン影響度の設定とかも出来てかなり高機能です。
これと同様の機能を自力実装はかなり骨が折れそうです。そこまではきっとやらないです。

また、現状のものでもデバッグ実行状態でtiny.xの変換で20秒くらいかかってしまうので、
全くダメダメですね。


VS2010のSTL

体感的にですが、VisualStudio2008と2010とを比較して、
STL(std::vector)が重くなった気配があります。

完全に同じコードではないので感覚的なものなのですが。

ただデバッグ用においてのみで、リリースビルド時には高速に動くため
巨大なデータにおいてはリリースで実行しようということになりそうです。

でも、10000程度の要素での出し入れが重いってのもなぁ…
(reserveを適切に使っているため、要素移動は起こらないはずなのに。)

そのうち同一コードでDebug/Release比較をやってみるとします。


VisualStudio2010でのWinSxS

VisualStudio2010では、またサイドバイサイド(Side by Side:SxS)の状況が変わっていた。どうやら、WinSxSを使っていないようです!
C:WindowsWinSxs の中を見ても vc100用のランタイムは入っていませんでしたし、
VS2010インストールフォルダ内のdll群をチェックしてみても、
埋め込みマニフェストすら入っていませんでした。

さらには、2010で作成されるexeの中の埋め込みマニフェストをみてみても
ランタイムのバージョンに関するものは記載がありませんでした。

ちなみに、VS2005/2008では、世間で有名になっているとおり
サイドバイサイドが使用されており、ランタイムの単純コピーでは動作しないようになっていました(一般的には)。
ユーザーはマイクロソフトより再配布ランタイムのパッケージをダウンロードして、インストールする必要がありました。

今回の2010での変更は、従来のdll単純コピーで済ますことが出来るという点では手軽になったと思います。
しかし、懸念されるのは一昔前のDLL-HELLです。また同じ状況が起こる可能性があります。

所感

WinSxSがそうとう厄介問題だったのは知っていましたが、
新バージョンで取りやめるほどとは思いませんでした。

以前のランタイムもマイナーバージョン間では単なるリダイレクトになっていたし、
全て新バージョンのランタイムで置き換えてきた現実からこのような方法に変更になったのかもしれません。
「今までも全て新しいものに置き換えてきた。今後も大丈夫だろう。
VCではWinSxSを廃止して、dll直配置を認めた方がサポートも楽になる。」
というような思惑だったりするのかも、と思ってます。

昔のようなバージョン依存は現在となっては低そうということでしょうか。


インデックスバッファ

DirectX9では16bitインデックスバッファが主流だったように思います。しかし、DirectX10以降はインデックスバッファも32bitインデックスとなってしまったようです。
生成時に16bitであると設定するものが見あたらない…。

DirectX9から10以降まで1つのAPIセットで対応するライブラリ作ってますが、
このような違いってどうしたものやら。

  1. フォーマット指定を追加。使えない環境(DX10世代)ならエラーにする
  2. あくまでフォーマット指定はヒント。
    1. 書き込み時とかには生成された結果フラグをみてUSHORT, UINTでインデックスを書き込み

どちらの方法にしてもキレイにならない気がします…。

  • 過去日記に同じようにこの情報を書いていました。10環境では16bitインデックスがなくなった、と。

VS2010対応 – ゲームプログラマになる前に~のやつ –

「ゲームプログラマになる前に覚えておきたい技術」に付属しているソース類で、
VisualC++2010用に変換したプロジェクトおよびソースコードを用意してみました。手元の環境でデバッグ/リリース構成のビルドを確認しています。2011/02 新バージョンを公開しました。
こちらからどうぞ

プロジェクト変換について

  • ライブラリの全体最適化を無効化してあります。
  • ワーニングレベルを3に落としたものがいくつかあります。
  • 算術関連(sin,cos,tan,など)を名前空間付きに変更しました。

サンプルコードによっては、全体最適化適用による不具合のため、
exe用のプロジェクトでも無効化してあるものがあります。

なお、変換に用いたのはVisulStudio2010Professionalです。
ですが、expressエディションでも開くことは可能かと思われます。

注意事項

公開しているアーカイブの再配布を禁止します。
また、公開したアーカイブを使用したことによる損害については、
筆者および公開した私自身がその責務を負わないこととします。
利用する際には、自己責任でご利用下さい。

ダウンロード、および、使用方法

CDROM内にある、VisualStudio2008用のソースコードを展開した後、
srcフォルダでダウンロードしたファイルを上書きで展開してください。

2011/02 新バージョンを公開しました。
こちらからどうぞ

注意事項に同意のうえ、ダウンロードする

このファイル中にソースコードが一部含まれますが、
これについては著者の許可をもらって公開しております。

動作確認環境

  • Windows7 Ultimate x64環境
  • VisualStudio2010Professional
  • PentiumDualCore E6500
  • Geforce9800GT

この環境で、含まれるサンプルソースコードの実行等を確認しております。
少なくともこのプロジェクト類を用いて 64bit環境での動作を確認できております。


ミップマップについて

どうやらミップマップが使われるためには、
射影行列(透視変換行列)適用してからじゃないとダメな模様。行列適用しないで、通常の射影空間(0-1)に収まるように頂点を準備して、
テクスチャ貼り付けてみたけど、これではミップマップがポリゴンの面積に応じて使われることがなかった。

しかしその準備した頂点で作られるポリゴンの面積によっては、
ミップマップが使われたりしたが、頂点単位?でしか判定していないのか?

一方、透視変換行列適用してみると、
ピクセルごとにどのミップマップレベルを使用するかが判定されており、
画面に描画してみるとその使用状況がわかった。

根本的に何が原因だったのかはわからんなぁ…。


アルファブレンディングについて【教えてほしい】

アルファブレンドで下記の合成はわかった

  • 通常合成(1*srcColor + 0*destColor)
  • 加算合成(1*srcColor + 1*destColor)
  • 半加算合成(srcA * srcColor + 1*destColor)
  • 半透明合成(srcA * srcColor + (1-srcA) * destColor)

しかしこれらがアルファ値だけ別の計算が出来るという仕組みが用意されていたりする。
これの有効な利用が思いつかない。

OpenGLやDirectXではアルファブレンドセパレートとして機能があったりするが。

D3DRS_SEPARATEALPHABLENDENABLE を有効化して
なにかやっているサンプルもまた見つからなかったし。
有効に使えている例、使える例を知っている人は是非教えてください。


テクスチャアドレッシングモード

テクスチャアドレッシングモード

テクスチャを張ったときに、1.0以上の値をどう扱って、
テクスチャを張るかのモード設定です。

出来ることの代表的なものとして、

  • 繰り返し貼る(リピート)
  • 反転しながら貼る(ミラー)
  • 繰り返さずに残った部分は引き延ばし

というのがあります。

OpenGL vs DirectX

で今回感じたのが、OpenGLとDirectXでこれらの機能の差違。
同じ挙動をする設定でも、画面の描画結果が違うということになりました。
もっとも大まかな挙動という点では一緒で、
今回の違いというのは、描画ピクセルが完全一致しないということを示しています。

どうも境界あたりの処理でそれぞれ差違が出ていました。
GL_CLAMP_TO_EDGEやGL_CLAMP_TO_BORDERなど標準機能ではなく
拡張機能で試したのですがうまくいきませんでした。

どうでもいいこと

テクスチャラッピングモードというとまた別のことを指すようです。
少しわかりにくい気がするのは自分だけでしょうか…


OpenGLのメモ

テクスチャのアドレッシングモードで、
境界色へのクランプってソフトウェア処理と思っていたが、
ちょっと前からそれは違っていたらしい。発覚したのは GL_CLAMP_TO_BORDER について調べてみたからで、
ある海外サイトによると、GeForce2のころはソフトウェア処理となっていたようだ。

あと、GL_CLAMP_TO_BORDERが3.0仕様では deprecatedになっている!という
記述を見かけたけど、OpenGL 3.1の仕様書を見てみたところ、
普通に記載があった。海外サイトのコメントをみていたら廃止というのがミスだったようで…

廃止になったのは、GL_CLAMP のようです。


DirectXのデバッグランタイム不具合

Windows7 (x64)の環境で、DirectX9を用いた開発を行おうとすると、
SDKのバージョンによっては問題を引き起こすことがわかった。検索しても海外でしか、同じ症状が発見されず、また解決法も不明だったので、
問題のあるバージョンを使用しない方法でしか解決が出来ないようだ。
それでも、別バージョンを使えばOKという点はまだ救いなのかもしれない。

問題

Windows7(x64)において、DirectX9のデバッグランタイムを有効にすると、
CreateDeviceで失敗する。
そのときのエラーメッセージは次の通り。

コメントもらったので修正
試したのは全て、Windows7(x64)環境下です。
x86環境では問題が起こらないのかもしれません。
どうやらx86,x64環境ともに発生するようです。

SDKバージョン 使用可否 Windows仕様
2008Nov 使用不可能 Win7(x64)
2009Mar 使用不可能 Win7(x64)
2009Aug 使用可能 Win7(x64)
2010Feb 使用可能 Win7(x64)

 

まとめ

このような結果になったので、Windows7環境でまともに使おうと思っても、
古すぎるSDKは使いにくい。2009Augがいいところだろうか。