元記事:Dev-Source-GameEngine-2.49-VideoTexture - BlenderWiki


VideoTexture モジュール



VideoTexture モジュールは、ゲーム中にテクスチャの操作を可能にします。動画ファイル、画像ファイル、ビデオキャプチャ、メモリバッファ、カメラレンダー、もしくはそれを組み合わせたものといった、様々なデータソースをテクスチャに使用できます。動画と画像ファイルはファイル名の変わりに URL を使用することでインターネットから読み込むことができます。更に、GPUに送る前に画像にフィルタを適用することができ、ブルースクリーン、カラーバンド、グレー、Normalマップなどのビデオエフェクトが可能です。VideoTexture は FFmpeg を使用して画像や動画を読み込みます。FFmpeg がサポートするすべてのフォーマットと Codec を VideoTexture はサポートしています。以下はその一例です。
[wiki]-AVI
-Ogg
-Xvid
-Theora
-video4linux capture card
-dv1394 camera
-videoForWindows capture card
-JPG[/wiki]


動作原理


原理は簡単です。最初にオブジェクトと名前で現存するテクスチャを認識し、その後新しいテクスチャを動的コンテンツで作成、二つのテクスチャを GPU 内で交換します。GE はこの置き換えに気づくことなく、そのテクスチャを掌握している以外は、そのオブジェクトを通常どおり表示します。最後は、新しいテクスチャは削除され、古いテクスチャが復活します。

このページは VideoTexture モジュールとシンプルなサンプルのガイドです。


ゲームの準備


VideoTexture モジュールを使用する前に、テクスチャを適切に適用したオブジェクトがある必要があります。

ゲーム内に生放送のプログラムが映し出されるテレビを置くのを想像してみて下さい。テレビオブジェクトと UV を作成し、スクリーン部分に違うテクスチャ、例えば 'tv.png' を適応します。このテクスチャの見た目はあまり重要ではありません。通常、電源オフの状態をシミュレートし、暗いグレーでつくることになるでしょう。このテレビが ON になった時、動的テクスチャをビデオキャプチャカードから作成し、tv.png の代わりにそれを使用します。TV スクリーンは本領を発揮するでしょう。

VideoTexture が使用できる Texture の定義方法は二つあります。
[wiki]+シンプルな UV Texture
+Image Texture チャネルのある Blender Material[/wiki]

VideoTexture は Texture レベルで動作するため、GLSL、マルチテクスチャ、カスタムシェーダといった、GE のテクスチャ装飾機能のすべてと互換性があります。


最初のサンプル


たくさんの Face の内の一つに、動画を表示したい Material/Image を割り当てているゲームオブジェクトが1つあるとします。

最初のステップは、Texture オブジェクトの作成です。これは一度だけ実行するスクリプト内で行います。ゲームスタート時に行うといいでしょう。動画はそのテクスチャをリフレッシュした時にのみ再生されますが、これは後ほどご紹介します。
通常このスクリプトは、対象オブジェクトへの参照を簡単に取得できるよう、その動画を表示したいオブジェクトに添付します。

import VideoTexture

contr = GameLogic.getCurrentController()
obj = contr.owner

if not hasattr(GameLogic, 'video'):

この 'video' アトリビュートのチェックは、その Texture を一度しか作成させないようにするためです。


Material の検索


    matID = VideoTexture.materialID(obj, 'IMvideo.png')

VideoTexture.materialID() はそのオブジェクトの動作を使用する Material を取得するのに便利な機能です。このメソッドは Material と UV テクスチャで動作します。
UV テクスチャの場合、そのテクスチャが割り当てられている Face に対応する Material が返ります。
Material の場合、最初のチャネルの名前がマッチする Image Texture チャネルを持つ Material が返ります

接頭辞 'IM' は、Texture 名を検索することを表しますが、接頭辞を 'MA' にすることで Material も検索可能です。例えばこのオブジェクトで VideoMat をいう名前の Material を探したい場合、以下のようなコードになります。

    matID = VideoTexture.materialID(obj, 'MAVideoMat')


Texture の作成


VideoTexture.Texture は、GPU 上に動的テクスチャを読み込む Texture オブジェクトを生成するためのクラスです。コンストラクタは1つの引数(必須)と、3つのオプション引数を取ります。

gameObj
ゲームオブジェクト。

materialID
VideoTexture.materialID()により返される Material インデックス。デフォルトでは0で、最初のチャネルを表します。

textureID
マルチテクスチャチャネル時の Texture インデックス。デフォルトは0で最初のチャネルです。
UVテクスチャの場合、このパラメータは常に0です。

textureObj
再利用したい他の Texture オブジェクトへの参照。
この引数を使用する場合、この Texture 上に source を作成してはいけません。また、リフレッシュも必要ありません。この Texture オブジェクトは、Material/Texture の両方のためのテクスチャを提供することになります。


    GameLogic.video = VideoTexture.Texture(obj, matID)

Texture の持続


GameLogic の、この処理のために作成した 'video' アトリビュートにこのオブジェクトを指定したことに注意して下さい。
なぜこうするのかというと、この Texture オブジェクトは複数のゲームスクリプトに渡って、ずっと持続させなければならないからです。ローカル変数はそのスクリプトの最後で削除され、GPU テクスチャも同時に削除されます。
GameLogic モジュールオブジェクトは、永続させるオブジェクトを置く場所として便利です。


ソースの作成


とりあえず Texture オブジェクトを手に入れましたが、ソースがないとまだ何もできません。VideoTexture がソースとして利用できるものの一つから source オブジェクトを作成する必要があります。

VideoFFmpeg
動画
ビデオファイル、ビデオキャプチャ、ビデオストリーミング

ImageFFmpeg
静止画
画像ファイル、ウェブ上の画像

