「 2012年10月 」一覧

透明ウィンドウの話 その2


アプリで透明なウィンドウっていう部分は1つのウリになる部分で、やっぱりWindows 7(Vista)でしか動かないってのはやっぱまずいと思うんですよ、ということでもう少し調べて何か方法はないかと考えてみました。以下にその考えてみた話をメモっておこうと思います。

まず、DWM OFF状態でそもそも目的の動作が出来ない時点でまずいでしょう。Vista,7でBasicテーマであっても背景透過なアプリとして動くべき。この方法を確立しなくてはいけないのかな。

続いて、Windows8でも動作できること。
挙動から完全なるDWM OFFではなさそうなので、これも厄介そう。上記のベーシックモードでも動くような実装で、こちらの方法が動くようであれば問題は一気に解決する。

現在とりあえず実験中。

前者のWindows7,VistaでのDWM OFF時の状態でも動くようにという点で、いろいろと試してみたところ、LayeredWindowならば、実装の仕方によっては正常に動くようです!
変に実装すると全く描画されないようですが・・・・。(その境目を現在調査中)

これがもしそのままWindows8で動くとすれば、問題は解決になるのかなと思います。

DirectXであれ、OpenGLであれ、レンダリング済み画像をバックバッファのロックという方法で取得して、LayeredWindow用のHBITMAP内のビットイメージに再書き込みという方法でいけるのかなと考えてます。

ちなみに GDIサーフェースに直接描くって方法は、ちょっとできないでしょう。
というのもLayeredWindowで要求される仕様が事前乗算済みアルファの形式を求めてるようで。
この処理をどうしても最後に処理してあげないといけないため、描画して終了という形にはならないのかなと思います。

※ バックバッファのロックってパフォーマンスペナルティが大きいので、どこまで実用になるかは未検証です


透明ウィンドウとWindows8


ようやくWindows8が発売されていろいろと話題になっているようですが、Aeroがなくなってしまった点は個人的に残念に思います。また、このAeroがなくなったことで、透明なウィンドウの扱いがちょっと困ったことになっているように見受けられます。

参考: http://umezawa.dyndns.info/wordpress/?p=3335

Windows Vista/Windows7 では、DWMの機能をつかってうまく実現できていたようですが、これが半透明は無効状態になったことで出来なくなったのかなと思います。

具体的に出来なくなっているように見られたのが、DirectXやOpenGLを用いた結果をデスクトップ上に半透明を有効にした状態での合成という点です。単純にアルファ無しの不透明で、背景を抜くような方法についてはうまくいくようです。

今回DirectX用に使ったサンプルは DWMTestという下記のサイトで公開されていたものを利用させて頂きました。

参考: http://nyaruru.hatenablog.com/entry/20060628/p2

また、OpenGL用には自分で作ったプログラムです。うまく行かなくてちょっと試行錯誤していたので、こちらはWin7ではかろうじて動いているもののもしかしたらよくない作りをしているかもしれません。

これらのプログラムをWindows7で動かすとこのようになります。

どちらの場合もDirectX, OpenGLでのアルファ付き描画の結果を、透過なウィンドウに対してうまく動いているように見えています。

これらをAeroをOFFにして動かす(ベーシックやクラシックのテーマで動かす)と、以下のようになります。

透過して欲しいところが全く抜けていない状態となっています。

さて、これをWindows8で動かしてみて画面をキャプチャしてみます。

このキャプチャ結果を見ると一見うまく動いているようにみえますが、先ほどの結果と比較すると色がちょっとおかしいことに気付くと思います。DirectXのほうは概ね問題ないように見え、OpenGL側はちょっとアルファが効き過ぎている、そんな感じでしょうか。

しかし、キャプチャしたデータではなく実際に動かすと、これらの両方ともの透明部分が妙な動きをするのです!それゆえどちらも正常に動いているとは言いがたい状況です。この部分は参考(1)のサイトさんのほうに詳しくかかれています。

まとめ

どうも今までの作りでうまくいっていた半透明ウィンドウ(透過型のアプリ)はちょっと作りを考え直さないといけないのかもしれません。Vista, Windows7とAeroの流れはどうやらここで終わりのようです。半透明のウィンドウ枠は結構好きだったので残念です。

