2017年12月12日火曜日

新しい試験環境に環境を構築しているのでメモ

基本環境

  • Arch Linux(x86_64)

インストール時に指定したパッケージグループ

  • base
  • base-devel

環境インストール後にインストールしたパッケージ

  • xorg
  • libjpeg
  • cairo

最初から入っていたけどよそでは入ってないかも知れないパッケージ

  • gdbm

2017年11月2日木曜日

スクリーンキャスト機能を復活

時間が空いたが動画を取得したので貼ってみる。動かしてるのはwOCE用のサンプルアプリで画像ビューア。無難なの...と選んだ結果「オフィスに貼ってあるアレ」的なフォルダの中身を表示させてみた。

また動画の終わりのあたりでマウスカーソルを動かして奥行きをデモしたりしてる。

2017年10月10日火曜日

スレッドでテクスチャをアップデートするのはダメポ(3)

なんて思ってたんだが実はテクスチャの更新が遅いのは更新回数が原因だった。

どうやらテクスチャの更新は思ってた以上に回数依存ぽくて、一度に更新するサイズを拡大したらメインスレッドでの更新でPBOも使ってないにもかかわらず一発で十分なほど改善された。

これだとスレッド化してPBOで更新するようにすれば大きめのテクスチャをまるごとでも更新できそうなんだけど、それをすると通信路が詰まりそうなので今の方法で問題が出るまで放置することにする。てかおそらく今でもリモートで動かすと詰まりそうだし。

2017年10月8日日曜日

スクリーンキャスト機能を復活

「キャスト」というのは違うかも知れん。画面を動画でキャプチャする機能を復活した。

今回はPBOを大量に用意してフルフレームで「ぬるんぬるん」キャプチャできる上に通常動作への影響が感じられないくらいの低負荷にできた。

最初はPBOではなくテクスチャに格納するようにしていたのだが、テクスチャからメインメモリに読めるはずのglGetTextureが全く機能せず画像が真っ黒になってしまうのでPBOを使ってみたのだが、画像の取り出しも高速化されているハズで満足な結果になった。

