プログラミング一覧

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化してしまうかも。


C++/CLIでの実行時エラー

C++/CLIとC++ネイティブのlibをリンクさせて、Windowsフォームアプリケーションを作ったときに、
よくわからないエラーが発生してしまうことがある。

どうやらCRT初期化の順序に問題があるのか。
これを解決するには、エントリポイントの修正を行えば解決する模様。
次のエントリポイントに設定させてあげれば問題解決できた。

ずいぶんと前にわかっていて、日記に書いたと思ったのに忘れていたので、
今更ながら追加。

上記の発生条件

どうやらグローバルなコンストラクタが実行されるときに何かがあるらしい。
C++のclassメンバにstaticなデータがある場合に発生する。
また、それが組み込み型(プリミティブ型)ならば問題なく動くが、
自分で作成したクラス型だと実行時エラーの引き金となる。

追記1

コンストラクタやデストラクタを備えるクラスだとアウトっぽい。
そのクラスがプリミティブ型しか保持していないとしても。

追記2

どうやらコンストラクタがあることが問題ではないらしい。
デストラクタがあることが問題のようだ.
デストラクタのあるクラス型で、クラスstaticメンバを持つと、このエラーが発生する。

こういったクラス構造をどこかで持ってしまうと、C++/CLIで実行時エラーとなる.