画像描画関数/オフスクリーン描画


ウィンドウのアップデート処理について

PP Basicでは、画像をMain / Subウィンドウに直接描画することが可能です。しかし、MacintoshのようなGUIベースのOSでは、描画したウィンドウAに他のウィンドウBが重なった場合、ウィンドウBを移動するとこの領域の画像は消去されてしまいます。

 →  → 

図1 他のウィンドウによる画像の消去


Mac OSでは、他のウィンドウによって隠されていた領域の再描画はアプリケーションが行う必要があります。 言い換えれば、アプリケーションが責任を持って再描画しない限り、他のウィンドウによって画像が消去された部分は空白のままになります。

Post Plot 3Dでは、メインウィンドウのコントロールパネルや2次元グラフ、メインウィンドウ内の3次元オブジェクト等はアプリケーションが画像の再描画を担当します。PP Basicに対しては、PP Basic専用オフスクリーンへ描画された画像のみ再描画を実施します。

オフスクリーン

Mac OSでは、画像再描画の負担を減らすために、オブジェクトを直接画面上に描画せずに、初めにメモリ上の仮想スクリーン(=オフスクリーン)上に欠けのない画像を描画し、必要に応じてオフスクリーン上の画像を画面上のウィンドウ内に転送するという手法がよく利用されます。オフスクリーンはGWorld(=Graphics World)と呼ばれ、メインウィンドウの画像の直接描画を避ける以外に画像処理用の一時作業場としても良く利用されます。

図2 オフスクリーンの利用によるウィンドウの再描画

PP Basicから直接ウィンドウに描画せずに、オフスクリーンへ

描画した画像を必要に応じてウィンドウに転送する

 

PP Basicでは、PP Basic専用に三枚のオフスクリーンを用意しており、それぞれMain Windowの仮想スクリーン、Sub Windowの仮想スクリーンおよび画像処理用の一時作業場として利用することが出来ます。

次に、具体的なオフスクリーン作成関数の使用法について説明します。



オフスクリーン作成関数

PP Basicでのオフスクリーン(=GWorld)作成の手順はいたって簡単で、以下のようなコマンドで作成することが出来ます。

#-----------------------------オフスクリーン作成サンプルコード
disposeGworld #古いGWorldを破棄
createGworld(800,600) #新しくGWorldを作成
setGworld #描画対象領域をGWorldに設定
cls #画面の消去
#
#             ここで画像描画
#
flushGworld #GWorldに描画された画像をメインウィンドウに転送
#-----------------------------


オフスクリーンの新規作成:createGworld

createGworld(wx,wy)

新規にオフスクリーンを作成します。作成するオフスクリーンのサイズはwx,wyで指定します。
このコマンドが呼び出されたときに既にオフスクリーンが作成されていた場合、PP Basicはエラーを返します。


描画対象領域の設定:setGworld, setScreen

描画対象領域の切り替えに使用します。対象をオフスクリーンとする場合setGworldを、メインスクリーンとする場合setScreenを呼び出します。setScreenでメインスクリーンに直接描画した画像は、flushScreenやflushGworldコマンドによる画面の再描画の際に消去されます。


オフスクリーン内の画像の消去:clsGworld

オフスクリーン内の画像を消去します。描画対象領域がメインスクリーンに設定されている場合にも、本コマンドを実行することでオフスクリーン内画像を消去できます。


オフスクリーン内の画像をメインスクリーンへ転送:flushGworld

オフスクリーンに描画された画像をメインスクリーンへ転送します。PP Basicプログラムの実行中は、このコマンドを実行するかflushScreenを呼び出すことで画像をモニタ上に表示することが出来ます。


オフスクリーンの破棄:disposeGworld

作成したオフスクリーンを破棄し、メモリを解放します。PP Basicプログラムの実行終了後、Basicで描画した画像を再描画する必要がない場合に呼び出します。
また、createGworldコマンドは呼び出し時に既にオフスクリーンが作成されているとエラーを返しますが、disposeGworldはオフスクリーンが作成されていない状態で呼び出されてもエラーとはなりません。プログラムの作成時には、createGworldを呼ぶ前に一度disposeGworldを呼び出す習慣を付けておくと良いでしょう。