opengl polygon 三角剖分

2024-03-21 11:28
文章标签 polygon 剖分 opengl 三角

本文主要是介绍opengl polygon 三角剖分,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        固定管线时代的openGL可以使用GL_POLYGON来描画简单的凸多边形。但是无法直接描画凹的,带孔的或者自交的多边形。

        而非固定管线时代openGL3.*,openGL4.*,直接就没有了GL_POLYGON。

        不管是那种情况,都需要将多边形转化为三角形(三角形,三角带,三角扇)。我们很容易在网络上搜索到gluNewTess这个系列的函数,用来分割多边形。但是所有的例子都是在旧版本openGL下进行的,其实在这个系列函数在新版本openGL中仍然可以使用。现在开始正文,内容比较简单。

1.gluNewTess 创建一个tess对象

2.gluTessProperty 设置下环绕方向

3.gluTessCallback 设置回调函数(GLU_TESS_BEGIN,GLU_TESS_END,GLU_TESS_VERTEX等)

4.gluTessBeginPolygon,gluTessBeginContour,gluTessVertex等函数

以上部分参考网络上的例子。这里只说一下注意的地方。

多边形会被分割为多个面片,每个面片的BeginMode类型是不一样的,有可能是GL_TRIANGLE_STRIP或者GL_TRIANGLE_FAN。比如一个18个点的多边形,可能会被分割成3个面片:6个点组成的GL_TRIANGLE_STRIP,9个点组成的GL_TRIANGLE_FAN,9个点组成的GL_TRIANGLE_STRIP。(数组是我编的,但是a.分割不会创建新点,b.因为存在不同三角形共用点的情况,分割后的点数量大于分割前的。)

基于上面的讨论,我们需要获取每面片的BeginMode和点序列。相关代码如下:

1.

GLenum g_Type;
void CALLBACK beginCallback(GLenum which) 
{//glBegin(which);g_Type = which;
}

