GLwDrawingArea, GLwMDrawingArea — OpenGL
用の描画ウィジェット
#include <X11/GLw/GLwDrawA.h>
ld ... -lGLw -lGL
-l<任意のウィジェットライブラリ>
-lXext -lXt -lX11 -lm
#include <X11/GLw/GLwMDrawA.h>
ld ... -lGLw -lGL -lXm -lXext -lXt -lX11 -lm
GLwDrawingArea および
GLwMDrawingArea は
OpenGL の描画に使
えるウィジェットである。これらのウィジェットは、指定されたパラメータに
基づいて、OpenGL
で必要となる適切なビジュアルとカラーマップを持つ
ウィンドウを与える。
また、GLwDrawingArea と GLwMDrawingArea
は再描画・リサイズ・入力・
初期化のためのコールバックも与える。
GLwDrawingArea
はいかなるウィジェットセットの一部でもないが、Xt
だけに は依存する。
GLwDrawingArea
はどんなウィジェットセットと組み合わせても使える。
GLwMDrawingArea は GLwDrawingArea
とほぼ同じであるが、Motif
のウィジェットクラスである
XmPrimitive
のサブクラスであり、デフォルト
状態が Motif
に適したようになっている。例えば、GLwMDrawingArea
は Motif
のデフォルトの前景色と背景色をリソースに持ち、キーボードの移動も
よりうまく扱える。
GLwDrawingArea を Motif
のプログラムで使えるが、GLwMDrawingArea
を使う
方が推奨される。
GLwDrawingArea と GLwMDrawingArea
はほとんど同じ動作なので、この
オンラインマニュアルの残りの部分では、動作が異なる部分を除いて
GLwDrawingArea
だけを説明する。明示的に述べない限り、GLwDrawingArea
に
関する全ての説明は
GLwMDrawingArea
にも当てはまる。
GLwDrawingArea
を生成する時に与える情報の中でも、特に重要なのは
ビジュアルを決めるために必要な情報である。
これを与える方法は 3
つあり、そのいずれもリソース経由で行われる。
特定の visualInfo
構造体を渡すこともできる。
(この visualInfo
は既に別のところで取得していなければならない。
アプリケーションが行う
OpenGL の描画とこの visualInfo
の互換性を保証す
るのはアプリケーション設計者の責任である)。
別の方法として、属性リストを与えることもできる。この属性リストは、
直接 OpenGL
プログラミングを行う場合に使われるものと全く同じ書式である。
最後に、それぞれの属性を個別のリソースとして指定することもできる。
最後の方法が最も単純であり、リソースファイルから操作できる唯一の方法であ
る。
ビジュアルの割り当て以外にも、GLwDrawingArea
は
アプリケーションに割り当てられなければカラーマップの割り当ても行う
(カラーマップが割り当てられる場合、カラーマップとビジュアルの互換性を
保証するのはアプリケーション設計者の責任である。)
アプリケーションが同じビジュアルから複数個の
GLwDrawingAreas を生成す
る場合、同じカラーマップが使われる(ただし異なるアプリケーション間では
カラーマップは共有されない)。
ウィジェットを生成しても、ウィジェットがリアライズされるまではウィンドウ
は生成されない。したがってアプリケーションはウィンドウに対する
OpenGL
の操作をウィジェットの生成直後に行ってはならない。
アプリケーションはウィンドウがリアライズされるのを待たなければならない。
そこでこれに代わる方法として、ウィンドウが生成されたことを示す
ginit コールバック
を使ってもよい。このコールバックを受け取れば、アプリケーションは
そのウィンドウに対して全ての
OpenGL
初期化処理を行い、それからその他の
操作を行うことができる。初期化については後で詳しく説明する。
アプリケーションは
glXMakeCurrent または簡易関数
GLwDrawingAreaMakeCurrent
を使って、アクセスする
GLwDrawingArea を選択する。
GLwDrawingAreaMakeCurrent
はディスプレイとウィンドウの代わりに
ウィジェットを引き数に取る。
これらの関数は、GLwDrawingArea
が一つしかなければ一度だけ呼べばよいが、
複数の GLwDrawingArea
がある場合は、それぞれのコールバックの先頭で呼ば
なければならない。
ここで言うコールバックには、ウィジェット自身が与えるコールバックだけで
なく、GL
の動作に影響を与える全てのコールバック(タイムアウトや作業手続き等)
も含まれる。
アプリケーションがダブルバッファリングを使っている場合は、
glXSwapBuffers ではなく
GLwDrawingAreaSwapBuffers
を呼ぶとよい。
この関数を使うとディスプレイとウィンドウの代わりにウィジェットを指定す
ることができる。
GLwDrawingArea クラス¶
GLwDrawingArea は
Core
クラスから動作とリソースを継承する。
クラスポインタは
glwDrawingAreaWidgetClass である。
クラス名は
GLwDrawingArea
である。
GLwMDrawingArea クラス¶
GLwMDrawingArea は
XmPrimitive クラスと
Core クラスから
動作とリソースを継承する。
クラスポインタは
glwMDrawingAreaWidgetClass である。
クラス名は
GLwMDrawingArea
である。
新しいリソース¶
以下の表はプログラマがデータを指定するために使うウィジェットリソースを
定義する。プログラマは継承されたクラスに対してリソース値を設定して、
そのウィジェットの属性を設定してもよい。.Xdefaults
ファイル内で
リソースを名前またはクラスで参照するには、プレフィックス
GLwN お よび
GLwC
を取り、残った文字列を使うこと。
以下では 2
つの表を示す。最初の表には
glXChooseVisual が直接使う
属性に対応するリソースが示されている。
glXChooseVisual
の場合と同様、全ての
Boolean 型のリソースの
デフォルト値は FALSE
であり、全ての整数型リソースのデフォルト値は
0 で ある。ただし redSize,
greenSize, blueSize
は例外で、これらのデフォルト
値は 1
である。これらのリソースは生成時にのみ設定され、ビジュアルを
生成する時に使われる。
GLwNattribList リソースまたは
GLwNvisualInfo リソースが
設定されている場合は、これらのリソースは無視される。
これらのリソースの固有の意味は
glXChooseVisual の
オンラインマニュアルで説明されているので、ここでは説明しない。
. |
|
|
|
名前 |
クラス |
型 |
OpenGL 属性 |
GLwNbufferSize |
GLwCBufferSize |
int |
GLX_BUFFER_SIZE |
GLwNlevel |
GLwCLevel |
int |
GLX_LEVEL |
GLwNrgba |
GLwCRgba |
Boolean |
GLX_RGBA |
GLwNdoublebuffer |
GLwCDoublebuffer |
Boolean |
GLX_DOUBLEBUFFER |
GLwNstereo |
GLwCStereo |
Boolean |
GLX_STEREO |
GLwNauxBuffers |
GLwCAuxBuffers |
Boolean |
GLX_AUX_BUFFERS |
GLwNredSize |
GLwCColorSize |
int |
GLX_RED_SIZE |
GLwNgreenSize |
GLwCColorSize |
int |
GLX_GREEN_SIZE |
GLwNblueSize |
GLwCColorSize |
int |
GLX_BLUE_SIZE |
GLwNalphaSize |
GLwCAlphaSize |
int |
GLX_ALPHA_SIZE |
GLwNdepthSize |
GLwCDepthSize |
int |
GLX_DEPTH_SIZE |
GLwNstencilSize |
GLwCStencilSize |
int |
GLX_STENCIL_SIZE |
GLwNaccumRedSize |
GLwCAccumColorSize |
int |
GLX_ACCUM_RED_SIZE |
GLwNaccumGreenSize |
GLwCAccumColorSize |
int |
GLX_ACCUM_GREEN_SIZE |
GLwNaccumBlueSize |
GLwCAccumColorSize |
int |
GLX_ACCUM_BLUE_SIZE |
GLwNaccumAlphaSize |
GLwCAccumAlphaSize |
int |
GLX_ACCUM_ALPHA_SIZE |
以下の表は GLwDrawingArea
ウィジェットのその他のリソースを列挙したもの
である。それぞれについての詳しい説明は後で述べる。
「アクセス」カラムのコードの意味は以下の通りである:
指定されたリソースが生成時に設定される(
C)、
XtSetValues
を使って設定される(
S)、
XtGetValues
を使って取得される(
G)、 適用されない(
N/A)。
. |
|
|
|
|
名前 |
クラス |
型 |
初期値 |
アクセス |
|
GLwNallocateBackground |
GLwCAllocateColors |
Boolean |
F |
CG |
GLwNallocateOtherColors |
GLwCAllocateColors |
Boolean |
F |
CG |
GLwNattribList |
GLwCAttribList |
int * |
NULL |
CG |
GLwNexposeCallback |
GLwCCallback |
XtCallbackList |
NULL |
C |
GLwNginitCallback |
GLwCCallback |
XtCallbackList |
NULL |
C |
GLwNinputCallback |
GLwCCallback |
XtCallbackList |
NULL |
C |
GLwNinstallBackground |
GLwCInstallBackground |
Boolean |
T |
CG |
GLwNinstallColormap |
GLwCInstallColormap |
Boolean |
T |
CG |
GLwNresizeCallback |
GLwCCallback |
XtCallbackList |
NULL |
C |
GLwNvisualInfo |
GLwCVisualInfo |
XVisualInfo* |
NULL |
CG |
- GLwNallocateBackground
- TRUE
の場合、(そうすることが適切であれば)新しく計算されたカラーマップ
とビジュアルを用いて背景ピクセルとピックスマップが割り当てられる。
FALSE
の場合、親のカラーマップとビジュアルを使って計算された値がそのま
ま保持される。 X
に背景をクリアさせたいアプリケーションでは、普通はこの値を
TRUE にする。
背景を自分でクリアするアプリケーションではこの値を
FALSE にすることが
多いが、自分で使うために背景色を問い合わせる場合にはこの値を
TRUE に してもよい。
また、カラーマップを一つしかサポートしていないハードウェアでは、
OpenGL
のカラーマップとデフォルトの
X
のカラーマップの行き来で画面の
色が乱れるのを避けるために、アプリケーションは色をよく注意して割り当てる必
要があるかもしれない。
(注意: Xt
の動作の仕方のため、背景色は最初はデフォルトのカラーマップ
を使って計算される。このリソースが設定されていると、背景色は正しく
再計算できる。カラーマップが動的に計算されるのではなく、明示的に
ウィジェットに与えられた場合、これらのリソースは常にそのカラーマップを
使って計算される。)
- GLwNallocateOtherColors
- これは GLwNallocateBackground
に似ているが、
通常はウィジェットによって割り当てられる、その他の色を割り当てる。
GLwDrawingArea
ウィジェットおよび
GLwMDrawingArea
ウィジェットはこれら
の色を使わないが、アプリケーションは問い合わせることを選んでもよい。
非 Motif の GLwDrawingArea
ウィジェットの場合は、割り当てられる色が他に
ないので、このリソースは何もしない。Motif
の GLwMDrawingArea の場合は、
XmPrimitive resources XmNforeground, XmNhighlightColor,
XmNhighlightPixmap
が計算される。
- GLwNattribList
- glXChooseVisual
を呼ぶのに必要な属性のリストを持つ。
このリソースが NULL
の場合、これは属性関連リソースに基づいて計算される。
NULL
でない場合は、属性関連リソースは無視される。
- GLwNexposeCallback
- ウィジェットが露出イベントを受け取った時に呼び出されるコールバックの
リストを指定する。
コールバックの理由は
GLwCR_EXPOSE となる。
コールバック構造体も露出イベントを持っている。
アプリケーションは一般的には画面の再描画を行うとよい。
- GLwNginitCallback
- ウィジェットが最初にリアライズされた時に呼ばれるコールバックを指定する。
ウィジェットがリアライズされるまではどのような
OpenGL の操作も実行でき
ないので、このコールバックは
OpenGL
の適切な初期化を行うために使える
(コンテクストの生成など)。
- GLwNinputCallback
- ウィジェットがキーボードイベントまたはマウスイベントを受け取った時に
呼び出されるコールバックを指定する。デフォルトでは、入力コールバックは
キーの押したり離したりしたとき、マウスのボタンを押したり離したりしたと
き、ボタンを押しながらマウスを動かした時に毎回呼び出される。
ただし、この動作はトランスレーションテーブルを変えることにより変更できる。
このコールバック構造体は入力イベントも持つ。
このコールバックの理由は
GLwCR_INPUT となる。
-
- 入力コールバックはプログラミングを楽にするために与えられている。
というのも、これは全ての入力イベントを簡単に捕捉する方法を与えるからで
ある。しかし、モジュール化が進んだプログラムは、全てのコールバックを
個々に捕捉するのではなく、専用のアクションとトランスレーションを
アプリケーションで与えることにより実現できることが多い。
明示的にトランスレーションを指定することにより、さらにカスタマイズする
ことができる。
- GLwNinstallBackground
- TRUE
が設定されている場合、背景色がウィンドウにインストールされる。
FALSE
が設定されている場合、ウィンドウは背景色を持たない。
このリソースは
GLwNallocateBackground も TRUE
でなければ効果がない。
- GLwNinstallColormap
- TRUE
が設定されている場合、このウィンドウのシェルがフォーカスを得た時
に、ウィジェットは
XSetWMColormapWindows
を呼び出して
ウィンドウマネージャにカラーマップをインストールするように指示する。
複数の GLwDrawingAreas
で一つのカラーマップを共有しているアプリケーション
の場合、各々のカラーマップに対してただ一つだけの
GLwDrawingArea に
このリソースに TRUE
を設定するのが最も効率的である。
アプリケーションがカラーマップの順序についてさらに制御を必要とする場合
は、このリソースには
FALSE
を指定し、アプリケーションが明示的に
XSetWMColormapWindows
を呼び出すとよい。
- GLwNresizeCallback
- GLwDrawingArea
がリアライズされた時に呼び出されるコールバックのリスト
を指定する。
コールバックの理由は
GLwCR_RESIZE となる。
- GLwNvisualInfo
- ウィンドウのビジュアル情報構造体へのポインタを持つ。
この値が NULL
の場合、visualInfo
構造体はウィジェットの生成時に
GLwNattributeList
リソース(このリソース自身はさまざまなリソース
から計算される)に基づいて計算される。
GLwNvisualInfo が NULL
でなければ、 GLwNattributList
と
属性関連リソースは無視される。
継承されるリソース¶
GLwDrawingArea と GLwMDrawingArea
のいずれも、コアのスーパークラスから
動作とリソースを継承する。
前に述べたカラーマップと背景色リソースの動作を除き、全てのデフォルト値
はコアのものと同じである。
これに加えて、Motif 版の
GLwMDrawingArea は XmPrimitive
も継承している。
色リソースの動作については既に説明した。
このウィジェットでは
TraversalOn
リソースは無効にされているが、
キーボード入力が必要なら有効にすべきである(また、アプリケーションは
ウィジェット内でマウスのボタン
1 が押される度に
XmProcessTraversal(widget, XmTRAVERSE_CURRENT)
を呼ぶべきである。これは
Motif
の描画領域で必要なことと同様である)。
Motif
は一つのトップレベルシェルが複数個のビジュアルを持つと混乱するの
で、
XmNhighlightOnEnter
は無効にされており、
XmNhighlightThickness には 0
が設定されている。
コールバック情報¶
以下の構造体を指すポインタが各々のコールバックに渡される:
typedef struct
{
int reason;
XEvent *event;
Dimension width, height;
} GLwDrawingAreaCallbackStruct;
- reason
- コールバックが呼び出された理由を示す。
ここに入る値は、前述のリソースの説明で述べられている。
Motif プログラマの場合
GLwCR_EXPOSE, GLwCR_RESIZE, GLwCR_INPUT
は順に XmCR_EXPOSE, XmCR_RESIZE,
XmCR_INPUT と同等である。
GLwCR_GINIT
に相当するものは Motif
には存在しない。
- event
- コールバックを起こした
XEvent
を指すポインタである。
GLwNginitCallback と GLwNresizeCallback
の場合は NULL
となる。
- width および height
- ウィンドウの幅と高さが設定される。
トランスレーション¶
GLwDrawingArea
は以下のトランスレーションを持つ:
<KeyDown>: glwInput()
<KeyUp>: glwInput()
<BtnDown>: glwInput()
<BtnUp>: glwInput()
<BtnMotion>: glwInput()
GLwMDrawingArea
はさらに以下のトランスレーションを持つ:
<Key>osfHelp: PrimitiveHelp()
アプリケーションでデフォルト値以外のイベントを受け取りたければ、
別のトランスレーションテーブルをインストールすることで実現できる。
アクションルーチン¶
GLwDrawingArea
は以下のアクションルーチンを持つ:
- glwInput():
- 前述のトランスレーションのいずれかが入力が起きたことを示した場合に呼び
出される。
このアクションルーチンの唯一の目的は入力コールバックの呼び出しである。
初期化¶
ウィジェットが最初に生成された時(例えば
XtCreateWidget(3X) を使用)、
ウィジェットに対応するウィンドウは自動的には生成されない。
実際にはウィンドウの生成はウィジェットがリアライズするまで待たされる。
しかし、
glXchooseVisual
はすぐに呼ばれるので、その結果を元にした
情報は利用できる。
ウィジェット生成とリアライズの間は以下のようになる:
- •
- ウィンドウに対する
OpenGL
の操作はできない。
- •
- resize
コールバックは生成されない。
- •
- 通常のウィンドウは利用できない(XtWindow
は NULL を返す)。
- •
- GLwDrawingAreaMakeCurrent (および
glXMakeCurrent) を呼んで
はならない。
ウィジェットがリアライズすると、以下の動作が起きる:
- •
- ウィンドウが生成される。
- •
- ginit
コールバックが呼ばれる。
ユーザはこのコールバックを使って、必要な
OpenGL
の初期化をウィンドウに
対して行うとよい。
入力コールバックを使ってキーボード入力を受け取る場合、イベント内の
キーコードを KeySym
に変換しなければならない。
変換には
XLookupKeysym(3X)
または
XLookupString(3X) を使う
こと。
キーボード入力はトランスレーションでも扱える。こちらの場合には変換は
不要である。
Motif プログラマは、OSF
がキーの仮想割り当てを使っていて、いくつかの
キー割り当てを置き換えていることを意識しておくべきである。
一般的な例としては、(GL
プログラムでよくするように)ESC
キーを使って
プログラムを終了させる場合には、トランスレーションには
<key>Escape で なく <key>osfCancel
を指定すべきである。
Motif プログラマは、Motif
スタイルの
GLwCreateMDrawingArea
を使っ て GLwMDrawingArea
を生成してもよい。
使用例¶
GLwDrawingArea
ウィジェットを生成し、適切なコールバックを割り当てる
コードを一部抜粋して示す。
#include <stdlib.h>
#include <X11/GLw/GLwDrawA.h>
static GLXContext glx_context;
. . .
main()
{
Arg args[10];
int n;
Widget parent;
Widget glw;
. . .
n = 0;
XtSetArg(args[n], GLwNrgba, True); n++;
glw = XtCreateManagedWidget("glw", glwDrawingAreaWidgetClass,
parent, args, n);
XtAddCallback(glw, GLwNexposeCallback, exposeCB, NULL);
XtAddCallback(glw, GLwNresizeCallback, resizeCB, NULL);
XtAddCallback(glw, GLwNginitCallback, ginitCB, NULL);
. . .
}
static void
exposeCB(Widget w, XtPointer client_data,
GLwDrawingAreaCallbackStruct *call_data)
{
GLwDrawingAreaMakeCurrent(w, glx_context);
}
static void
resizeCB(Widget w, XtPointer client_data,
GLwDrawingAreaCallbackStruct *call_data)
{
GLwDrawingAreaMakeCurrent(w, glx_context);
}
static void
ginitCB(Widget w, XtPointer client_data,
GLwDrawingAreaCallbackStruct *call_data)
{
Arg args[1];
XVisualInfo *vi;
XtSetArg(args[0], GLwNvisualInfo, &vi);
XtGetValues(w, args, 1);
glx_context = glXCreateContext(XtDisplay(w), vi,
NULL, GL_FALSE);
GLwDrawingAreaMakeCurrent(w, glx_context);
}
Motif
プログラムで必要となる相違点は、
GLwDrawingArea.h ではなく
GLwMDrawingArea.h を使い、
GLwDrawingAreaWidgetClass 型でなく
GLwMDrawingAreaWidgetClass 型の
ウィジェットを生成することだけである。
これらを行う代わりに、Motif
プログラムでは
GLwCreateMDraw(3X) を
使ってもよい。
GLwDrawingArea
が既にリアライズされているウィジェットの子として生成さ
れた場合、GLwDrawingArea
は即座に生成され、ユーザには
ginit を
追加する機会が与えられない。このような場合には、初期化にはコールバック
を使わず、ウィジェット生成の直後に行うべきである。
非 Motif の GLwDrawingArea
ウィジェットを Motif
プログラムで使い、さら
にキーボードの遷移も行う場合には、ユーザが
GLwDrawingArea へ遷移した場
合の動作は未定義である。
関連項目¶
glXChooseVisual(3G),
GLwDrawingAreaMakeCurrent(3X),
glXMakeCurrent(3G),
GLwDrawingAreaSwapBuffers(3X)
GLwCreateMDraw(3X),
Core(3X),
XmPrimitive(3X),
VirtualBindings(3X),
XSetWMColormapWindows(3X11)
および OpenGL の仕様。