書式
void gluTessCallback( GLUtesselator* tess,
GLenum which,
_GLUfuncptr CallBackFunc )
delim $$
引き数
- tess
- テセレーションオブジェクト(gluNewTess を使って作る) を指定する。
- which
- 定義するコールバックを指定する。 有効な値は次の通りである: GLU_TESS_BEGIN, GLU_TESS_BEGIN_DATA, GLU_TESS_EDGE_FLAG, GLU_TESS_EDGE_FLAG_DATA, GLU_TESS_VERTEX, GLU_TESS_VERTEX_DATA, GLU_TESS_END, GLU_TESS_END_DATA, GLU_TESS_COMBINE, GLU_TESS_COMBINE_DATA, GLU_TESS_ERROR, GLU_TESS_ERROR_DATA。
- CallBackFunc
- 呼び出される関数を指定する。
説明
gluTessCallback は、テセレーションオブジェクトが 使うコールバックを指示するために使う。 指定されたコールバックが既に定義されている場合、そのコールバックは 置き換えられる。 CallBackFunc が NULL ならば、現在あるコールバックは未定義の 状態にされる。これらのコールバックはテセレーションオブジェクトが使い、 ユーザが指定したポリゴンをどのように三角形分割するのかを 記述するために使われる。 それぞれのコールバックにはふたつのバージョンがある点に注意すること: ユーザが指定したポリゴンデータを受け取るものと受け取らないものである。 あるコールバックについて両方のバージョンが指定されている場合は、 ユーザが指定したポリゴンデータを受け取るバージョンの方が使われる。 一部の関数に使われる polygon_data 引き数は、 gluTessBeginPolygon が呼び出された時に指定されていたポインタの コピーである点に注意すること。 指定可能なコールバックは以下の通りである:
- GLU_TESS_BEGIN
-
開始コールバックは glBegin のように呼ばれ、(三角形)プリミティブ
の開始を示す。
この関数は GLenum 型の引き数をひとつ取る。
GLU_TESS_BOUNDARY_ONLY 属性に GL_FALSE が設定されてい
る場合は、引き数には GL_TRIANGLE_FAN,
GL_TRIANGLE_STRIP, GL_TRIANGLES
のいずれかが設定される。
GLU_TESS_BOUNDARY_ONLY 属性に GL_TRUE が設定されている
場合は、引き数には GL_LINE_LOOP が設定される。
このコールバックの関数プロトタイプを以下に示す:
- void begin ( GLenum type );
- GLU_TESS_BEGIN_DATA
-
GLU_TESS_BEGIN コールバックとほぼ同じであるが、ポインタ引き数
をひとつ多く取る点が異なる。
このポインタは gluTessBeginPolygon が呼ばれたときに与えられた
opaque なポインタと同一のものである。
このコールバックの関数プロトタイプを以下に示す:
- void beginData ( GLenum type, void *polygon_data );
- GLU_TESS_EDGE_FLAG
- 稜線フラグコールバックは glEdgeFlag に似ている。 この関数は真偽値をひとつ引き数として取り、この引き数はどの稜線が ポリゴンの境界上にあるのかを示す。 このフラグが GL_TRUE ならば、その後に続くそれぞれの頂点は ポリゴン境界上にある稜線を開始する。つまり、内部領域を外部領域と区別 する稜線を開始する。 このフラグが GL_FALSE ならば、その後に続くそれぞれの頂点は ポリゴン内部にある稜線を開始する。 稜線フラグコールバックは(もし定義されていれば)最初の頂点コールバックの 前に呼び出される。
-
三角形要素によるファン形状と三角形要素によるストリップ形状は稜線フラグ
に対応していないので、NULL でない稜線フラグコールバックが指定されている
場合にも開始コールバックは GL_TRIANGLE_FAN や
GL_TRIANGLE_STRIP を引き数に呼ばれることはない。
(このコールバックが NULL に初期化されていれば、性能への影響はない。)
その代わりに、ファン形状やストリップ形状は独立した三角形群に変換される。
このコールバックの関数プロトタイプを以下に示す:
- void edgeFlag ( GLboolean flag );
- GLU_TESS_EDGE_FLAG_DATA
-
GLU_TESS_EDGE_FLAG コールバックに似ているが、ポインタ引き数を
ひとつ多く取る点が異なる。
このポインタは gluTessBeginPolygon が呼ばれたときに与えられた
opaque なポインタと同一のものである。
このコールバックの関数プロトタイプを以下に示す:
- void edgeFlagData ( GLboolean flag, void *polygon_data );
- GLU_TESS_VERTEX
-
頂点コールバックは開始コールバックと終了コールバックの間で呼ばれる。
このコールバックは glVertex に似ており、テセレーション処理で
作られた三角形群の頂点を定義する。
この関数はポインタ引き数をひとつだけ取る。
このポインタは、頂点が記述された(gluTessVertex を参照)ときに
ユーザが指定した opaque なポインタと同一のものである。
このコールバックの関数プロトタイプを以下に示す:
- void vertex ( void *vertex_data );
- GLU_TESS_VERTEX_DATA
-
GLU_TESS_VERTEX コールバックとほぼ同じであるが、ポインタ引き数
をひとつ多く取る点が異なる。
このポインタは gluTessBeginPolygon が呼ばれたときに与えられた
opaque なポインタと同一のものである。
このコールバックの関数プロトタイプを以下に示す:
- void vertexData ( void *vertex_data, void *polygon_data );
- GLU_TESS_END
-
終了コールバックの用途は glEnd と同じである。
このコールバックはプリミティブの終わりを示し、引き数は取らない。
このコールバックの関数プロトタイプを以下に示す:
- void end ( void );
- GLU_TESS_END_DATA
-
GLU_TESS_END コールバックとほぼ同じであるが、ポインタ引き数
をひとつ多く取る点が異なる。
このポインタは gluTessBeginPolygon が呼ばれたときに与えられた
opaque なポインタと同一のものである。
このコールバックの関数プロトタイプを以下に示す:
- void endData ( void *polygon_data);
- GLU_TESS_COMBINE
-
結合コールバックは、テセレーションが干渉を検出した時や
形状特徴をマージしようとした時に、新しい頂点を作るために呼び出される。
この関数は次の 4 つの引き数を取る: GLdouble 型の要素 3 つの配列、
4 つのポインタの配列、GLfloat 型の要素 4 つの配列、ポインタへのポインタ
である。
関数プロトタイプを以下に示す:
-
void combine( GLdouble coords[3], void *vertex_data[4],
GLfloat weight[4], void **outData );
-
void combine( GLdouble coords[3], void *vertex_data[4],
- 頂点は、既存の 4 つまでの頂点の線形結合として定義される。 この頂点は vertex_data に格納される。 線形結合の係数は weight で与える。 この重み付けにおいては、係数の合計は必ず 1 でなければならない。 いくつかの重みの値が 0 であっても、頂点を指す全てのポインタは有効である。 coords は新しい頂点の座標を与える。
- ユーザは新しい頂点を割り当て、vertex_data と weight を 使ってパラメータを補間し、新しい頂点を指すポインタを outData に 返さなければならない。 この処理はレンダリングコールバックの間に与えられる。 gluTessEndPolygon が呼ばれてからしばらく後に メモリを解放するのはユーザの責任である。
-
例えば、ポリゴンが 3 次元空間内の任意の平面内にあり、
各頂点に色が割り当てられている場合には、GLU_TESS_COMBINE
コールバックは以下のようになる:
-
void myCombine( GLdouble coords[3], VERTEX *d[4],
GLfloat w[4], VERTEX **dataOut ) {
VERTEX *new = new_vertex();
new->x = coords[0];
new->y = coords[1];
new->z = coords[2];
new->r = w[0]*d[0]->r + w[1]*d[1]->r + w[2]*d[2]->r + w[3]*d[3]->r;
new->g = w[0]*d[0]->g + w[1]*d[1]->g + w[2]*d[2]->g + w[3]*d[3]->g;
new->b = w[0]*d[0]->b + w[1]*d[1]->b + w[2]*d[2]->b + w[3]*d[3]->b;
new->a = w[0]*d[0]->a + w[1]*d[1]->a + w[2]*d[2]->a + w[3]*d[3]->a;
*dataOut = new; }
-
void myCombine( GLdouble coords[3], VERTEX *d[4],
- テセレーション処理が干渉を見つけた場合には、GLU_TESS_COMBINE コールバックまたは GLU_TESS_COMBINE_DATA コールバック(後述)が 定義されていなければならず、さらにこのコールバックは NULL でない ポインタを dataOut に書き込まなければならない。 そうでない場合は、GLU_TESS_NEED_COMBINE_CALLBACK エラー が起こり、出力はまったく行われない。
-
GLU_TESS_COMBINE コールバックとほぼ同じであるが、ポインタ引き数
をひとつ多く取る点が異なる。
このポインタは gluTessBeginPolygon が呼ばれたときに与えられた
opaque なポインタと同一のものである。
このコールバックの関数プロトタイプを以下に示す:
-
void combineData ( GLdouble coords[3], void *vertex_data[4],
GLfloat weight[4], void **outData,
void *polygon_data );
-
void combineData ( GLdouble coords[3], void *vertex_data[4],
- GLU_TESS_ERROR
-
エラーコールバックはエラーが起きたときに呼び出される。
このコールバックは GLenum 型の引き数をひとつ取る。
この引き数は起こったエラーを示し、
GLU_TESS_MISSING_BEGIN_POLYGON, GLU_TESS_MISSING_END_POLYGON,
GLU_TESS_MISSING_BEGIN_CONTOUR, GLU_TESS_MISSING_END_CONTOUR,
GLU_TESS_COORD_TOO_LARGE, GLU_TESS_NEED_COMBINE_CALLBACK,
GLU_OUT_OF_MEMORY のいずれかが設定される。
これらのエラーを表す文字列は、gluErrorString の呼び出しで取得
できる。
このコールバックの関数プロトタイプを以下に示す:
- void error ( GLenum errno );
- GLU ライブラリは、足りない呼び出しを挿入することにより、 最初の 4 つのエラーからは復帰する。 GLU_TESS_COORD_TOO_LARGE は、座標の絶対値が 予め定義されている定数である GLU_TESS_MAX_COORD を超えている 頂点があり、その座標値が束縛を受けたことを示す。 (座標値は、ふたつの座標値を掛け合わせてもオーバーフローしない程度に 小さくなければならない。) GLU_TESS_NEED_COMBINE_CALLBACK は、テセレーション処理が 入力データ中のふたつの稜線の干渉が検出され、 GLU_TESS_COMBINE コールバックや GLU_TESS_COMBINE_DATA コールバックが与えられなかったことを示す。 この場合には出力はまったく行われない。 GLU_OUT_OF_MEMORY は、出力結果を生成するために必要なメモリが 不足していたことを示す。
- GLU_TESS_ERROR_DATA
-
GLU_TESS_ERROR コールバックとほぼ同じであるが、ポインタ引き数
をひとつ多く取る点が異なる。
このポインタは gluTessBeginPolygon が呼ばれたときに与えられた
opaque なポインタと同一のものである。
このコールバックの関数プロトタイプを以下に示す:
- void errorData ( GLenum errno, void *polygon_data );
使用例
テセレーション処理されたポリゴンは次のようにすると 直接レンダリングできる:
gluTessCallback(tobj, GLU_TESS_BEGIN, glBegin);
gluTessCallback(tobj, GLU_TESS_VERTEX, glVertex3dv);
gluTessCallback(tobj, GLU_TESS_END, glEnd);
gluTessCallback(tobj, GLU_TESS_COMBINE, myCombine);
gluTessBeginPolygon(tobj, NULL);
gluTessBeginContour(tobj);
gluTessVertex(tobj, v, v);
...
gluTessEndContour(tobj);
gluTessEndPolygon(tobj);
普通は、テセレーション処理で得たポリゴンはディスプレイリストに格納 すべきである。そうすれば、レンダリングするたびに毎回テセレーション処理 をやり直す必要がないからである。