※ Windows8でもこれらDirectXやOpenGLを併用した半透明でもうまく合成できる方法をご存じの方は教えて頂けるとうれしいです。


スキニングメッシュのバウンディングボックス


久しぶりにスキニングメッシュ(エンベロープモデル)のネタです。
キャラクターのモデルでバウンディングボックスやスフィアを使って、あたり判定を行っていましたが、
結構無駄な部分が出来てしまい、結果厳密なチェックが出来ないという残念な結果になってしまいます。

かといって、頂点変形をCPUで全ての頂点で行って厳密なバウンディングボックスを作るのもこのご時世に何かあっていないようなそんな気がします。今だとシェーダーでスキニングロジック実装しちゃいますしね。

そんなわけでもう少しまともなバウンディングボックスを作れないかチャレンジしてみました。今回はこの中身に触れたいと思いますが、まずは処理結果の図を以下に示します。

割と各部位に従ってボックスが出来ているのがわかると思います。これが動きに合わせて追従してくれるので、使い勝手はよいかなと思っています。ボックス自体の頂点情報は固定で、単にボーンの行列に合わせて変形されるので処理も結構軽い物となっています。

処理手順

画像を見てもわかるようにDirectXサンプルの定番 tiny.x を使用しています。
そして、SkinnedMeshサンプルの改造です。

  1. 各ボーンの影響頂点群を取得して、各頂点で一番大きなボーンはどれなのかの情報を保持します。
    D3DXにはこの操作に便利な GetBoneInfluence, GetNumBoneInfluence というID3DXSkinInfoのメンバ関数が用意されているので楽に処理できます。
  2. 各頂点を走査して、自身が一番影響を受けるボーンのボーン行列と頂点位置を乗算します。
  3. 計算されたボーンローカルの位置で、そのボーンがもつバウンディングボックス情報を更新します。
    位置が最小、最大なら現在の値で置き換えるという処理。

これらの処理により、各ボーンが自分の影響する範囲でのバウンディングボックスを構築することが出来ます。

その他

動かしてみていると若干つなぎ目部分で隙間が出来ていたりします。
あたり判定に使うにはちょっとまずい場合があるのかもしれません。
あと、ConvertToIndexedBlendedMesh でメッシュを更新したあとだと、GetBoneInfluenceで返ってくる値と食い違いが出て悩みました。どうやらこれは変換前の頂点データ群についての結果を返してくるようです。
変換前後での頂点のマップを用意して処理してあげることが必要でした。


記事の削除


そういえば10月になってガード解除系は違反になったんだったなと思い出して、
過去の録画環境構築ネタでやっていた ktv-fsusb2の改造記事を削除しました。

ソフトの簡単な組み合わせで実現できるようなネタは残してありますが、さすがに電子工作じみたこととファーム書き換えなどまで行ってTS抜きするような話はまずいだろうという判断です。


RhodecodeのActiveDirectory認証


ActiveDirectoryの認証を用いてユーザー認証できるというRhodecodeですが、その説明を書いた部分が見つからないのでここにメモがてら残しておきたいと思います。一応紹介記事ではLDAP/ActiveDirectoryが使える!とあるのにその設定が見つからないのはどうなのだろうと思ったり。

Rhodecodeの設定

ここで試しているRhodecodeは 1.4.3 です。
管理者ユーザーでログインして LDAP の項目を表示させます。そして以下の内容で設定していきます。

  • LDAPを有効にする にチェックを入れる。
  • ホスト: ActiveDirectory(ドメインサーバー)が動いているアドレスを入力
  • ポート: 389
  • アカウント:検索用のユーザー名. なければ適当なユーザー名を。
  • パスワード:上記ユーザーのパスワード
  • 接続のセキュリティ:暗号化無し
  • 証明書チェック:NEVER
  • Base DN: ドメイン名がMYDOMAIN.LOCALの場合だと、 DC=MYDOMAIN,DC=LOCAL と入力する
  • LDAPフィルター: 空欄のまま
  • LDAP検索範囲:SUBTREE
  • ログイン属性: sAMAccountName
  • 名前属性(FirstName): givenName
  • 名字属性(LastName): sn
  • メールアドレス属性:mail

これらの設定で自分の環境ではドメインのユーザーを認証できています。


linuxによるAndroid開発環境を整える(NDK編)


