境界のマーキング


凸型と非凸型

実は、OpenGL のポリゴンは凸型のポリゴンしか表示することができません
GL_POLYGON で描画する時に、穴の開いたポリゴンや凹んだポリゴンは表示できないのです

そのため、三角形や四角形などのポリゴンは有効ですが
中央に穴の開いたポリゴンや、アルファベットの M のような形は描画できないことになります
このような複雑なポリゴンを作るには、複数の単純な凸型ポリゴンを組み合わせるのです

通常、複雑なポリゴンの描画は複数個の三角形で構成します
しかし、複数の三角形で複雑なポリゴンを構成する場合、一部の辺が図の内部に埋もれます
これでは境界線がどこにあるのかわかりません
そこで、非凸型ポリゴンを作るには glEdgeFlag() 関数を使って
頂点がポリゴンの境界辺の開始点となるかどうかを指定することができます

void glEdgeFlag(GLboolean flag);
void glEdgeFlagv(const GLboolean * flag);

flag が GL_TRUE を表すなら、その頂点は境界辺の開始点であることをあらわします
デフォルトではすべての頂点が境界辺の開始点となります

この関数に GL_TRUE を渡した後の頂点は、境界辺の開始点であると判断され
GL_FALSE を渡した後の頂点は、境界辺の開始点ではないと判断されます
この状態値を エッジフラグと呼んでいます

glEdgeFlag() 関数は、glBegin() と glEnd() の間でも呼び出すことができます
それ以外の場所でも呼び出すことができるため、事実上、常にエッジフラグを変更できます
#include <windows.h>
#include <GL/gl.h>
#include <GL/glut.h>

void disp( void ) {
	glClear(GL_COLOR_BUFFER_BIT);

	glBegin(GL_POLYGON);
		glEdgeFlag(GL_TRUE); glVertex2f(-0.9 , -0.5);
		glEdgeFlag(GL_TRUE); glVertex2f(-0.85 , 0.9);
		glEdgeFlag(GL_FALSE);glVertex2f(0 , 0.3);

		glEdgeFlag(GL_TRUE); glVertex2f(-0.9 , -0.5);
		glEdgeFlag(GL_FALSE);glVertex2f(0.9 , -0.5);
		glEdgeFlag(GL_TRUE); glVertex2f(0 , 0.3);

		glEdgeFlag(GL_TRUE); glVertex2f(0.85 , 0.9);
		glEdgeFlag(GL_FALSE);glVertex2f(0.9 , -0.5);		
		glEdgeFlag(GL_FALSE);glVertex2f(0 , 0.3);
	glEnd();	

	glFlush();
}

int main(int argc , char ** argv) {
	glutInit(&argc , argv);
	glutInitWindowPosition(100 , 50);
	glutInitWindowSize(400 , 300);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);

	glutCreateWindow("Kitty on your lap");
	glutDisplayFunc(disp);

	glutMainLoop();
	return 0;
}


上の図は、エッジフラグの設定を行うことで実現した非凸型のポリゴンです
この図形には、3 つ三角形が隠されていることに気づいてください
頂点に色をつけるなどをすれば、3 つの三角形がはっきりと見えるでしょう



前のページへ戻る次のページへ