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の開発日記です。スクリーンキャストはこのへんに置いてあります。

引っ越すことにした。

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