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”细分的原理以及细节解释的文章,有兴趣的朋友可以看一下。



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