OpenGL绘制凹多变形

参考:http://blog.csdn.net/jnleec/article/details/8141863

参考:http://www.songho.ca/opengl/gl_tessellation.html

http://m.blog.csdn.net/blog/sangni007/9040257

http://blog.csdn.net/wind_hzx/article/details/11830425

环境:windows8.1 ,vs2013

一、简介

OpenGL中认为合法的多边形必须是凸多边形,凹多边形、自交多边形、带孔的多边形等非凸的多边形在OpenGL中绘制会出现出乎意料的结果。例如,在大多数系统中,只有多边形的凸包被填充,而在有些系统中,并非所有的凸包都被填充。OpenGL之所以对合法多边形类型做出限制,是为了更方便地提供能够对符合条件的多边形进行快速渲染的硬件。简单多边形可被快速地渲染,而复杂多边形难以快速检测出来。为了最大限度的提高性能,OpenGL假定多边形是简单的。

二、凹多边形的绘制

虽然在OpenGL中可以使用glBegin(GL_POLYGON)来画一个多边形,但是它只能实现简单的凸多边形。对于一些复杂的多边形,比如凹多边形,或者有实心有空心的多边形,OpenGL的glBegin(GL_POLYGON)就不能满足需求了。

通常可以采用一种叫做"分格化"的方法来画复杂的多边形。非凸多边形最简单的填充方法最简单的应该是GLU 网格化对象GLUtesselator(GLUT库或者libTess库)。要用分格化的方法画多边形,步骤如下:

1. gluNewTess(); //创建一个新的分格化对象

2. gluTessCallback(); //注册回调函数,完成分格化的一些操作,照着写就行了。

3. gluTessProperty(); //设置一些分格化的属性值,如环绕数和环绕规则,用来确定多边形的内部和外部

4. gluTessBeginPolygon(); //开始画多边形

gluTessBeginContour(tessobj);//设置多边形的边线 1

gluTessEndContour(tessobj);//结束设置边线1

gluTessBeginContour(tessobj);//,如果有边线2,设置多边形的边线 2

gluTessEndContour(tessobj);//结束设置边线2

5.gluTessEdnPolygon(); //结束画多边形

6. gluDeleteTess(); //删除分格化对象

绘制代码如下:

void drawGraphics(int type)
{
	GLUtesselator * tessobj;
	tessobj = gluNewTess();
	//注册回调函数
	gluTessCallback(tessobj, GLU_TESS_VERTEX, (void (CALLBACK *)())vertexCallback);
	gluTessCallback(tessobj, GLU_TESS_BEGIN, (void (CALLBACK *)())beginCallback);
	gluTessCallback(tessobj, GLU_TESS_END, (void (CALLBACK *)())endCallback);
	gluTessCallback(tessobj, GLU_TESS_ERROR, (void (CALLBACK *)())errorCallback);

	//gluTessCallback(tessobj, GLU_TESS_COMBINE, (void (CALLBACK *)())combineCallback);//多边型边自相交的情况下回调用回调函数 

gluTessBeginPolygon(tessobj, NULL);
gluTessBeginContour(tessobj);//设置多边形的边线 	

gluTessVertex(tessobj, g_vertex[k][j], g_vertex[k][j]);

gluTessEndContour(tessobj);
gluTessEndPolygon(tessobj);

gluDeleteTess(tessobj);

}

回调函数:

//顶点的回调函数
void CALLBACK vertexCallback(GLvoid* vertex)
{
	GLdouble* pt;

	int numb;
	pt = (GLdouble*)vertex;

	glColor3f(0.8, 0.8, 0.8);

	glVertex3d(pt[0],pt[1],pt[2]);
}

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

void CALLBACK endCallback()
{
	glEnd();
}

void CALLBACK errorCallback(GLenum errorCode)
{
	const GLubyte * estring;
	//打印错误类型
	estring = gluErrorString(errorCode);
	fprintf(stderr, "Tessellation Error: %s/n", estring);
	exit(0);
}

三、思考

当然也可以利用回调函数记录分格化的顶点和绘制类型,然后利用数组的绘制函数进行一次性的绘制,以提高绘制效率。

时间: 2024-10-09 20:01:37

OpenGL绘制凹多变形的相关文章

OpenGl 绘制一个立方体

