IDLのZバッファ擬似デバイスは、2次元または3次元のグラフィックスを描画する際に用いられるバッファ (一時的な記憶領域)である。3次元グラフィックスを表示する際に、オブジェクトの前後関係を判断する(Zバッファ法による陰面処理)のに用いられる。また、2次元グラフィックス処理の際に、作業用のフレームバッファとして用いることもできる。
IDLのZバッファは2種類の領域から構成される。一つは8ビット/ピクセル(または24ビット/ピクセル)の画像を保持するためフレームバッファ、もう一つはZバッファ法で用いられる深度を保持するための16ビット/ピクセルの震度バッファである。2つのバッファの解像度は同じである。
出力先のデバイスを Zバッファ疑似デバイスに変更する。
SET_PLOT, 'Z', /COPY
Zバッファの解像度を設定する。以下の例では800x600ピクセルに変更している。デフォルトの解像度は 640x480ピクセルである。
DEVICE, SET_RESOLUTION = [800, 600]
色深度を変更する。指定可能な値は8(デフォルト値)と24である。
DEVICE, SET_PIXEL_DEPTH = 24
色深度が24-bitのとき、色値をフルカラー(24-bit color, true color)か疑似カラー(pseudo color, indexed color)のどちらとして解釈するかを切り替える。デフォルトではフルカラーとして解釈される。色深度が8-bitの時は、疑似カラーのみ利用できる。
; フルカラー (デフォルト)
DEVICE, DECOMPOSED = 1
; 疑似カラー
DEVICE, DECOMPOSED = 0
グラフィックスデバイスの状態を調べる。
HELP, /DEVICE
Zバッファに割り当てられているメモリーを解放し、Zバッファは初期化される。
DEVICE, /CLOSE
出力デバイスをウィンドウ表示に戻す。
; Unix
SET_PLOT, 'X'
; Windows
SET_PLOT, 'WIN'
Zバッファに切り替える前に、システム変数 !D.NAME
の値を保存しておいて、元に戻す。
; 元のデバイス名を保存しておく
olddevice = !D.NAME
SET_PLOT, 'Z'
; 元のデバイスに戻す
SET_PLOT, olddevice
Zバッファのうち画像保持用のフレームバッファは、IDLのプロット・グラフィックスルーチンで利用可能な疑似デバイスである。通常のウィンドウなどのデバイスと同様、ERASE
プロシージャでバッファをクリア、TV
プロシージャとTVSCL
プロシージャで配列の内容をバッファに書き込むことができる。 またTVRD
関数でバッファの内容を配列に読み出すことができる。
色深度がデフォルトの8-bitのときは、フレームバッファを操作するとき、ERASE
, TV
, TVSCL
, TVRD
で特にキーワードは不要である (デフォルトの読み書き対象のチャンネルが CHANNEL = 0
のため)。
olddevice = !D.NAME
SET_PLOT, 'Z'
DEVICE, SET_RESOLUTION = [800, 600]
; Zバッファに対して適当なプロット
CONTOUR, DIST(100), NLEVELS = 100, /FILL
; バッファの内容を配列 a に読み出す
a = TVRD()
; 元のデバイスに戻す
SET_PLOT, olddevice
; 配列 a の内容をウィンドウに表示 (カラーテーブルを設定して表示)
DEVICE, DECOMPOSED = 0
LOADCT, 2
TV, a
DEVICE, SET_PIXEL_DEPTH = 24
として色深度を24-bitに設定したときは、フレームバッファは赤・緑・青色用のそれぞれ8-bitのチャンネルから構成される。フレームバッファ読み書きの際、操作対象のチャンネルを指定する場合、CHANNEL
キーワードを用いる。このとき、CHANNEL = 1
が赤、CHANNEL = 2
が緑、CHANNEL = 3
が青チャンネルとなる。TRUE
キーワードで 1 を指定すると、24-bit カラーとして読み書きを行う。
深度バッファを直接読み書きするには、ERASE
プロシージャ, TV
プロシージャ, TVSCL
プロシージャ, TVRD
関数で CHANNEL = 1
(色深度が24bitのときは、CHANNEL = 4
)、/WORD
キーワードの両方を指定する。
a = TVRD(CHANNEL = 1, /WORDS)
TV, a, CHANNEL = 1, /WORDS
深度バッファはshort integer型で -32765から32765の値を取る。この値は、Z値 (Z-value) と呼ばれ、画像保持用フレームバッファにおける同じ場所の深度を保持する。Z値は手前に行くほど大きくなる。まだ何も描画されていない場所の深度は -32765 (つまりもっとも後方) である。点を描画するときは、その点の深度とその点の位置におけるZ値を比較し、深度がZ値よりも大きいとき(つまり手前にあるとき)のみ描画する。この時、Z値をその深度で置き換える。多くの3次元グラフィックスルーチンでは、グラフィックスデバイスがZバッファの時、自動的にこの処理を行ってくれる。
以下の例では、重なり合う球とグリッドを表示する。この例では SHADE_VOLUME
プロシージャを用いて等値面として球を作っているが、MESH_OBJ
プロシージャを用いれば一発で作成できる。
olddevice = !D.NAME
SET_PLOT, 'Z'
DEVICE, SET_RESOLUTION = [512, 512]
ERASE
; 表示範囲を設定 (ここで深度バッファと奥行きとの対応づけも行われる)
SCALE3, XRANGE = [0, 20], YRANGE = [0, 20], ZRANGE = [0, 20]
; 球面1を作る
; まず、各点における中心からの距離を計算する
sphere1 = FLTARR(21, 21, 21)
FOR x = 0, 20 DO FOR y = 0, 20 DO FOR z = 0, 20 DO sphere1[x, y, z] = SQRT((x - 13) ^ 2 + (y - 10) ^ 2 + (z - 10) ^ 2)
; 等値面を作る
SHADE_VOLUME, sphere1, 5.5, v1, p1
; サーフェースをZバッファに描画する
; POLYSHADE はグラフィックスデバイスがZバッファの時は、Zバッファに直接描画を行う
dummy = POLYSHADE(v1, p1, /T3D)
; 同様にして球面2を作る
sphere2 = FLTARR(21, 21, 21)
FOR x = 0, 20 DO FOR y = 0, 20 DO FOR z = 0, 20 DO sphere2[x, y, z] = SQRT((x - 7) ^ 2 + (y - 10) ^ 2 + (z - 10) ^ 2)
SHADE_VOLUME, sphere2, 4, v2, p2
dummy = POLYSHADE(v2, p2, /T3D)
; グリッドを描く
FOR i = 0, 20 DO PLOTS, [i, i], [0, 20], [10, 10], /T3D
FOR i = 0, 20 DO PLOTS, [0, 20], [i, i], [10, 10], /T3D
; a にフレームバッファ、b に深度バッファを保存する
a = TVRD()
b = TVRD(CHANNEL = 1, /WORDS)
; 元のデバイスに戻し、バッファの内容を表示する
SET_PLOT, olddevice
DEVICE, /DECOMPOSED
WINDOW, XSIZE = 1024, YSIZE = 512
TV, a
LOADCT, 33, RGB_TABLE = table
TV,REFORM(table[BYTSCL(b), *], 512, 512, 3), 512, 0, TRUE = 3
画面出力は以下のようになる。左がフレームバッファ、右が深度バッファ(わかりやすいように着色)の内容である。
西田圭佑 (NISHIDA Keisuke)