前回でNDKの手前まで環境構築が終わったので今回はNDKに関する部分の設定を行っていきます。

ネイティブ開発用の準備をする

NDKを用いるとC/C++で開発を行うことが出来ます。ここからはNDKをインストールして環境を整えていきます。

http://developer.android.com/tools/sdk/ndk/index.html からNDKのアーカイブをダウンロードします。
この記事を書いている時点では r8b というバージョンのものになります。

ダウンロードしたら、ホームディレクトリで展開しておきます。

環境変数を設定します。
.bashrcを開いて末尾に設定を追加します。今までの分もちょっとだけ整理してみて、以下のようになっています。

設定したら再読込を行っておきます。

eclipseを起動します。そして Sequoyahプラグイン群をインストールを行います。
より丁寧な解説は過去の記事を参考にお願いします。

以前のものはWindows環境で書かれているので、多少違うかもしれませんが大体は同じです。

Sequoyahプラグインのインストール

メニューの Help / Install New Softwareを選択して、Work Withの部分に、”http://download.eclipse.org/sequoyah/updates/2.0/”を入力します。
そのときに、”Group Items by category”のチェックを外しておきます。

現れたプラグインのリストを全てチェックを入れて、インストールを行います。インストール後には、eclipseの再起動が必要となります。

再起動したら、Preferences より Android のカテゴリを開き、”Native Development”を開きます。ここにNDKの展開先を入力する部分があるので、そこに先ほど展開したディレクトリを設定します。

動作チェック その1

新規にプロジェクトを作成して “Android Project from Existing Code” を選び、NDKのサンプル内に含まれているhello-jni からプロジェクトを作成します。

プロジェクトを右クリックして Android Tools/Add Native Support を選択します。
その後、Run as / Android Application で実行してみます。
うまく設定されていれば、C/C++のソースコードがコンパイルされ、Android端末上に Hello from JNI!の文字が表示されていることと思います。

ndk-gdbの設定など

続いてC/C++側に任意のブレークポイントを設定して使えるようにするための設定を行います。
まずDebug Configurationsを開きます。そこで C/C++Applicationを選択し、新規作成を行います。

作成した構成を選択し、画面中央部分の、”Using GDB(DSF) Create Process Launcher “の部分のリンクできる場所をクリックします。新しいウィンドウが開くので“Standard Create Process Launder”を選択します。

Mainタブの部分では、デバッグ対象の .so 名が表示されていますがこれをプロジェクトのパス内の obj/local/armeabi/app_processというパスに変更します。

Debuggerタブの部分では、Debuggerが gdb/mi になっているので、 gdbserver に変更します。
GDB debugger の部分には、android-ndkに入っていたgdbを選択させます。
linuxの場合、android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-gdb というファイルになります。

GDB command file の部分には後ほど作成する gdb2.setup を設定します。
これも obj/local/armeabi の中にできあがる予定となっています。

Debugger Optionsの中のConnection タブを開きます。
この中の Type を TCP に変更します。そしてPort number を 5039 に変更します。

android-ndk-r8bに含まれているndk-gdbファイルを編集します。

ファイル中で、

となっている部分を、以下のようにコメントアウトしておきます。

続いてapp_process, gdb2.setupのファイルを用意します。
まずJava側のonCreate関数でブレークポイントを設定して、デバッグ実行を行います。
このとき、ブレークポイントで停止したら、端末(Terminal)を起動します。

作業を行っているプロジェクトのディレクトリまで移動し、(jni,objディレクトリらがある場所)、そこで ndk-gdb-eclipse スクリプトを実行します。
実行後、obj/local/armeabiディレクトリに移動します。

この場所にapp_process, gdb.setupファイルが出来ていると思います。gdb.setupはコピーして中身を編集します。

gdb2.setupを開いて、末尾の “target remote :5039” を削除します。

ここまで出来たら、一度デバッグ実行を終了させておきます。

動作確認 その2

