OpenGL繪製填充非凸邊形

OpenGL沒有辦法直接繪製非凸多邊形,但是可以通過gluTessVertex()這種OpenGL的“細分”的方法對非凸多邊形進行繪製。具體原理是:

GLUtesselator, 能將任意多邊形,簡化爲三角形或凸多邊形的組合,從而使OpenGL能繪製出任意形狀的多邊形。

1. gluNewTess();                 //創建一個新的分格化對象
2. gluTessCallback();            //註冊回調函數,完成分格化的一些操作,照着寫就行了。
3. gluTessProperty();            //可有可無的,設置一些分格化的屬性值
4. gluTessBeginPolygon();        //開始畫多邊形
    draw polygon...              //在這裏畫多邊形,一個一個點畫就可以,最後一個點會和第一個點自動連接起來
    gluTessEdnPolygon();         //結束畫多邊形
5. gluDeleteTess();              //刪除分格化對象

但是實際操作過程中一定要注意一個問題:

多變形上的點要保證在gluTessEndPolygon()執行之前空間不被釋放,一般地,在開始gluTessBeginContour()之前多邊形的點就應該已經指定了!!!

否則會出現繪製不出圖像的現象,因爲OpenGL沒有讀取到點的信息。以下是我在MFC框架View中用OpenGL繪製任意多邊形的方法,大家有興趣的可以看一下。

void CALLBACK PolyLine3DBegin(GLenum type)
{
	glBegin(type);
}

void CALLBACK PolyLine3DVertex(GLdouble * vertex)
{
	const GLdouble *pointer = (GLdouble *)vertex;
	glColor3d(1.0, 0, 0);//在此設置顏色  
	glVertex3dv(pointer);
}

void CALLBACK PolyLine3DEnd()
{
	glEnd();
}
void DrawFloor(DataFloor* floor)
{
	if (!floor) return;
	std::vector<glm::vec3>& boundary_pts = *floor->GetBoundaryPtsToFloor();//這裏獲取點的座標

	size_t amount_pts = boundary_pts.size();
	if (amount_pts < 3)
		return;
	GLdouble(*quad)[3];
	quad = new GLdouble[amount_pts][3];//申請動態內存
	for (int i = 0; i < amount_pts; i++)//初始化所有的點到GLdouble(*quad)[3]中
	{
		glm::vec3 pt = boundary_pts.at(i);
		quad[i][0] = pt.x;
		quad[i][1] = pt.y;
		quad[i][2] = pt.z;
	}

	GLfloat curColor[4];
	glGetFloatv(GL_CURRENT_COLOR, curColor);
	glColor3ub((GLubyte)220, (GLubyte)220, (GLubyte)220);

	GLUtesselator* tess = gluNewTess();
	if (!tess) return;
	gluTessCallback(tess, GLU_TESS_BEGIN, (void (CALLBACK*)())&PolyLine3DBegin);
	gluTessCallback(tess, GLU_TESS_VERTEX, (void (CALLBACK*)())&PolyLine3DVertex);
	gluTessCallback(tess, GLU_TESS_END, (void (CALLBACK*)())&PolyLine3DEnd);
	gluTessBeginPolygon(tess, NULL);
	
	gluTessBeginContour(tess);
	for (int i = 0; i< amount_pts; i++)
	{//繪製Tess“細分”出的點
		gluTessVertex(tess, quad[i], quad[i]);

	}
	gluTessEndContour(tess);
	gluTessEndPolygon(tess);
	glColor3f(curColor[0], curColor[1], curColor[2]);
	delete[] quad;//釋放內存
}

效果如下:

之前我有轉載兩篇關於“Tess”細分的原理以及細節解釋的文章,有興趣的朋友可以看一下。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章