盤面表示に苦労する
今は、Ubuntu版EdaxBoardの開発中で、今日は、とりあえず、メインウインドウに盤面表示をしようとしたのだが、中々、上手くいかず、作業時間を消費した。プログラミング環境が異なると、画像表示方法も異なるので大変だ。
EdaxBoardの場合、盤面と石の画像を、予め、png形式の画像ファイルとして作成しておき、その画像をウインドウに表示している。
ただし、Windows版では、このpngファイルは実行ファイル内にリソースとして埋め込んであるので、配布パッケージにはpngファイルは存在しない。
macOS版では、pngファイルは、Appバンドルの中に埋め込んである形になっているので、ユーザー的には、これらのpngファイルを別ファイルに差し替えれば、表示する盤面画像を変更可能だ。
もっとも、仕様的に、盤面画像をユーザーがカスタマイズ可能にするのであれば、Windows版についてもpngファイルは実行ファイルに埋め込むのではなく、別ファイルとして実行ファイル外に置いている。
なので、macOS版でpng画像が差し替え可能になっているのは、プログラミングの都合上、結果的にそうなっている! というだけの事だ。
それでは、Ubuntu版については、どうなっているのか、というと、やはり、png画像のデータは実行ファイルに埋め込んでいる。
Windows版と微妙に書き方が異なっているのは、Ubuntu版の実行ファイルにはリソース領域というモノは存在していないので、普通の配列の初期化データとして埋め込んでいる格好になる。
そんなトリッキーな事をしなくても・・・、と、思った人もいるかもしれないのだが、上記のやり方は、グラフィックスライブラリとしてGtkを使うソフトの場合、Gtkにより専用ツールまで用意されているので、由緒正しいやり方、という事になる。
なので、EdaxBoardでも、盤面画像等はpngファイルとしてではなく、上記の様な配列の初期化データとして実行ファイルに埋め込んでいるのだが、問題は、ここからだ。
前述の様に、このやり方は由緒正しいやり方なので、Gtkの処理関数の中には、こうやって埋め込まれているpng画像データから描画用のオブジェクトを生成してくれる関数もあったりする。
具体的には、Gdk::Pixbuf::create_from_inlineという関数に、前述の配列を渡すと、描画可能なデータが入ったオブジェクトが返される。
問題は、そのオブジェクトを使って、RGBAの画像データを取り出そうとすると、サイズが大きい盤面データの場合のみ、クラッシュしてしまった! という事だ。
盤面データは860x853ピクセルあるので、作者的には、上記の関数は大きなビットマップには対応していないのかなあ、と、思った訳だ。
何故なら、上記の関数は、作者の他のUbuntu版ソフトで、結構、使ってきていたのだが、Nostalgic UFO Battlerを除くと、ビットマップのサイズは128x128ピクセルくらいが最大だったからだ。
もっとも、Nostalgic UFO Battlerでは、1024x1024ピクセルの画像を読み込んでいて、問題なく利用できていたので、作者的にも、変だなあ、とは思ったのだが、Nostalgic UFO Battler用のデータは、小さいキャラクターを幾つも透明背景の上に並べた画像になっていた訳だ。
その結果として、ピクセル数は大きかったのだが、pngデータのサイズ的には、EdaxBoardの盤面データよりも小さかった訳だ。
なので、作者的には、pngデータが大きすぎるとダメなのかなあ、と、思って、AmuseGraphicsを使って、より小さいキャンバスに盤面データの一部をコピーする格好で分割し、複数のpngファイルに分けてみた。
その結果として、横方向に10分割した10個のpngファイルを読み込ます事は出来たので、そうやって読み込んだ画像をEdaxBoard内で並べて本来の画像用のRGBAデータを作成した。
これでやっと、描画できる筈! という事でやってみると、表示された画像は変な感じだった。
具体的には、色が変だったし、パターンについても、少しずれて複数表示される感じだった。
上記は、普通に考えると、RGBAデータがRGBデータとして扱われている感じだったのだが、前述のNostalgic UFO Battlerのコードを見てみると、別に、テスト用のコードに問題はない感じだった。
なので、RGBAデータを適当な色データで埋めてみた所、正しく表示された。
つまり、表示用のコードは正しい感じだったので、作者的には、前述のGdk::Pixbuf::create_from_inlineが、クラッシュしていないだけで、実は、正しく動作していないのか? と、疑った。
なので、より小さいピクセルである所の石の画像だけを読み込んで表示してみた所、やはり、描画が同様に変になった。
と、言う事で、作者的には疲れてしまったのだが、その後、Ubuntu版AGMPlayerのソースコードを見てみた所、前述のPixbufからRGBAデータを取り込む為の処理関数を自前で用意していて、その処理関数の中身を見てみると、どうも、読み込む画像によって、Pixbufに保存される画像データの形式が異なる! という事が判った。
つまり、作者製のソフトで使っている画像データは、多くの場合、透明背景のアイコンデータみたいな感じになるので、PixbufにはRGBAデータが保存されていたのだが、今回のEdaxBoardに関しては、透明領域がないpngデータになっているので、Pixbufに保存されているデータというのも、RGBAの32ビットではなく、RGBの24ビットだった! という事が問題の本質の様だった。
なので、作者的には、Ubuntu版AGMPlayerから、前述のコードを持ってきて、更に、盤面データを複数に分割しない最初のモノに入れ替えて、RGBAデータを取得して画像表示してみた所、やっと、マトモに表示された。
もっとも、実際には、RGBAデータが手元にあるからといって、ウインドウにそのデータを描画できる訳ではない。
つまり、他にも色々と苦労しながら作業していた訳なのだが、疲れてしまったので、今日は、盤面の背景画像を表示できる様になった所で、作業は終了! という事にした。
なので、EdaxBoardで必要になるテキスト表示! なんかはまだ出来ていないので、画面表示用の作業は明日も続く事になる。
ちなみに、AGMPlayerに処理コードがあったにも関わらず、最初、それを使わなかったのは、AGMPlayerの処理コードがEdaxBoard用としては、複雑すぎる! と、考えたからだ。
AGMPlayerを使ってみれば判る筈なのだが、AGMPlayerでは、フォルダーなんかのビットマップ表示以外にも、動画のサムネイル表示だとか、その半透明合成処理だとかもある訳だ。
つまり、ソースコードの公開を前提にしているEdaxBoardの場合、そういった、自前ライブラリ化してある各種ルーチンは使いたくないので、基本的な所から、最低限のコードで書こうとしている訳だ。
その結果として、普通なら、何も考えずに自前のライブラリ関数を呼ぶので、最早、Ubuntu版だからといって、画面描画に困る事はないのだが、逆に、いつもそんな感じでコーディングしている分、そのライブラリを使えない! という事になると、細かい処理内容なんて覚えていないので、苦労する事になる訳だ。
と、言う事で、まだ、苦労しそうではあるのだが、最悪、前述の自前ライブラリのコードを部分的にでも持って来れば、何でもできる筈なので、多分、明日には、描画系の実装は終わっている様な気がしている今日この頃だ。