C/C++側のコードにブレークポイントを設定してみます。ここではとりあえずNewStringUTFを呼び出している部分にブレークポイントを設定します。そして以下の手順を実行します。

  1. 先ほどJava側のonCreateにブレークポイントを設定してあるので、まずここまでをデバッグ実行します。
  2. 停止したら端末で ndk-gdb-eclipse を実行します。(エラーが出るようなら –forceオプションを付けます)
  3. eclipseでDebug As/debug configurationにて、先ほど作成した構成を選択して Debugボタンを押します。先ほどはHelloJNI-NativeGDBという名前で構成を作成してあります。
  4. Java側のonCreateで停止している部分を解除し、実行を継続します。
  5. C/C++側のブレークポイントを設定してある部分でデバッガが停止することを確認します。

まとめ

ここまでの手順にてUbuntuを用いて NDK環境の C/C++ソースコードのデバッグが出来るようになりました。VMwareを用いてのLinux環境なので、Windows環境を汚さずにAndroidのネイティブ開発を行うことが出来ます。開発PCのリソースは結構高めに必要になりそうですが、開発効率という面で十分に効果を発揮してくれるものと思います。

C/C++ソースコードの警告エラー

その他、こまるようなポイントとして C/C++側のソースコードについて警告が消えてくれないことがあります。
一度ソースコードを開いてしまうとどうも駄目なようです。
そのためプロジェクトの設定で、”C/C++ General”/”Code Analysis”内のチェックボックスを全てOFFにして対処しています。
また、この後既に検知された警告エラーをDeleteで削除しています。

その後で、プロジェクトを右クリック “Clean Project”を実行し、”Build Project”を行うと、.soファイルが生成されることを確認できました。


linuxによるAndroid開発環境を整える(NDKの手前まで)


Ubuntu Desktop 12.04 LTSを使ってAndroid用の開発環境を準備してみます。

その環境ですが、実PCではなく仮想マシンに構築してみることにします。
ここでは VMware Workstation 8.0 を使用し、仮想マシンの設定はUbuntu 64bitのデフォルトで構成しています。

仮想マシンを構築したあとで、Ubuntuのディスクイメージをセットして、
“Ubuntuをインストール”を選択します。
仮想マシンなので、ディスクを全削除してインストールにしておきます。

Dashホームから”Terminal”と入力すると、”端末”アプリケーションが見つかるので、起動させます。
その後、VMwareToolsをインストールします。
(tar展開&インストールスクリプトの実行)
注意点としては、sudo ./vmware-tools-install.pl というように sudo コマンドで実行することくらいでしょうか。

今64bit Linuxを使用しているので下記のパッケージをインストールします。

AndroidSDKのインストール

Java(JDK)をまずインストールします。

javaがインストールされたことを確認します。

このような状態になっていたら大丈夫です。

Android SDKをダウンロードしてきます。
ここでは android-sdk_r20.0.3-linux.tgz というファイルで作業しています。
また他のユーザーに影響を与えないために、ホームディレクトリ以下にSDK群を配置する方法をとります。

SDK Toolsを PATH に追加します。

vi で .bashrc を開き末尾に以下の内容を追記します。

現在の環境で反映されるように、再読込させます.

Eclipseのインストール

Eclipseをインストールします。ここではちょっと前のバージョンの 3.8.1 64bit版を使用します。

このバージョンのものをダウンロードするのにちょっと手間取りました。
Eclipse Downloadsから Packages ではなく Projects を選び、その中にある”Eclipse Project”を選ぶことでようやく任意の過去のバージョンのものへアクセスできるようになります。

以下のようにしてホームディレクトリ以下にeclipseというディレクトリが出来るようにファイルを展開します。

一度eclipseが起動するかを確認しておきます。
下記コマンドではなく、ホームディレクトリ内eclipseディレクトリを開いたウィンドウからeclipseを実行してもかまいません。

起動が確認できたら終了しておきます。

ADTのインストール

eclipseを起動し、メニューから “Help / Install New Software” で ADT をインストールします。
Addボタンを押して、Nameに ADT, Locationに https://dl-ssl.google.com/android/eclipse/ を入力して、OKを押します。

すると、情報が取得されてインストール可能な一覧が出てくるので、
チェックボックスにチェックを入れてインストールを行います。
“Developer Tools”にチェックを入れるだけでOKです。最近はネイティブ用のプラグインも追加されたようです。これにチェックをいれておいてもよいでしょう。

チェックを入れたら Next ボタンを押してインストールを行っていきます。
途中でeclipseの再起動が行われます。
そのときに、新規にAndroidSDKをインストールするか、既に置いてある場所を入力するかを確認するダイアログが出てきます。

