Zバッファ

概要

IDLのZバッファ擬似デバイスは、2次元または3次元のグラフィックスを描画する際に用いられるバッファ (一時的な記憶領域)である。3次元グラフィックスを表示する際に、オブジェクトの前後関係を判断する(Zバッファ法による陰面処理)のに用いられる。また、2次元グラフィックス処理の際に、作業用のフレームバッファとして用いることもできる。

IDLのZバッファは2種類の領域から構成される。一つは8ビット/ピクセル(または24ビット/ピクセル)の画像を保持するためフレームバッファ、もう一つはZバッファ法で用いられる深度を保持するための16ビット/ピクセルの震度バッファである。2つのバッファの解像度は同じである。

基本的な操作

出力先のデバイスを Zバッファ疑似デバイスに変更する。

  1. SET_PLOT, 'Z', /COPY

Zバッファの解像度を設定する。以下の例では800x600ピクセルに変更している。デフォルトの解像度は 640x480ピクセルである。

  1. DEVICE, SET_RESOLUTION = [800, 600]

色深度を変更する。指定可能な値は8(デフォルト値)と24である。

  1. DEVICE, SET_PIXEL_DEPTH = 24

色深度が24-bitのとき、色値をフルカラー(24-bit color, true color)か疑似カラー(pseudo color, indexed color)のどちらとして解釈するかを切り替える。デフォルトではフルカラーとして解釈される。色深度が8-bitの時は、疑似カラーのみ利用できる。

  1. ; フルカラー (デフォルト)
  2. DEVICE, DECOMPOSED = 1
  3. ; 疑似カラー
  4. DEVICE, DECOMPOSED = 0

グラフィックスデバイスの状態を調べる。

  1. HELP, /DEVICE

Zバッファに割り当てられているメモリーを解放し、Zバッファは初期化される。

  1. DEVICE, /CLOSE

出力デバイスをウィンドウ表示に戻す。

  1. ; Unix
  2. SET_PLOT, 'X'
  3. ; Windows
  4. SET_PLOT, 'WIN'

Zバッファに切り替える前に、システム変数 !D.NAME の値を保存しておいて、元に戻す。

  1. ; 元のデバイス名を保存しておく
  2. olddevice = !D.NAME
  3. SET_PLOT, 'Z'
  4. ; 元のデバイスに戻す
  5. SET_PLOT, olddevice

フレームバッファ

Zバッファのうち画像保持用のフレームバッファは、IDLのプロット・グラフィックスルーチンで利用可能な疑似デバイスである。通常のウィンドウなどのデバイスと同様、ERASE プロシージャでバッファをクリア、TV プロシージャとTVSCL プロシージャで配列の内容をバッファに書き込むことができる。 またTVRD 関数でバッファの内容を配列に読み出すことができる。

色深度がデフォルトの8-bitのときは、フレームバッファを操作するとき、ERASE, TV, TVSCL, TVRD で特にキーワードは不要である (デフォルトの読み書き対象のチャンネルが CHANNEL = 0 のため)。

  1. olddevice = !D.NAME
  2. SET_PLOT, 'Z'
  3. DEVICE, SET_RESOLUTION = [800, 600]
  4. ; Zバッファに対して適当なプロット
  5. CONTOUR, DIST(100), NLEVELS = 100, /FILL
  6. ; バッファの内容を配列 a に読み出す
  7. a = TVRD()
  8. ; 元のデバイスに戻す
  9. SET_PLOT, olddevice
  10. ; 配列 a の内容をウィンドウに表示 (カラーテーブルを設定して表示)
  11. DEVICE, DECOMPOSED = 0
  12. LOADCT, 2
  13. 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キーワードの両方を指定する。

  1. a = TVRD(CHANNEL = 1, /WORDS)
  2. TV, a, CHANNEL = 1, /WORDS

深度バッファはshort integer型で -32765から32765の値を取る。この値は、Z値 (Z-value) と呼ばれ、画像保持用フレームバッファにおける同じ場所の深度を保持する。Z値は手前に行くほど大きくなる。まだ何も描画されていない場所の深度は -32765 (つまりもっとも後方) である。点を描画するときは、その点の深度とその点の位置におけるZ値を比較し、深度がZ値よりも大きいとき(つまり手前にあるとき)のみ描画する。この時、Z値をその深度で置き換える。多くの3次元グラフィックスルーチンでは、グラフィックスデバイスがZバッファの時、自動的にこの処理を行ってくれる。

以下の例では、重なり合う球とグリッドを表示する。この例では SHADE_VOLUME プロシージャを用いて等値面として球を作っているが、MESH_OBJ プロシージャを用いれば一発で作成できる。

  1. olddevice = !D.NAME
  2. SET_PLOT, 'Z'
  3. DEVICE, SET_RESOLUTION = [512, 512]
  4. ERASE
  5. ; 表示範囲を設定 (ここで深度バッファと奥行きとの対応づけも行われる)
  6. SCALE3, XRANGE = [0, 20], YRANGE = [0, 20], ZRANGE = [0, 20]
  7. ; 球面1を作る
  8. ; まず、各点における中心からの距離を計算する
  9. sphere1 = FLTARR(21, 21, 21)
  10. 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)
  11. ; 等値面を作る
  12. SHADE_VOLUME, sphere1, 5.5, v1, p1
  13. ; サーフェースをZバッファに描画する
  14. ; POLYSHADE はグラフィックスデバイスがZバッファの時は、Zバッファに直接描画を行う
  15. dummy = POLYSHADE(v1, p1, /T3D)
  16. ; 同様にして球面2を作る
  17. sphere2 = FLTARR(21, 21, 21)
  18. 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)
  19. SHADE_VOLUME, sphere2, 4, v2, p2
  20. dummy = POLYSHADE(v2, p2, /T3D)
  21. ; グリッドを描く
  22. FOR i = 0, 20 DO PLOTS, [i, i], [0, 20], [10, 10], /T3D
  23. FOR i = 0, 20 DO PLOTS, [0, 20], [i, i], [10, 10], /T3D
  24. ; a にフレームバッファ、b に深度バッファを保存する
  25. a = TVRD()
  26. b = TVRD(CHANNEL = 1, /WORDS)
  27. ; 元のデバイスに戻し、バッファの内容を表示する
  28. SET_PLOT, olddevice
  29. DEVICE, /DECOMPOSED
  30. WINDOW, XSIZE = 1024, YSIZE = 512
  31. TV, a
  32. LOADCT, 33, RGB_TABLE = table
  33. TV,REFORM(table[BYTSCL(b), *], 512, 512, 3), 512, 0, TRUE = 3

画面出力は以下のようになる。左がフレームバッファ、右が深度バッファ(わかりやすいように着色)の内容である。

重なり合う球とグリッド。左がフレームバッファ、右が深度バッファの内容

西田圭佑 (NISHIDA Keisuke)
nishida at kwasan.kyoto-u.ac.jp
$Id: zbuffer.html,v 1.7 2019/09/03 07:13:02 nishida Exp $