ImageBuff
アプリケーションメモリ上の画像
コンピュータ生成画像、画像アプリケーション用

ImageViewport
ビューポートの一部もしくは全体(アクティブカメラがスクリーンに表示しているレンダリング画像)

ImageRender
非アクティブカメラのレンダリング画像

ImageMix
前述のソースの二つ以上をミックスした物

このサンプルでは、シンプルな動画ファイルをソースとして使用しています。VideoFFmpeg コンストラクタはファイルネームを引数として取ります。ファイル位置に混乱が生じないよう、この動画ファイルが Blend ファイルと同じディレクトリにあるものと仮定し、GameLogic.expandPath()を絶対パスを生成するのに使用しています。

    movie = GameLogic.expandPath('//trailer_400p.ogg')
    GameLogic.video.source = VideoTexture.VideoFFmpeg(movie)

video.source オブジェクトを生成し、そのソースのセットと、それを永続的にするため、 Texture オブジェクトの source アトリビュートに指定しています。Texture オブジェクトが永続的であれば、ソースオブジェクトも永続的になります。
この Texture ソースはいつでも変更できることに注意して下さい。二つの動画をゲーム中に切り替えたい場合、以下のようにします。

    GameLogic.mySources[0] = VideoTexture.VideoFFmpeg('movie1.avi')
    GameLogic.mySources[1] = VideoTexture.VideoFFmpeg('movie2.avi')

そしてこの後、ゲーム中にソースを指定(再指定)します。

    GameLogic.video.source = GameLogic.mySources[movieSel]


source の設定


この VideoFFmpeg source は動画再生用のアトリビュートをいくつか持っています。

range ([start,stop])
start と stop に動画再生の場所を頭からの秒数で設定します。デフォルトでは動画全体になっています。

repeat (integer)
動画リプレイする回数で、-1で無限です。

framerate (float)
相対的なフレームレート。1.0未満で遅く、1.0より上で早くなります。

scale (bool)
True をセットすると、高速な最近傍スケーリングアルゴリズムを作動させます。

テクスチャの縦と横は2のべき乗でなければなりません。動画画像サイズが2のべき乗でない場合、サイズ変更処理が要求されます。デフォルトでは VideoTexture は正確ですが低速な gluScaleImage()関数を使用します。一番いいのは、実行時にサイズ変更する必要がないように、あらかじめ動画をサイズ変更しておくことです。

flip (bool)
その画像の縦を反転しなければならない時に True にして下さい。
FFmpeg は常に画像を上下逆に出力するため、このアトリビュートはデフォルトで True になっています。

filter
GPU に送る前にその動画に適用するフィルタを設定します。
VideoTexture filter オブジェクトを一つ指定します。デフォルトでは、画像は GPU にそのまま送られます。アルファチャネルがその動画にある場合、自動的に読み込まれ、同様に GPU に送られます。

gluScaleImage() はリアルタイムビデオには非常に遅いため、単に scale アトリビュートを True にセットすることにします。動画の大きさがすでに2のべき乗である場合は効果がありません。

    GameLogic.video.source.scale = True


動画の再生


これで動画を再生する準備が整いました。

    GameLogic.video.source.play()

動画再生はバックグラウンドプロセスではありません。このテクスチャをリフレッシュする時のみ動作します。そのため、別のフレーム毎に実行されるスクリプトで、Texture オブジェクトの refresh() メソッドを呼び出す必要があります。

if hasattr(GameLogic, 'video'):
    GameLogic.video.refresh(True)

もしこの動画ソースが止まった時は、refresh()は効果がなくなります。refresh()の引数はテクスチャを次のリフレッシュ時に再計算するべきかどうかを示すフラグです。動画再生時は明らかに True にしたくなるでしょう。


高度な処理


refresh()メソッドの引数の True は、単に GPU に送った後の image バッファを無効にし、次のフレームに新しい画像をソースから読み込めるようにするだけです。これにはその画像を Python で利用できなくなるという副作用があります。
また、source の refresh()メソッドを直接呼ぶことで手動で行うこともできます。

以下は可能な処理の一部です。



GameLogic.video.refresh(False)
image = GameLogic.video.source.image
# image is a binary string buffer of row major RGBA pixels
# ... use image
# invalidates it for next frame
GameLogic.video.source.refresh()


# note that we don't even call refresh on the Texture 
# we could also just create a source object without a Texture object
image = GameLogic.video.source.image
# ... use image
GameLogic.video.source.refresh()
(訳注:コメントの翻訳です。
# Texture の refresh()も呼んではいけないことに注意
# また、Texture オブジェクトがなくても source オブジェクトの作成だけはできます。


デモのダウンロード


こちらからダウンロードできます。


上級のデモ


こちらのデモは、同じテクスチャ上で二つの動画を交代で使用するものです。別に elephants dream のティーザーが必要ですが、他の再生したいファイルに差し替えることもできます(訳注:日本語ファイル名はおそらく無理。blendファイルと同じフォルダにおくこと)。

こちらのデモは、ImageMix ソースの使用デモです。ImageMix は、VideoFFmpeg、ImageFFmpeg、ImageRender などの他のテクスチャソースを必要とするソースです。setSource()にこれらをセットし、それぞれのウェイトをsetWeight()で行います。このウェイトは0-256までの Short Integer で、合計256でなければなりません。ImageMix はこれらのウェイトに従い、すべてのソースをミックスします。ソースは画像サイズが(2のべき乗の一番近い寸法に縮小した後に)同じである必要があります。そうでない場合、Python のエラーがコンソールに表示されます。


元記事:Dev-Source-GameEngine-2.49-VideoTexture - BlenderWiki
このページは27 May 2009, at 22:14版を元にしています。