「 プログラミング 」一覧

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


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

テクスチャを張ったときに、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がいいところだろうか。


R2VB


どうやら最近のNVIDIAドライバ+新しめのボードだと、
R2VB(Render To VB)は使えないようだ。チェックしてみてもNGとなってしまう。
これってGeForce6200とかで使えたという噂を聞いたけど、
そのくらい昔のハードでしか使えないってことなんだろうか。

※ R2VB使うくらいなら DirectX10以降のストリームアウト使えってことか

DirectX9で、ストリームアウトはあきらめろということで結論かも。
OpenGLならエクステンション駆使して何とかできるのかもしれない。


今日のトラブル


原因不明。IDIRECT3DDEVICE9のSetVertexShaderConstantF関数で設定した値が、シェーダーに送られてない。
一方で、D3DXのID3DXCONSTANTTABLEで設定すると値はきちんと送られている。

なぜだー。

これのせいで数時間もアルゴリズムの方が間違っているのかと悩んでた。

現在ダウンサンプリングを勉強中


RedmineでSVNリポジトリとの同期


先日、cronを利用してRedmineの活動カテゴリで
ソースコードのコミット履歴もある程度のタイミングで反映されるようにしてましたが、
Subversionなら別の方法も採れるのでは?と試してみました。Subversionのサーバー側でのフックスクリプトを使用します。
post-commitスクリプトで、

/usr/bin/ruby /redmine/script/runner “Repository.fetch_changesets” -e
production

これでコミット直後でRedmine側が更新されるので、
なかなかいいんじゃないでしょうか。


WinSxS問題 その2


基本的事項

まずは知っておかなくてはいけないこと。

外部マニフェストの挙動

  • 外部マニフェストはexeのみに適用される。
    • そのexeが必要とするdllらには適用されない点に注意
  • WindowsXP環境では、外部マニフェストのほうが埋め込みマニフェストよりも優先される
    • 2003より優先順序が逆転した。

症状

再頒布ランタイムパッケージがインストールできない環境で発生した。
インストールできない環境とは、ユーザーがゲスト権限くらいしかない場合を指す。
あるいはどうしても事情により入れられないとか。

このときに、exeとdllと同フォルダにおいて、
そのプライベートアセンブリとして、VCランタイムを配置した。
このときに、最近のWindowsUpdateが適用されたバージョンを置いた。
(VC90.30729.4148バージョン)

そして、exeがこのバージョンのランタイムを使うように、外部マニフェストファイルを作成して
実行をさせようとした。

この結果が、昨日のエラーを引き起こしていた。
理由は、dllにはこのマニフェストの影響が及ばないからである。
故にdllは埋め込みマニフェストに従い、21022.8のランタイムを要求しているし、
exeは外部マニフェストによって強制された 320729.4148バージョンを要求する。

ここで同一のアセンブリ名であるためにdllがロードされてチェック機構が働いた段階で、
不整合がおこり、ローダーの段階で失敗してしまう。
その結果、exeが実行されることなく強制終了されてしまう。
試した環境ではエラーダイアログすら出ない。

解決策

簡単に解決する方法がある。
ひとつは、VisualStudio2008,およびSP1環境のデフォルト動作では、
RTM版のランタイムにバインドされる。
これは、9.0.21022.8 のバージョンである。
これに対応するランタイムを入手し、それをプライベートアセンブリとして使用する。

ただし、セキュリティ関係で問題になりそうな気もするが仕方ない.

もう一つは、最初から埋め込みマニフェストで最新バージョンを使うように
全部アプリケーションをリビルドする。
これには、まずプロジェクト設定の、プリプロセッサ定義で、
_BIND_TO_CURRENT_VCLIBS_VERSION を定義しておく。

これを行うとビルドした環境の最新のバージョンへバインドされる。
よって、最近のやつであれば 30729.4148にバインドされる。
リビルドにより dllからexeまでがこれに依存するようになるため、
VisualStudioのインストールディレクトリから再配布ランタイムをコピーして使用すればよい。

最後の方法は、exeでやったように、dllに対しても依存するアセンブリ情報を強制変更する方法である。
これには、hogehoge.dll.2.config というファイルを作成する。
ポイントは”2″という部分。

このファイルにより、目的のバージョンへバインドがリダイレクトするように設定すれば、
dllとexeのバージョン要求不一致を解決できる。
この方法は一応海外のMS CONNECTで記述があったためおそらく正式な方法だと思う。

しかし、日本語での情報が見つからなかったためここに書いてみた。


WinSxS問題


Windowsのサイドバイサイドって、
強力な仕組みなんだけど、その強力さ故色々と面倒なこと引き起こしてるなぁと思います。

昔DLL HELLとか散々な目にあったからこそ作られた仕組みであると理解しているけれど、
今食らっている状況はWinSxS HELLともいえるような気がします。

マニフェストファイルを作成して、実行体と同じ場所にDLLを
プライベートアセンブリとして配置する方法でトラブル。

dllが要求するものと、exeが要求するものと同一アセンブリ名、異なるバージョンアセンブリ
という状況が出たときに問題は起こる…。

通常サイドバイサイドのポリシー設定により、適切にリダイレクトがかかるために
上記の問題は起こらない。なぜならば同一の参照先を示すことになるから

現在回避策を調査中・・・。


Redmineによるリポジトリ管理機構について


どうやら、設定で自動更新としても、
メニュー項目から、リポジトリを覗いたときに初めて情報を取得するようだ。

だから、毎回”活動”のページを開くだけでは、
ソースコードの状況を確認することが出来なかった!

そこで次のようにして、この問題をとりあえずは解決することにした。

  1. 自動更新のチェックを外す
  2. redmineユーザーのcronにスクリプト実行を設定

エンコーディング

他にもソースコードのエンコーディングが怪しかったので、設定を見直してみた。

「管理」/「設定」/「リポジトリ」/「リポジトリのエンコーディング」
とたどって、次のように設定。

utf-8,shift_jis,euc-jp


SkinnedMeshで複数描画したい


DirectXのサンプルSkinnedMeshをいじって、
リソースは1つ、描画用インスタンスは複数なんてものを作成してみました。 

色々と、DirectXの仕様で躓く点が多かったように思います。

実現の為のポイント

  • AnimationControllerは単純にCloneで作成しても、ボーン構造(FRAME)は共有されてしまう
    • 独立させたいのは、マトリックスパレット.
    • 一緒にボーンオフセット行列もインスタンスごとに保持させてしまうと、楽にはなる。
  • マトリックスパレットは、MeshContainerが保持するのではなく、一段外に追いやってみる。
    • 自分では FRAMEの中に追い出しました。MeshContainerと並列して存在する感じに。

このような点から、
描画用のオブジェクト生成時には、

  • FRAME構造をコピー(別インスタンス作成)
  • AnimationControllerをcloneする
  • 上記でそれぞれ描画用のインスタンス用としてのデータができたので、関連づける.
    • D3DXFrameRegisterNamedMatrices()を使用する

これで画像のようにインスタンスごとにアニメーションデータを持った感じで
描画ができるようになりました。

面倒といえば面倒なので、要望があったらlib化してしまうかも。