しかし、動作確認に使ったサンプル画像がアレなので動画の公開はまた今度〜(ぉ

Cairoが

透過画像が暗く表示されるので何事かと思ったが、Cairoが改版されて透過色の扱いが普通になったのが原因だった。

以前はCairoでは透過の場合RGBの各要素に不透過率が乗じられた状態で格納されてた。こうするとそのまま足せばいいのである意味簡単なのだがCairoを特別扱いする必要があった。

で、これがなくなって普通にRGBにはそのままの値が入るようになったので、普通に扱えば良くなった。というワケ。

2017年9月23日土曜日

概ねVBOは制覇した

敵は己自身(のミス)だけだったわけだけどorz

インデックスの値とか調べたところで三倍三倍繰り返してたのが原因で、インデックス数の三倍をglDrawElementsに投げててsegfaultで落ちるとか悩んでた。インデックス数はポリゴン数の三倍なので元々三倍されているというマヌケだ。

VBO使えないとキャラ出せないのでどうしようかとも思ったが、このあたりはこれで大丈夫そう。

2017年9月16日土曜日

VBOに着手

窓の描画ではほぼメリットのなかったVBOだが、背景画像や部屋、キャラを含むオブジェクトの描画では必要になるのでとりあえずエクイレクタングラーな背景画像もサポートするために着手してみた。流石に球の頂点を毎回プロセッサから送りつけるのは無駄が許容範囲を超えるしついでにスカイボックスもVBO化しときたい。毎回同じ頂点なんだし。

2017年9月13日水曜日

終了時に画面OFF

終了時に画面をOFFするようには組んであったが終了する方法がなかったので追加して画面がちゃんとOFFされることを確認できた。んしんし。

他に参照と(後)constポインタとポインタの原則を守ってない部分があったので修正。この原則は...

  • 参照ならdeleteしない(実体か呼び出し側が管理してる)
  • ポインタならdeleteする必要がある
  • (後)constなポインタ、つまりポインタ自体がconstならNull安全(最低でもassertされてる)
...というもの。本来ならこのあたりは言語が強制すべき部分だけどなー。

2017年9月10日日曜日

キャラメイク

キャラメイクについて考えてみたのだが、MMOだとそこにいるキャラ全部のデータをグラボに読ませなきゃならない関係上、好きなように-例えばFBX読ませたりとかみたいな-キャラ作らせるわけには行かなくて、その上wOCEはコミュニケーションツールに重点を置くのでゲームと違って「なうろーでぃんぐ」が許されない。なのでデータはなるべく小さくなるべく使い回さなきゃならん。

今のは知らないけどDC版のPSOがああいう、種族、身長、太さ、色みたいな限られたキャラメイクになってたのはそういう理由からだと推測していて、今だともうちょっとリソース使えるにしても似たようなものになりそう。そのへんの研究のためにやってみるかな...。

2017年9月8日金曜日

スレッドでテクスチャをアップデートするのはダメポ(2)

テクスチャのアップデートがクッソ遅いのできっちりコントロール下に置かないとフレームレートを維持できないのが理由で処理を再び集中化した...のだが、わかっているつもりではあったがここまで遅いとは思わなかった。フレームあたり8x8のタイルでせいぜい200枚くらいしか更新できない。

というところで今のところテクスチャサイズが二冪ではないのを思い出した。どのみちグラボで完結する処理に比べたらクッソ遅いんだろうけど二冪にしたら多少は高速化できるかも知れぬ。

--

二冪テクスチャを作ってやってみたが大して変わらなかった。転送サイズ拡大のほうが効くかも。

2017年9月7日木曜日

XRandRで画面を自動設定

VRHMDのプロファイルから画面名を読んで、XRandRで読んだEDIDに書いてある名前と一致してる画面が見つかったらONにして所定位置へ配置するようにした。これで一応画面配置に関する問題は解決。

いちいちXRandRを起動してるのでlibXRR使いたいところだけど手間なので後回しにしてこの件はひとまず終了っと。

2017年9月5日火曜日

スレッドでテクスチャ更新するのはダメポ

テクスチャ更新はかなり重い処理なのでフレーム更新に影響が出ないようにコントロールする必要があるのだが、別スレッドでこの処理をするとまったくコントロールできなくなってテクスチャ更新がまとまって入ってくるとフレームレートどころの話ではなくなる。RiftCV1なんかはフレームレートが乱れるとブラックアウトして回復しないようだし、ダメダメだ。

困ったことにフレームバッファのスワップはVSYNCに近い場合でもなければVSYNC待ちをしないので、メインスレッドでメッセージ処理をしようとすると無駄に描画するばかりでほとんど処理が進まなくなる。これがスレッド化した理由なのだが。

どうやらフレームバッファをスワップした後にglFinishを呼んでおくとVSYNCを待ってくれるようなので、結構苦労してマルチスレッド化したのだが元に戻すかあるいはテクスチャ更新だけメインスレッドですることになりそう。

--

RiftCV1がブラックアウトするのはUSB3の電源が原因のようだ。追加電源使うボード使ってるのだが、DK2も挿してるのがダメっぽい。

2017年9月4日月曜日

libXRandRの資料がろくでもない

接続されてる端子がわかってれば何も考えずにXRandRをspawnすればいいのだが、その端子を探すためにはEDIDを読まなければならないので調べてみた(get-edidはうちの環境では画面ひとつ分しか読んでくれなかった)。

libxrandrのmanページがメモ同然なのでXRandRのソースを読んだらstaticおじさん感が溢れ出してくる上に処理自体が結構めんどくさい。libXRandRが低レベルすぎる感。これは将来的には自前で書くとしても今は自前で書かずにXRandRをspawnして結果をパースするほうが良さそうだ。

「xrandr --prop」とかでEDIDを取得できたらEDIDのオフセット54からの長さ18bytesの4つのブロックのうち、先頭が00 00 00 fc 00になっているブロックに画面の名前が入ってるので、それが検出されたVRHMDと一致してたらその端子名を使って、画面有効化なら「xrandr --output 端子名 --auto -pos 場所」、画面無効化なら「xrandr --output 端子名 --off」をspawnすればいいようだ。

2017年9月3日日曜日

XRandRしなきゃならんかもだ

OpenHMDからRiftCV1の歪み補正情報を得たので試してみた。

のだけれど、RiftCV1は設定しないと画面として認識してくれないのでDK1/2のように一度画面を設定すれば繋がってる限り画面の設定が保存されるってわけには行かない。

KDEは接続のパターンごとに設定を覚えているけれど(そしてよくデスクトップと画面の対応を滅茶苦茶にしてくれて腹立たしいけれど)XFce4は全く覚えてくれない(が、変更してもデスクトップと画面の対応は安定している)...という感じに環境によって追加された画面の扱いがまちまちなのでここいらでXRandR使って自前で設定すべきなのかもと。どのみち他所の環境で動かすようになったら必要になるし。

2017年8月27日日曜日

レイアウタ

シェルからのリクエストで子プロセスへの通信路を確保して起動できるようにした...んだけどメニューとか出すためにはレイアウタを完成させないとならん。とりあえず描画内容を反映できるからとメニューとか先に「てやーっ!」て作っても結局「リストコントロールを使ったメニューコントロール」を作るのだから二度手間だ...てわけでレイアウタでやることを書いてみる。

レイアウタはサイズを持つWidgetのサイズを決めるもので、レイアウタを使うことでユーザプログラムは配置計算から解放される。要するに項目を追加してったり、予めサイズが決まってるところを分活したりする時に確保する幅や割合だけで宜しくやってくれるってわけ。

しかし、追加したり割り当てたりするのはいいんだけど、どういうインターフェイスにするべきか悩むところ。縦用とか横用とか用意するのかとか。

2017年8月17日木曜日

描画領域外の画素

Rift他大抵のVRHMDは光学系の歪みを描画内容を歪ませることで補正しているが、この副作用として実際のフレームバッファより大きな領域を必要とする。この関係で描画領域が実画面サイズと一致している場合フレームバッファ外から画素を拾う必要がある。

となるとテクスチャとして確保されたフレームバッファオブジェクトの外側をアクセスするわけで、デフォルトの設定では左右の外側が繰り返しになってしまって見苦しい、

というワケでフレームバッファオブジェクトの設定をGL_CLAMPへ変更。この設定だと外側へのアクセスは外周の半分の値を得られるのでちょうどいい塩梅にぼやけた感じになってくれる。最初歪み補正テクスチャの属性をいじって変わらんなーと悩んでたのはナイショだ。

2017年8月16日水曜日

TB::Threadの修正

TB::Threadではスレッド本体を自動で起動しているのだが、これがタイミングが悪いと継承する前のスレッド本体(純粋仮想関数)を呼び出してしまう可能性がある。

実際にはスレッドの起動は最低優先度スレッドで行われるのでまず起きないことではあるし今のところ問題は起きていないのだが、起動準備ができていないのに起動する可能性は依然残っているので明示的にRaiseThreadを呼び出して起動するようにした。

明示的に呼び出さないと動かないとか仕様として気持ち悪いのだが全ての継承先クラスのコンストラクタの処理が完了した事を確認する方法がないので仕方がない。

2017年8月12日土曜日

地磁気センサの磁化分除去

地磁気センサを扱うには地磁気より強い機器自体の磁化成分を除去する必要がある。旧来は「機器を8の字に回して」キャリブレーションしてみたり、あるいは旭化成が特許を持ってるDOEみたいな方法もあったのだが、VRHMDをぐるぐる回してキャリブレーションするのはかなり面倒だしDOEは知的財産権的に微妙だし四点のサンプルを必要とする。

考案自体はだいぶ前にしていたのだが式が解けなかったのだが、先ほど式ではないが図で解けた。しかもDOEが四点のサンプルを必要とするのに対して新方式は二点でキャリブレーションを進められる。

2017年8月2日水曜日

他の窓をGLXでキャプチャするのはダメポ

開発環境にはXfce4を使っているのだが、この環境でGLXでキャプチャするとXfce4をコンポジット処理の「全画面オーバーレイウィンドウを直接表示する」を設定しておかないとキャプチャできず真っ黒になり、指定しておくと画面の更新が止まり、コンポジットを使わないとゴミが読み出される...という状況になっている。

まぁ要するにこの方法では無理って事だ。

KDEとかだとまた違う可能性もあるのでそのうち試すとしても、GLXによるキャプチャが使えないとするとあのスットロイX標準の方法でキャプチャするしかないのか...orz

--

Xephryを取り込んだりして子コンテキストに描画させることはできるので不可能じゃないんだけど、手間かかりそうなので将来の課題だなー。本筋じゃないし。

2017年7月30日日曜日

どうしてLinuxではforkしたままだと共有ライブラリを読まないんだろう...。

forkしてexecするためのクラスを作ったのだが、ここで親プロセスではなく子プロセスが戻ってきてしまうように間違ったところ、共有ライブラリを読んでくれなくて死亡。

これはforkしてexecしてしまう場合には問題にならないが、プリエンプティブなスレッドが欲しい場合に問題になる。以前これについて調査したところ「forkする前になんか呼び出して予めライブラリを読ませとけ」というのが回答だったし他の回答はなかったのでこれがベストなんだろう。

メモリ空間をまるごと共有みたいな真似せずに必要ならmmapして共有しとけということかも知れぬ。

2017年7月28日金曜日

キャプチャのためのGLXコンテキスト

描画先が根窓ではない以上、キャプチャのためのGLXコンテキストが必要になる...というわけで作りかけだった部分を一通りちゃんと組んで安定してGLXコンテキストを扱えるようにしてみた...相変わらず値窓は真っ黒なわけだけどこれは後でXephyrの窓になるように修正するのでおk。

GLXコンテキストは何かマズイことをするとエラーを出すとかじゃなくてsegfaultで落ちるというセンシティブなブツなのだが、ラッパクラスがちゃんと動くことを確認できたのでこれで気軽に子コンテキストを扱えるようになるというもの。キャプチャに関してはあとはXephyrの起動と本命窓の特定ってところで、イベントの配信が巧く行けばアプリケーション側はVRHMDを外さずに開発できるようになる。

VRHMDの脱着は結構厄介な問題で、うちではDK1のスポンジはボロボロで、DK2のスポンジは切れた...と思ったら剥がれてただけなので補修しとこう。ともかくVRな開発で脱着を繰り返すとすごい勢いで痛むのだ。VRカバーってのもあるけど取れやすくて困るし...単純に面倒というのも小さくはないけどね。

2017年7月27日木曜日

WindowManagerの作り方

wOCEの前身であるRWMはWMとして書かれたが途中でWMではなくディスプレイマネージャであることに気付いて方針転換した関係上、おそらくwOCEではもう使わない情報だろうが本当に探すのが大変なのでWMの作り方へのリンクをメモしておく。

現在本当に探しているのは「窓を最小化するときには何をすべきなのか」なのだが、またこの情報がない。すぐに出てくるXIconifyWindowはWMに対してアイコン化するというメッセージを送るだけなので実際の処理はWMがする。WMの好きにやっていいってことなんだろうけど。

そんなもんが必要なのはXephyrの窓を表示しておいても邪魔なだけというのが理由。どのみちwODMの画面が上になるのだが無意味に表示させてオーバーラップの処理しても仕方がないので。

だがXの処理では表示させない窓はUnmapすることになってて、しかしUnmapすると中身が一切合切なくなってしまうので使えないし、窓がIconizeされるときにはUnmapされない。なので窓がIconizeされる時に何してるのか調べる必要があるというわけ。


「アイコナイズした時の座標」みたいなXリソースがあったのでおそらくこれを使うのだろう。値が非常に大きいので要は最小化した時は画面外に移動しているようだ...結局これかぁ...。

特定プロセスが作った窓を探す

X画面を直接キャプチャしようとするといろいろ問題があるので、X画面キャプチャのためにはXephyrやXnestを起動してその窓を探す必要がある。PIDはwODMからそれらを起動する時に得られるとしても、特定PIDの窓を探す方法がわからなかったので調査した。

StackOverflowの「How to get an X11 Window from a Process ID?」にあった。同様のエントリはもうひとつ。他の似たようなエントリはシェルスクリプトを使うものだったのでこの件とは無関係だ。

それによるとどうやら「_NET_WM_PID」ってラベルでAtomとして書き込まれているらしい。X11には窓に任意のデータを追加する機能があるのでXLibあたりがそれを使って書いといてくれているようだ。

--

間違い。_NET_WM_PIDとかの値はアプリケーションが自分で設定する必要がある。おそらく各種フレームワークはやってくれるだろうけど。

2017年7月26日水曜日

イベントがおかしい

SightEnterイベントが連続して送られてくるのだが...調べてみると一番近いWidgetを探すメソッドが奥のWidgetに反応しちゃってて、奥をWidgetが通る度にLeave/Enterが発生しているという困った状況になってる。

...んだが原因判明。ある点に対応するWidgetを探すときに子要素を辿る方法が間違っていたのが原因。間違っていたというより完全に余計なことをしているので、他の何かと間違って入れたものと思われるorz

ともかくこれで長かった「サンプルアプリケーションを作る(1)」をclose。

2017年7月23日日曜日

VSYNCを待たない問題(描画処理を待たせてみた)

フレーム時間の70%を経過してから描画処理が開始されるように設定してみたところ、目論見通り他の処理を高速化できた。最初の状態の10秒以上が0.5秒になると言ったところ。ほぼVSYNCを待つ環境と同様なのでこの方向で間違いはないだろう。

あとは描画負荷に合わせて待ち時間を調整したりフレームバッファの初期化なんかを待ち時間の前に入れて並列性を高めてみたりでこのあたりは完成とする。VSYNCに同期できないのは腹立たしいが現状では難しいので後回しにしとく。

VSYNC問題は続く

glSwapBufferがVSYNCを待たない問題はまだ解決していない。これを解決しないと何してもクッソ遅いので避けて進むわけにはいかないし。VSYNCを待つような設定や処理にしても待つのは処理がVSYNCを跨ぐ場合だけで、そうでない時は何も待たないのでほとんど意味がない。これはAMDのドライバだけでなくIntelのドライバも同様だ。

描画スレッドを待たせるだけなら周期的に描画スレッドを寝かせればいい。VRでは描画タイミングが大事なのでVSYNCからの時間情報が欲しいところだがないなら仕方ないというところで、ひとまず周期の最初の半分以上は描画スレッドを寝かすことにする。pthreadはコオペレイティブなので他のスレッドが長引くと大きく時間が狂うわけだが...。


Bloggerが吐くHTMLがアホなので直接HTMLで書くことにした。改行なんて吐いてんなよ。しかも微妙に間違ってるし。

2017年7月7日金曜日

Xのキャプチャを「表側」から...という計画

画面側のX環境をキャプチャしてVRHMDを脱がずに開発したいところだが、デスクトップ環境がルート窓を使ってなかったりしててなかなかうまく行かない。そこでXephyrとかXvfbとかXnestとかみたいな仮想画面を使ってルート窓からではなく「表側」からのキャプチャを試してみようと思う。

実のところルート窓をキャプチャするのは実画面のサイズに縛られたり、wODMの出力までキャプチャされちゃったり、Xdamageでキャプチャすると遅かったりでイマイチなわけだけど、仮想画面なら実画面を無視してサイズを設定できるしXephyrなら動画も楽々だし。

実装するにはXephyrの窓を探さなければならないわけだが。

2017年7月3日月曜日

VSYNC問題

グラボのドライバの中にはVSYNC待ちを無視してくれるものがあって、そういうドライバに当たると描画が忙しくてメッセージの転送や処理が回らなくなることがある。また逆に画像転送などのようにメッセージ処理に時間を取られて描画が疎かになったりする。なので描画とメッセージ処理を別のスレッドにした。スレッドの管理にはpthreadを使う。

メッセージ処理といってもテクスチャのアップデートなどがあるので描画スレッドとOpenGLのリソースは共有しなければならない。X環境ではこれはglXCreateContextでGLXコンテキストを作るときに元のGLXコンテキストを指定してやることでできる。なお、子コンテキストは親スレッドで作る

で、子コンテキストを作ったらスレッドを起こす。スレッドで子コンテキストをglxMakeCurrentすればおしまい。glxMakeCurrentを調べればわかるがpthreadのスレッドはGLXコンテキストを切り替え対象にしててちゃんと切り替えてくれる。余計な心配は要らない。

2017年6月27日火曜日

引き続きサンプルアプリケーションを作りつつフレームワークや画面側を試験している。作っているサンプルは画像ビューアなのだがスライドショー的動作は確認できた。これは最終的な仕様からは外れる動作確認的なものだ。

アプリケーションは画面からのイベントで受動的に動作するのでTB::Threadをアプリケーションクラスの親に追加しない限り能動的には動作しない。試しにスレッドを使わず初期化ハンドラの中で延々と処理させていたら、アプリケーションがいつまでもメッセージを受信しなくて画面側がイベントを送れなくなって画面ごと固まるというラバストネス的によろしくない動作になった。

そのうちアプリが固まってる時の処理を書かねばなるまい。Windowsで窓が白くなるアレだ。送信もスレッド化して送信しようとした時にキューにメッセージがあったら固まってると認識していいだろう。

課題はもうひとつ。テクスチャの更新など時間がかかる処理があるのでメッセージ処理系は描画コンテキストを複製して描画それ自体とは別のスレッドにする必要がある...しかし...もうどんなスレッドがあるかとかだいたいしかわかんねーよ。

2017年6月25日日曜日

TB::Prefsは設定を変数のように扱えて便利だが...。

サンプルアプリケーションを書いてたらなかなか根の深い問題を掘り当ててしまった。TB::Prefsはお手軽に使えるけど複数箇所から同じキーでアクセスするということができないので共通な設定を拾えない。使い方で悩むよりTB::Prefsを直すかなー。

「既に同じキーで値が登録されていたらそいつへの参照として振る舞う」的な...型違ったらどうするかなー。

2017年6月8日木曜日

i18n的なカタログ作ろうとするとどうしてもgettextみたいに「生成したファイルを人力で加工(つまり翻訳)して変換」したくなる。こういうのはmakeでもVCSでも扱いにくくなるのだが、ファイルの最後に追加された項目を追加するようにすれば扱いやすいかも知れず。

そのままカタログを生成すれば追加分は空だけど、すでに項目は追加されているのでその部分はもう変更されないので安心して書き換えられるしパッチも当たるという寸法。なくなったキーに対応する部分は放置されるけど問題はないだろう。
キャプチャ動かしたら真っ黒だったので、頭冷やすために他の場所を進めることにした。ということでルート窓キャプチャの修正を取り込んだ上で一つ戻ってplanet(VRゲームプラットフォーム)を進める。

planet記述スクリプトを読んでそのようにインスタンスを生成する部分なのだが、字句解析器を修正してる。今までは記号が出てくるだけでトークンを分離していたが修正後は呼び出し側から型を要求することで記号込みで字句解析できるようになる。これで負数をマトモに扱えるというものだ。

2017年6月7日水曜日

Xのキャプチャ

ルート窓を取り込むためのGLXコンテキストを作って、スレッドでカレントにするとsegfaultで、X越しに設定するとBadMatchでおっ死ぬのだが...スレッドなのでBadMatchってのはないと思うのだが...と悩んでいたのだが、manに「drawable が None なのに ctx が NULL でない場合」にも起きるとの記述がある。この場合drawableはルート窓なので...。

もしやと思いルート窓用のコンテキストを先に作って、それを描画先窓のコンテキストで共有するようにしたらX越しに設定すると相変わらずBadMatchは起きるものの直接設定した時にはsegfaultは起きなくなった。

もっとも、キャプチャできていないんだけど(ダメジャン

2017年6月6日火曜日

そのうちwebkitもやっとかなきゃだなー。と調べてみたところportにCairo-Windowsがある。wOCEの描画関連はCairoベースだが実行環境はLinux系なのでクッソ惜しい。wOCEのサーバにはXがないのでgtkのportで丸々持ってこられても困るんだが...これは窓用でも同じか。

webkitの概要はこのへんがわかりやすいと思うのでメモ。

2017年6月5日月曜日

根窓に直接描画するようにすると画面真っ暗というのはどうもxfce4の仕様が変わったのが原因な気がする。デスクトップの背景に記憶になかった「透明」ってのがある(指定したけど変わらなかった)。

窓を作って描画するとキャプチャが非常に面倒になるので避けたいのだが...キャプチャ自体はできるのだけれどGLXのコンテキストにはXのdrawableを指定する必要があって、描画対象の窓が別になると別のコンテキストになる。

親子関係があれば別コンテキストでリソースを共有できるので別コンテキストであること自体はいいのだが、GLXのコンテキストはスレッドにくっついてるのでスムーズに切り替えるには別スレッドにしとく必要がある(単一スレッドで切り替えるといちいちコンテキストの解放、作成を繰り返すことになるので非常に遅い)。逆に言えば別スレッドであればフレームバッファ切り替えの隙を突く必要もなくなるわけだが...。
あっれー?根窓に直接描くと何も出ないぞー?

2017年6月4日日曜日

今現在の本題であるデスクトップキャプチャに戻る。

wOCEの窓を用意してフレームバッファを取り込むだけの簡単なお仕事...のはずだったのだが、ルート窓に直接描画しているはずなのにwOCEの画面だけ...つまりVRの画面だけがキャプチャされる。たぶん「ルート窓に直接描画」になっていないのだろう。

もうひとつの問題も解決。

結局のところ「親指定がないときの動作が間違っていた」に尽きる。画面側ではアプリケーションに対応するクラス(DM::App)はWidget関連の処理を纏めるためにWidgetの一種として作られているが、アプリケーション側ではアプリケーションを代表するクラス(App::App)はWidgetではなく、そこが間違いの原因だった。

App::Appはmainより早く初期化されるので親にWidgetを付けるわけには行かなくてそうなっているのだが、App::Widgetのコンストラクタで親がないときにはApp::AppのIDを親に指定してパケットを作るところがDM::AppWidgetを作るようになってた。

...orz
C++の委員には科学者はいても工学者はいない。

そんな感じでC++は改版されてもデフォルトではちっともお手軽セキュアにならないから困る。

と、wOCEで使ってるtoolboxのcontainerを使う度に思う。例えばTB::List<T>のNodeはデストラクタで自分でリストから外れてくれるのでリストにゴミが残らない。リスト自体が消えた時の処理を書けたり指定すれば一緒に消えてくれるおまけ付きだ。

だがstdのリストにポインタを収めてしまうと自分の反復子を知らないと簡単には外せないし外す処理をリストにポインタを置くクラス全部に書かなきゃならん。かと言って現物を突っ込むと勝手にdeleteできない。もうね、アホかと(ry

なんか「コンピュータ・サイエンス」の連中、間違った方向に進んでねぇか?
さて、IDの生成をどうしようかと考えているわけだが...。

  • AppはResourceでもあるのでmainより前に初期化される。
  • クラスをstaticにインスタンス化してもコンストラクタが呼ばれるまでメンバの初期値は不定
  • 基本型や構造体をstaticに配置すると初期値は静的に設定される
みたいな条件があるのでAppで全部やるのもいいが、構造体をstaticに置いてノードから操作するような設計を試してみようかと。
template<typename T> struct IDArray{
  unsigned used;
  IDArray::Node* array;
  unsigned size;
  class Node{
  public:
    Node(IDArray& arr) : id(arr.used++), body(&arr){
      //mallocしたりreallocしたりした領域を確保したりthisを所定位置に設定したり
    };
    ~Node(){
      //返却と配列の所定位置のクリア
    };
  protected:
    const unsigned id;
  private:
    IDArray& body;
  };
};
こんな感じで。

2017年6月3日土曜日

原因がわかってきた。

現状で判明している問題は二つ。
  1. IDが正しく生成されていない
    具体的には生成されるIDが0,0,1...のように最初に0が二つ続いてしまう。これはAppの親がResourceなのが原因で、mainの前の初期化順が正しくないのが原因。対策を考えねばならない。
  2. 生成メッセージがサーバに渡って登録される時にはIDが0に化けている
    原因はまだわかっていないがCursorSetは正しく動作しているのでWidget絡みであることは判明している。
...今までこんなアホなバグ出さなかったんだけどなー。修正は問題起こしやすいわ。
通信方法をごっそり変更した直後なので起きてもおかしくはないことではあるが、Widgetに限ってサーバと画面でIDが食い違っているようだorz

キャプチャを後回しにして原因究明中...。

以前はできてたのになーんかルート窓をキャプチャできない...。

と思ったら、今のコードはフレームバッファオブジェクト(FBO)を使っているのでフレームバッファを切り替えてキャプチャして戻して...という操作が必要っぽい。全体的な描画関連処理は以下のような感じ...。

  1. FBOをbind
  2. 右視野設定
  3. 右を描画するついでにDisplayList蓄積
  4. 左視野設定
  5. DisplayList再生
  6. 生フレームバッファをbind
  7. FBOのテクスチャからVRHMDの光学歪みを除去するよう歪ませて描画
  8. VSYNC待ち

FBOはVIEWクラスにがっちり隠蔽されてて触れないのだが、VSYNC待ちの時は生フレームバッファがbindされた状態でxDisplayモジュールに処理が回ってくる。このタイミングならデスクトップをキャプチャできるだろう。

2017年6月2日金曜日

public継承すると親クラス扱いできるが、加えて多重継承してると当然全ての親クラス扱いできる。そうすると色んなパラメタとしてthisを使えて便利。で、この多重継承の「何でもthis」に慣れてしまって過去コードでDIしたりしててコンポジションになってると激しく不便を感じる今日この頃。
現状では大改造の余波でスクリーンキャストをオミットしてあるので復活せねばなるまい。てことでチケットを起こす。今はXのルートウィンドウのキャプチャ機能を実装しているのでスクリーンキャストに着手するのはもうちょっと後になるけど、スクリーンキャストできないと見せられないからね。
このブログはこのあたりで開発しているVRへ引き籠るためのプロジェクト、wOCEの開発日記です。スクリーンキャストはこのへんに置いてあります。

引っ越すことにした。

引っ越し先。 見えるかな。