OpenGL绘制填充非凸边形

原创 2015年11月18日 21:53:24

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



版权声明:本文为博主原创文章,未经博主允许不得转载。

OpenGL-学习之路-不规则区域的填充算法

一. 简单递归的不规则区域填充
  • PatrickLin93
  • PatrickLin93
  • 2014年10月27日 22:48
  • 2877

OpenGL网格化回调函数问题解决方案

使用平台MFC 部分代码:     GLUtesselator* m_pTess; //1.2版本以上的OPENGL库的GLUtesselator     m_pTess = gluNewTes...
  • abcdef8c
  • abcdef8c
  • 2011年10月13日 23:32
  • 1242

OpenGL从1.0开始--填充区属性

和点属性和线属性一样,OpenGL也提供面的属性,我们称之为填充区属性。 简明扼要,我们先来看一个示例(代码借鉴于http://www.xuebuyuan.com/2205027.html) #i...
  • wudiliyao
  • wudiliyao
  • 2017年11月14日 20:45
  • 107

openGL画矩形并填充颜色的例子

  • 2012年06月17日 09:35
  • 16KB
  • 下载

OpenGL: 多边形分格化 和 gluTessCallback() 函数在c++中的使用方法

虽然在OpenGL中可以使用glBegin(GL_POLYGON)来画一个多边形,但是它只能实现简单的凸多边形。对于一些复杂的多边形,比如凹多边形,或者有实心有空心的多边形,OpenGL的glBegi...
  • jnleec
  • jnleec
  • 2012年11月02日 18:03
  • 1919

OpenGL: 填充非凸多边形

OpenGL多边形填充时默认为凸多边形void display() { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glBeg...
  • Augusdi
  • Augusdi
  • 2014年02月27日 09:51
  • 9030

opengl多边形的填充

  • 2013年06月03日 14:17
  • 304KB
  • 下载

openGL-边界填充

思路: 先将线框边界画出来,填充为白色。之后用glReadPixels函数得到某个像素点的颜色值。之后判断是否被填充过,或是否为边界颜色,如果没有被填充,就将其四个方向的像素点入栈再填充 ...
  • qq_33951440
  • qq_33951440
  • 2017年05月31日 19:37
  • 339

计算机图形学(二)输出图元_11_OpenGL多边形填充区函数(下)

多数图形软件包使用逼近平面片来显示曲面。这是因为平面方程是线性的,而处理线性方程比二次或其他类曲线方程快得多。因此OpenGL和其他图形软件包提供多边形图元来实施曲面的逼近。对象用多边形网络来建模,而...
  • heyuchang666
  • heyuchang666
  • 2016年05月21日 17:52
  • 4677

OpenGL-学习之路-不规则区域的填充算法

一. 简单递归的不规则区域填充
  • PatrickLin93
  • PatrickLin93
  • 2014年10月27日 22:48
  • 2877
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OpenGL绘制填充非凸边形
举报原因:
原因补充:

(最多只允许输入30个字)