OpenGl 绘制一个立方体 为了绘制六个正方形,我们为每个正方形指定四个顶点,最终我们需要指定6*4=24个顶点.但是我们知道,一个立方体其实总共只有八个顶点,要指定24次,就意味着每个顶点其实重复使用了三次,这样可不是好的现象.最起码,像上面这样重复烦琐的代码,是很容易出错的.稍有不慎,即使相同的顶点也可能被指定成不同的顶点了. 如果我们定义一个数组,把八个顶点都放到数组里,然后每次指定顶点都使用指针,而不是使用直接的数据,这样就避免了在指定顶点时考虑大量的数据,于是减少了代码出错的可能性.

opengl绘制图片

#include <GL/glew.h>#include <glut.h>#include "FreeImage.h"#include <stdio.h> #include <malloc.h> #pragma comment(lib, "FreeImage.lib") GLuint texture; // Storage For One Texture ( NEW ) /*void loadTexture(){ FI

OpenGL绘制简单场景,实现旋转缩放平移和灯光效果

本项目实现了用OpenGL绘制一个简单场景,包含正方体.球体和网格,实现了物体的旋转.缩放.平移和灯光效果.附有项目完整代码,有详细注释.适合初学者熟悉opengl使用. 开发情况 开发环境VS2012+OpenGL 开发平台 Intel core i5,Intel HD Graphics Family 本项目实现了绘制一个场景(包括立方体.球体.网格),对各物体实现平移.旋转.缩放功能,添加了光源并简单设置了物体材质. 本项目示例代码下载(里面有详细注释) 感谢nehe的框架! 场景介绍 初始

OpenGL绘制棱锥,剔除

/** * 缓冲区工具类 */public class BufferUtil { /**  * 将浮点数组转换成字节缓冲区  */ public static ByteBuffer arr2ByteBuffer(float[] arr){  ByteBuffer ibb = ByteBuffer.allocateDirect(arr.length * 4);  ibb.order(ByteOrder.nativeOrder());  FloatBuffer fbb = ibb.asFloatBu

openGL绘制正方形

/** * 缓冲区工具类 */public class BufferUtil { /**  * 将浮点数组转换成字节缓冲区  */ public static ByteBuffer arr2ByteBuffer(float[] arr){  ByteBuffer ibb = ByteBuffer.allocateDirect(arr.length * 4);  ibb.order(ByteOrder.nativeOrder());  FloatBuffer fbb = ibb.asFloatBu

OpenGl绘制螺旋线

/** * 缓冲区工具类 */public class BufferUtil { /**  * 将浮点数组转换成字节缓冲区  */ public static ByteBuffer arr2ByteBuffer(float[] arr){  ByteBuffer ibb = ByteBuffer.allocateDirect(arr.length * 4);  ibb.order(ByteOrder.nativeOrder());  FloatBuffer fbb = ibb.asFloatBu

Opengl绘制计算几何库CGAL三角剖分结果的Demo

Ubuntu下改编了一个用CGAL计算输入点的三角剖分,并用OpenGL显示结果的C++程序. 该Demo可作为一个计算几何及绘图的框架. 代码如下: //编译命令:g++ spatial_sort.cpp -lglut -lGL -lGLU -lCGAL -lCGAL_Core -lgmp #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>   #include <CGAL/Triangulation_eucl

使用OpenGL绘制 shapefile文件 完成最基本的gis操作

主要内容概述 1.解析shapefile(.shp)文件.‘ 2.将经纬度数据按照墨卡托投进行投影(调用proj.4库)完成. 3.将数据用OpenGL的方式进行绘制. 上述3方面只是完成初步的绘制,对于要完成一个复杂的地理信息系统还有很大的差距, 下面介绍我设计的简单的地理信息框架(用于交流,进步).先上个图,根据图来说更加易懂. 其中地图框架中包含多个物理地理图层,是真实存在的图层,所有在该图层下的数据都会被绘制到图层上(即一张图片). 物理图层中包含了多个逻辑图层(Layer),是为了方便

OpenGL绘制一个三角形

应该建立一个vertex shader文件和一个pixel shader文件,分别命名为shader.vsh和shader.fsh. shader.vsh: attribute vec3 position; //入参,主程序会将数值传入 void main() { gl_Position = vec4(position,1); //顶点经过投影变换变换后的位置 } shader.fsh: void main() { gl_FragColor = vec4(0.5,0.5,0.5,1); //顶点