ここではUse existingSDKsを選択し、先ほどのandroid-sdk_r20.0.3-linux.tgzを展開した場所を入力します。
(例: /home//android-sdk-linux)

その後 SDK Platform Toolsが見つからない!とエラーが出てきます。
そのウィンドウに Open SDK Managerというボタンがあるのでこれをクリックして起動します。

開いたウィンドウで Android SDK Platform-tools という項目にチェックを入れておきます。
このときに開発したい対象の Androidバージョンにもチェックを入れておきます。

チェックを入れたらインストールボタンを押してインストールを行います。

(何も考えずにチェックしてインストールしてしまうとそれなりに時間がかかります、ご注意を。対象のバージョンをトップカテゴリで丸ごと選択するのではなく個別に選択しておくと多少は時間が少なくてすむかもしれません。SDKとsamplesだけをとりあえずインストールしておいて、あとで必要になったときに追加するという方法でもよいかと思います。)

端末(terminal)を開いてパスの設定を変更します。
先ほどの PATHの設定に下記の内容を追加します。

ADBの再起動

ADBを管理者権限で動かしておかないとデバイスの認識が出来ないようなので…。
下記の手順で、adbを管理者権限で起動させます。

ここでAndroid端末を接続してみます。
VMware側に接続されるようにしてください。
(VMwareウィンドウの右下にUSB用のアイコンがあるのでそれで適切に接続してください)

接続してデバイスを認識しているか表示させてみます。

一部伏せていますが、上記のように表示されればOKです。
またEclipseを再起動し、LogCatのウィンドウを開いてみると、デバイス中のログメッセージが流れていく様子を確認することが出来ます。

動作確認 その1

とりあえずここまででJavaによるAndroidの開発環境は準備できたことになるので、
うまく動作するかを確認してみます。

eclipseを起動して、New Project/Android ApplicationProject を選択します。
各項目は適切に設定してください。一応こちらの画面を参考までに下記に示します。
表示していない部分に関してはデフォルト設定のままです。

上記の設定でプロジェクトを作成しようとした際に、足りないパッケージをインストールするか聞かれたので、そこはInstallを行っています。

onCreateの中にブレークポイントを設定し、Debug As / Android Application でデバッグ実行をしてみます。
うまくいけば、このブレークポイントで停止します。
うまく行かない場合には、まず端末上に今実行したアプリケーションが表示されているか、Debugで実行を行っているかを確認してみてください。Run Asではブレークポイントで停止しませんので・・・。


GitlabとRhodecodeのメール設定


GitlabとRhodecodeを調べていてメール関連でどちらも設定を放置していたので調べてみました。

Gitlabの場合

gitlab.yml の email セクションの host という項目に対して、メールサーバーのアドレスを設定します。
たいていlocalhostのままなので、ここにメールサーバーのアドレスを記載します。
localhostのままでメールを送れるようにするためには、gitlabを動かしているサーバーでPostfixなりssmtpなりのメールサーバーを動かす必要があります。

Rhodecodeの場合

production.ini ファイルの中に smtp_server という項目があるので、そこにメールサーバーのアドレスを記載します。送信についてSMTP認証がかかっていたりする場合には、smtp_serverの行付近にアカウント情報を設定するような項目があったので、そこで設定してあげればよいように思います。

ついでに、email_prefix という項目もあるので、何かしら設定しておくと、メール振り分け設定の指標になるし便利だと思います。


Rhodecodeのバージョン更新


1.3.6を以前インストールしましたが、最近は既に1.4.3が出ているようなので以下の手順でバージョンをあげてみました。

バージョンを更新する

production.ini.oldの中身を確認しつつ、新しく作られた production.ini の中身を再設定していく.
自動マージされるらしいのだけど、手元ではうまくいきませんでした。

データベースを更新します。

起動し直します

そういえば更新してみて気付きましたが、言語を日本語の設定にすることが出来るようになったようです。production.iniの中にlangという項目があり、そこにjaを設定することができます。

チケット連携?

rhodecodeのIssue Tracker連携があるかと思っていたのですが、連携というわけでは無く単にリンクが張られるだけのようでした。コミットコメントにチケット番号を記述しておくと、それに対応する
IssueTrackerのチケットへ飛べるだけの機能のようにみえます。