|
はじめての LG3D プログラミング- LG3D で Hello World! その 3 アニメーション編 - |
||
今までの Hello, World は画像ファイルを使用して、それを表示させるという方法をとっていました。しかし、画像ファイルを用意するのはちと面倒です。 そこで、今回は動的に表示するイメージを作ってしまいましょう。ところで、動的にイメージが作れるのだったらということで、簡単なアニメーションにも挑戦してみました。 今回使用した LG3D のバージョンは Release-0.7.0 です。
|
動的にイメージを作る |
||||||||||
LG3D には System.out.println("Hello, World!"); のように簡単に文字列を出力することはできません。出力できるのは、テクスチャすなわちイメージだけです。 それじゃというわけで、イメージを作ってしまいましょう。イメージを動的に作るにはいろいろ方法がありますが、一番基本的な BufferedImage クラスを使ってみます。
イメージを作る部分を下に示します。
まずは BufferedImage オブジェクトを作成します。ここで作成しているのは 200 × 25 pixel で透明を使用できるイメージです。第 3 引数の TYPE_INT_ARGB は int の中にアルファを加えた ARGB の色情報を格納することを示しています。 生成するだけだと何もないイメージなので、そこに書き込んでいきます。そのためには Grphics オブジェクトを使用します。今までダブルバッファリングを自分で行われた方にはすぐ分かると思いますが、やり方はまったく同じです。 次の setRederinghHint メソッドは描画するときの設定を行うために使用します。ANTIALIASING というのは、輪郭の部分を濃淡で表すことによって見た目が滑らかになるような手法です。 そして、色を設定し、フォントを指定して、drawString メソッドを使用してイメージに文字を書き込みます。最後に使用した Graphics オブジェクトを廃棄しておきます。 これで、Hello, World! と書かれたイメージが作成できました。 さて、問題はここからです。イメージをどのように表示しましょうか。 今までは ImagePanel クラスというお手軽クラスを使用してきましたが、それを使うわけにはいきません。というのも、ImagePanel クラスは画像をファイルからしか読み込まないようになっているからなのです。 それでは、どうしましょう。 前回、Shape3D クラスなど表示できるクラスには Appearance クラスという色や材質などを保持したクラスを保持していることを説明しました。この Appearance クラスはその他にテクスチャも保持しています。 テクスチャというのは 3D 物体に貼りつけるイメージのことです。テクスチャをポリゴンに貼りつけることで、モデリングをすると複雑になってしまう形状も、擬似的に表すことができます。たとえば、デコボコを表すために下の図のようにデコボコの画像を貼りつけることで擬似的にデコボコを表してしまいます。
このような技法をテクスチャマッピングといい、CG に欠かせない技術となっています。 先ほどのイメージもこのテクスチャとして物体に貼りつけてしまおうというわけです。 それでは、まずテクスチャを作ってみます。LG3D ではテクスチャを org.jdesktop.lg3d.sg.Texture クラスで表します。直接 new することもできるのですが、ここではユーティリティクラスの org.jdesktop.lg3d.sg.utils.image.TextureLoader クラスを使用してみましょう。
TexutreLoader オブジェクトを生成するにはコンストラクタでイメージを指定します。その他にも、いろいろな方法で生成できるのですが、それについては Javadoc をご覧ください。 TextureLoader オブジェクトが生成できたら、Texture オブジェクトを getTexture メソッドを使用して取得します。 さて、Texture オブジェクトは生成できました。次はこれを Appearance オブジェクトに設定します。 前回は Appearance オブジェクトを ImagePanel オブジェクトから取得させましたが、ここでは直接生成してみます。Appearance クラスを直接使用してもいいのですが、使い方が簡単な org.jdesktop.lg3d.utils.shape.SimpleAppearance クラスを使ってみました。 SimpleAppearance クラスのコンストラクタは第 1 から第 4 引数が RGBA の色情報で、次に SimpleAppearance オブジェクトのタイプを指定します。ENABLE_TETURE はテクスチャを使えるようにすることですが、DISABLE_CULLING はこういうものだと思っていてください。 次に、setTexture メソッドを使用して、生成した SimpleAppearance オブジェクトにテクスチャを持たせます。 前回は ImgePanel クラスを使用しましたが、今回はよりプリミティブな FuzzyEdgePanel クラスを使いました。FuzzyEdgePanel は Lg3dHelp で使われているクラスで、パネルの端の部分がぼやけたような感じになったパネルです。ぼやける量はコンストラクタの第 3 引数で指定できますが、ここでは EDGE を 0 にしているのでボケません。 後は前回と同じです。 FuzzyEdgePanel オブジェクトを Component3D オブジェクトに addChild して、それを Frame3D に addChild します。 実行すると下の絵のようになります。
事前にイメージを作らなくてもちゃんと表示することができました。
|
アニメーションに挑戦 |
|||||||||||
せっかく動的にイメージを表示することができたので、やってみたいことがあります。 それはアニメーションなんです。アニメーションは異なるイメージを次々と表示させれば実現できます。 キャラクターが動くようなアニメーションでもいいのですが、まずは文字を変化させることをやってみます。
アニメーションをするには定期的に繰り返し処理を行わなければならないのですが、それには java.util.Timer クラスを使用しました。java.util.TimerTask クラスを派生させたクラスに繰り返し行いたい処理を記述します。
BufferedImage オブジェクトを生成して描画するのは先ほどと同じです。しかし、BufferedImage オブジェクトは使い回しをするので、前回描いたものをクリアする必要があります。それを clearRect メソッドを使用して行っています。 描画する文字列はフィールドに定義してあります。
できたイメージからテクスチャを作成して、Appearance オブジェクトに設定するのも HelloWorld6 クラスと同じです。 最後に Timger オブジェクトを生成して、5 秒ごとにタスクを繰り返すようにします。 これで実行すれば、Hello, World! から順々に文字列が表示されるはずです。 ところが、実行すると例外が発生してしまいました。
CapabilityNotSetException 例外のメッセージを見てみるとテクスチャを貼ることができないと書いてあります。 えー、でもさっきまでテクスチャ貼れてたじゃないですか。どうしてなんだろう。 SimpleAppearance クラスと Appearance クラスの Javadoc を見てみたら Appearance クラスの定数に ALLOW_TEXUTRE_WRITE なんてのがありました。これだ、と思ってソースに加えてみました。
ところがこれでもだめです。 しかたがないということで、テクスチャ貼り替えをしていると思われる部分を lg3d-core のソースの中から探して見ました。そうしたら、コンストラクタで ALLOW_TEXTURE_WRITE を指定するのではなくて、Appearance#setCapability メソッドで指定するのだそうです。しかし、それは気づかないと思うんですが...
こうすることで、ちゃんと実行することができました。
|
おまけ その 1 |
|||||||
せっかくアニメーションまでできたのですから、もう少しよくばって何か違うものを作ってみましょう。今までのソースを流用できて、簡単に作れるものがいいですね。 というわけで、ディジタル時計を作ってみます。
時計を作るといっても HelloWorld7 クラスとほとんど同じで、描画の部分が異なるぐらいです。 変更した部分は赤字で示してみました。
時間の表示のところに java.textDateFormat クラスを使わないで Tiger で取り入れられた java.util.Formatter クラスを使用しています。詳しくは虎の穴を参照ください。
HelloWorld7 クラスと LgClock クラスで行ったアニメーションは効率がいい方法とはいえません。というのもアニメーションを行うために毎回 TextureLoader オブジェクトを生成し、新しい Texure オブジェクトを生成しているからです。 この方法で 1 秒間に何枚もテクスチャを描きかえるようなアニメーションはつらいのも事実です。 もう少し効率のいい方法もあるのですが、ここでは実現の容易さを優先させてこの方法をとりました。
|
おまけ その 2 |
|||||||
今までは文字でアニメーションをしていましたが、やっぱりアニメーションといえば絵ですよね。そこで、こんなものを作ってみました。
このサンプルは動的にテクスチャを生成するわけではなく、初期化時にまとめて画像ファイルを読み込んで、テクスチャを生成してしまいます。
テクスチャを作ってしまえば後は定期的にそれを切り替えるだけです。
実行すれば、ジャグリングをしてくれるはず... えっ、誰かに似ている? たぶん、気のせいです ^^;;
|
|