動かないコード


最近は動かないコードばかり書いてます。コンパイルを通してニヤリ、として終了です。
コンパイル時にすでに判定や計算が終わっている、とか、プリプロセッサ終了時に状態確定とか、そんなことばっかりやってました。

ふと、覗いてみるとどうやらBoostのPreprocessorが分野的に近い。そして、templateで色々とごちゃごちゃやったことは、メタプログラミング、という分野にいるっぽいことがわかりました。

こうやってできたコード、少なくとも人に読ませられるコードじゃないなぁと実感してます。数ヶ月後の自分でも怪しい・・・。

 


昨日の答え。


意外にも日を変えて再度悩んでみると思いつくものである。
とりあえず下記コードでやりたいことはできた。
しかし、T,Sなど1文字の型引数にしておくと、次みたときに相当わからないなぁ…

しかしこのコード、少なくとも今年一番イケてると自負してます

 


(no title)


メンバ変数で配列で…

メンバ変数のポインタを利用して、型情報取得できないか色々と思案中。メンバ変数のポインタ型をテンプレートの型として受け取るまではいけるものの、その型からさらに固定配列だった場合には長さを知りたい。

うーん、できるんだろうか…。

[code lang=”cpp”]
class A {
int a[100];
int b;
};
[/code]

このようなクラスがあって、 &A::a, &A::b という状態からその型と配列情報がテンプレートで展開できれば、目的のことが達成できるのに…。しばし悩んでみます。

 


OS再インストール中


いろいろとやることがあって大変な時期に、OSから再インストール中・・・。
もちろん、Vista x64版で。しかしながら色々とトラブルに見舞われ。

トラブルの点を列挙すると

  • MSDNのOSアクティベーションが上限超えた…。
  • DaemonToolsがインストールでこける

前者はもうしょうがないので、放置。そして、DaemonToolsの件はどうやらウィルスバスター2008のせい。
リアルタイムの検索を切ってみたら、それだけでインストールは成功しました。きっとほかの誰かも同じようにできなくなっているのじゃないかと思います。

MSDNのアクティベーションが上限超えたのはどうしようか。次の更新時期で更新せず、新規で契約しちゃおうかと考え中です。


XBOX360のゲームパッド


入力管理モジュール

Vista x64環境であっても XBOX360のゲームパッド非公式ドライバが存在していたので早速導入。 しかし、x64なので非公式ドライバは署名がない…。そのため起動時には、F8を押して、「ドライバ署名の強制を無効にする」を選択しなくてはならない。とりあえずそれで動作をチェックしてみたところ、やはりちゃんと動きました。

Vistaでの公式ドライバ名

XBOX 360 For Windows(Controller)

Vistaでの非公式ドライバ名

Microsoft Xbox360 Controller

だそうです。これの違いを見て自前で処理を振り分けとかしないとダメかも知れませんね。

 


smbclient


WindowsPCのほうにデータをコピー(バックアップ)したくて、久々にLinuxからWindowsの共有をマウントする、ということをしてみました。

そこで驚いたのが、いつの間にかコマンドやオプションが無くなっていること。
mount -t smbfsではそんなタイプ知らないといわれるし、 smbmountコマンドやろうとしたらそれも無いと言われる。

一方、smbclientは入っていたりするので謎でした。
結果は最近のものは、mount -t cifsとしてマウントさせるとのこと。
さらにこの状態では日本語フォルダをコピーしたり出来ないので、適切にオプションを設定してやることが必要

 

これで何とか出来るようになりました。ちなみにWindowsはVista, LinuxはEUCで保存するようにしているのでこんな感じに。


スプライン実装してた


週末はずっと3次スプライン関数を実装してました。
とりあえず非周期版と周期版の2種類を用意。参考文献は、C言語によるアルゴリズム事典より。
実際に使う場面はまだ先になりそうだけど、出てきた値をグラフ化してみるといい感じの曲線を描いてくれてちょっと幸せ。

HDDレコーダ応答不能

番組表表示させようとしたらリモコンが聞かなくなった。
そして、電源オフだけは効いたのですが、PLEASE WAIT …. の状態のままずっと・・・。また何か毒電波出したのだろうか。

 


スキニング問題


前からやっていたスキニング、前回までの結果ではうまくできないことが判明し、もがいてます。

出来ないのは下記の理由により。

  •  SkinedMeshサンプルではマトリックスパレットに設定している値そのものがワールドになっている。
  •  結果、ライト位置をモデル空間に変換しただけではNG (全てをワールドでやればOKでしょうが…)

というわけで、スキンメッシュの表示方法そのものを変更しようかと。
点光源にチャレンジしていなかったら、上記の問題点に気付かずに放置していただろうなーと思うと運が良かったのかな。

 


描画システムのMultiThread対応


スキニングメッシュもかろうじて表示できたので、諸々の部分をダブルバッファリングにして、描画とメインの実行ループの分離を行ってみました。文章にするとこれだけのことなのに苦戦しましたよ…。

  • DirectXのリソース作成・破棄はメインスレッドでやらなくてはいけない
  • アプリケーションの実行はサブスレッドになる。
  • DirectXは、WndProcが実行されるスレッドで初期化されなくてはならない。また基本的にこのスレッドで実行されるべきである。
  • 当然、描画要求を出してタイミングがきたら描画。このためバッファリング必要

色々と書き換えてようやく、ポイントライトなシェーダーを実行させるところまでは出来ました。しかしスキキングメッシュ関連で、マルチスレッド化に伴いフォルスシェアリングが起こりそうだったので、またスキニングメッシュは表示できない状態へ戻りました…


DirectXのロックの謎


DirectX9のLockについて、調べてみたことをメモしておきます。

Textureのロックには、範囲指定があるが、Lockは複数回できるのか?

まずは推測から。
範囲指定がわざわざあるということは、部分1でLockし、部分2でLockしても問題なさそうである。また、領域が重なった場合は多重ロックになりNGとなる。と予想。

結果は・・・領域が被っていようが、別部分であろうがNGでした。どうやら、範囲指定はパフォーマンスをあげるためのダーティー判断くらいでしかなさそう。ただし、異なるミップマップについては同時Lockは可能のようです。

 

VertexBufferのロックはどうだろうか?

テクスチャが上記のような結果になったのだから、やはり多重ロックは失敗するだろうと予想。あるいはNO_OVERWRITEフラグなんかあるし、領域さえ違えば成功するのかも知れない。

結果は・・・領域が被っていようが、別であろうが、多重ロックは成功する。多重ロック後は、正しくUnlock呼ばないといけないそうです。

このロックの挙動の違いは問題になりそう…。そもそも多重ロックを許可しない方針でプログラムを作っていくべきかも知れません。

上記を試したのは、DirectX9.0cで、GeForce7600GT on Vista(x64)です。他のメーカーのカードでは異なる結果となるかも知れません。 次は、OpenGLのMapBufferとか調べてみる?!