在GLU_TESS_BEGIN的回调函数中,取得BeginMode(BeginMode就是glBegin的参数。在新版openGL中,我们不使用glBegin系列函数来描画图形。所以这里不调用 glBegin.

2.

std::vector<vec3 > g_vecPoint3D;
void CALLBACK vetexCallback(GLdouble * vertex)
{g_vecPoint3D.push_back(vec3(vertex[0], vertex[1], vertex[2]));
}

在GLU_TESS_VERTEX的回调函数中,取得分割后的坐标。

3.

std::vector<std::pair<GLenum, std::vector<vec3>>> g_vecvecPoint3D;
void CALLBACK endCallback(void)
{//glEnd(which);g_vecvecPoint3D.push_back(std::make_pair(g_Type, g_vecPoint3D));g_vecPoint3D.clear();
}

如果进入了GLU_TESS_END的回调函数,标志着一个分割后的面片已经结束了。此时,我们已获得的坐标点就是一个面片的所有坐标点。将beginMode和坐标一起存起来。(std::make_pair(g_Type, g_vecPoint3D))

4.重复1,2,3,得到每个面片的beginMode和坐标列。

这样一来,polygon就分割完成了。可以描画数据或者将数据存起来。

====================================

如果注册了GLU_TESS_ERROR回调函数,以下是错误码。

/* TessError */
#define GLU_TESS_ERROR1     100151
#define GLU_TESS_ERROR2     100152
#define GLU_TESS_ERROR3     100153
#define GLU_TESS_ERROR4     100154
#define GLU_TESS_ERROR5     100155
#define GLU_TESS_ERROR6     100156
#define GLU_TESS_ERROR7     100157
#define GLU_TESS_ERROR8     100158#define GLU_TESS_MISSING_BEGIN_POLYGON  GLU_TESS_ERROR1
#define GLU_TESS_MISSING_BEGIN_CONTOUR  GLU_TESS_ERROR2
#define GLU_TESS_MISSING_END_POLYGON    GLU_TESS_ERROR3
#define GLU_TESS_MISSING_END_CONTOUR    GLU_TESS_ERROR4
#define GLU_TESS_COORD_TOO_LARGE        GLU_TESS_ERROR5
#define GLU_TESS_NEED_COMBINE_CALLBACK  GLU_TESS_ERROR6

===============================

其他的分割方法:

1.earcut算法,https://github.com/mapbox/earcut.hpp

支持多种语言,按官方的描述就是快.只需要一个头文件。官网写着需要openGL SDK.

由于算法的原因,会产生很不"完美的三角形",比如2个角度很小的锐角和1个大钝角,这可能不是你想要的。只支持2d,3D场合需要先将图形拍扁。但是由于会产生不完美的三角形,转回3D后的效果,和你想的可能相差很大。

不过以上只是推测,不负任何责任。

2.CGAL 

打开网站,看一眼目录,你就能感觉到这个库很强大。

这篇关于opengl polygon 三角剖分的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/832530

相关文章

POLYGON Horror Carnival - Low Poly 3D Art by Synty

465 个独特的预设模型 一个正在运行的摩天轮和旋转木马 包括10个示例脚本,让嘉年华栩栩如生 ◼ 描述◼ 欢迎来到恐怖嘉年华。这个地方曾经有诱人的音乐,现在却有着令人不安的旋律,暗示着其中令人不安的惊喜。 这场险恶的盛会的真正核心在于演示场景。它使用3D低多边形资源构建,具有来自不祥的狂欢帐篷、摊位、摩天轮、旋转木马等游戏开发资源。它是疯狂人物与毫无戒心的寻求刺激者玩捉迷藏游戏的完美狩猎场。

SPOJ - QTREE (树链剖分)

基础的树链剖分题目,不过是边权,可以向下映射成点权或者按边剖分。 VIEW CODE #include <iostream>#include<stdio.h>#include<cmath>#include<string.h>#include<algorithm>#include<string>using namespace std;const int mmax=100

OpenGL-ES 学习(6)---- 立方体绘制

目录 立方体绘制基本原理立方体的顶点坐标和绘制顺序立方体颜色和着色器实现效果和参考代码 立方体绘制基本原理 一个立方体是由8个顶点组成,共6个面,所以绘制立方体本质上就是绘制这6个面共12个三角形 顶点的坐标体系如下图所示,三维坐标的中心原点位于立方体的中心,但是要特别注意的是,前后方向表示的是Z轴,上下方向表示的是Y轴 立方体的顶点坐标和绘制顺序 立方体坐标定义

OpenGL:中点直线算法

理论部分 中点直线算法是通过在像素中确定与理想直线最靠近的像素来进行扫描转换的。 在上图中,假设直线的斜率 0 ≤ m ≤ 1 0\le m \le 1 0≤m≤1。假设当前最近的像素已经确认为 P ( x k , y k ) P(x_k, y_k) P(xk​,yk​),由于 x x x位最大的位移方向,因此直线在 x x x方向上每次增加一个像素单位,而在 y y y方向上是否

OpenGL学习笔记(二十九)

目录 模板测试 模板测试 当片段着色器处理完一个片段之后,模板测试(Stencil Test)会开始执行,和深度测试一样,它也可能会丢弃片段。接下来,被保留的片段会进入深度测试,它可能会丢弃更多的片段。模板测试是根据又一个缓冲来进行的,它叫做模板缓冲(Stencil Buffer)。

OpenGL学习笔记(二十八)

目录 面剔除 面剔除 一个3D立方体,从任何一个方向去看它,最多可以同时看到的面是3个。可以从一个立方体的任意位置和方向上去看它,但是永远不能看到多于3个面。所以为何还要去绘制那三个不会显示出来的3个面呢。如果可以以某种方式丢弃它们,会提高片段着色器超过50%的性能,这就是面剔除要做的事情。

OpenGL学习笔记(二十七)

目录 混合 混合 在OpenGL中,物体透明技术通常被叫做混合(Blending)。透明是物体(或物体的一部分)非纯色而是混合色,这种颜色来自于不同浓度的自身颜色和它后面的物体颜色。一个有色玻璃窗就是一种透明物体,玻璃有自身的颜色,但是最终的颜色包含了所有玻璃后面的颜色。这也正是混合这名称的出处,因为我们将多种(来自于不同物体)颜色混合为一个颜色,透明使得我们可以看穿物体。

OpenGL学习笔记(二十六)

目录 模板测试 模板测试 当片段着色器处理完片段之后,模板测试(Stencil Test) 就开始执行了,和深度测试一样,它能丢弃一些片段。仍然保留下来的片段进入深度测试阶段,深度测试可能丢弃更多。模板测试基于另一个缓冲,这个缓冲叫做模板缓冲(Stencil Buffer),我们被允许在渲染时更新它来获取有意思的效果。 模板缓冲中的模板值(Stencil Value)通常是

OpenGL学习笔记(二十五)

目录 EarlyZ EarlyZ 现在大多数 GPU 都支持一种称为提前深度测试(Early depth testing)的硬件功能。 提前深度测试允许深度测试在片段着色器之前运行。明确一个片段永远不会可见的 (它是其它物体的后面) 。 片段着色器通常是相当费时的所以应该尽量避免运行。 对片段着色器提前深度测试一个限制是,你不应该写入片段的深度值。如果片段着色器将写入其

OpenGL学习笔记(二十三)

目录 颜色 颜色 现实世界中有无数种颜色,每一个物体都有它们自己的颜色。我们要做的工作是使用(有限的)数字来模拟真实世界中(无限)的颜色,因此并不是所有的现实世界中的颜色都可以用数字来表示。然而我们依然可以用数字来代表许多种颜色,并且你甚至可能根本感觉不到他们与真实颜色之间的差异。颜色可以数字化的由红色(Red)、绿色(Green)和蓝色(Blue)三个分量组成,它们通常被缩