diff --git a/thirdparty/libtess2/HPKBUILD b/thirdparty/libtess2/HPKBUILD new file mode 100644 index 0000000000000000000000000000000000000000..6fce20c328682915e220ed60965ed121794843c4 --- /dev/null +++ b/thirdparty/libtess2/HPKBUILD @@ -0,0 +1,84 @@ +# Contributor: 小肉头君 +# Maintainer: 小肉头君 + +pkgname=libtess2 +pkgver=v1.0.2 +pkgrel=0 +pkgdesc="Game and tools oriented refactored version of GLU tesselator." +url="https://github.com/memononen/libtess2" +archs=("armeabi-v7a" "arm64-v8a") +license=("SGI FREE SOFTWARE LICENSE B") +depends=() +makedepends=("premake4") +install= +source="https://github.com/memononen/$pkgname/archive/refs/tags/$pkgver.tar.gz" + +downloadpackage=true +patchflag=true +buildtools="make" + +builddir=$pkgname-${pkgver:1} +packagename=$builddir.tar.gz + +cc= +prepare() { + if $patchflag + then + cd $builddir + # 本库example依赖gl相关套件,ohos暂不支持 + # 所以打patch修改example源码,注释gl相关代码,只是进行example的计算(源库是一个算法库),不涉及gl的显示 + # 修改premake4.lua,让example不依赖gl相关套件 + patch -p1 < `pwd`/../libtess2_oh_pkg.patch + # patch只需要打一次,关闭打patch + patchflag=false + cd $OLDPWD + fi + cp -rf $builddir $builddir-$ARCH-build + if [ $ARCH == "armeabi-v7a" ] + then + cc=${OHOS_SDK}/native/llvm/bin/arm-linux-ohos-clang + fi + if [ $ARCH == "arm64-v8a" ] + then + cc=${OHOS_SDK}/native/llvm/bin/aarch64-linux-ohos-clang + fi +} + +build() { + cd $builddir-$ARCH-build + premake4 gmake > `pwd`/build.log 2>&1 + cd $OLDPWD + cd $builddir-$ARCH-build/Build + make CC=${cc} -j4 > `pwd`/build.log 2>&1 + # 对最关键一步的退出码进行判断 + ret=$? + cd $OLDPWD + return $ret +} + +# 安装打包 +package() { + cd $builddir-$ARCH-build + # 源库Makefile 没有make install,这里手动copy到usr目录 + mkdir -p $LYCIUM_ROOT/usr/$pkgname/$ARCH/include/ + mkdir -p $LYCIUM_ROOT/usr/$pkgname/$ARCH/lib/ + cp Source/*.h Include/*.h $LYCIUM_ROOT/usr/$pkgname/$ARCH/include/ + cp Build/libtess2.a $LYCIUM_ROOT/usr/$pkgname/$ARCH/lib/ + cd $OLDPWD + unset cc +} + +# 测试,需要在 ohos 设备上进行 +check() { + echo "The test must be on an OpenHarmony device!" + # ./example + # loading... + # go... + # view0: -34.327606 + # view1: 377.603638 +} + +# 清理环境 +cleanbuild(){ + rm -rf ${PWD}/$builddir $builddir-armeabi-v7a-build $builddir-arm64-v8a-build #${PWD}/$packagename +} \ No newline at end of file diff --git a/thirdparty/libtess2/README.OpenSource b/thirdparty/libtess2/README.OpenSource new file mode 100644 index 0000000000000000000000000000000000000000..01cfd9c16316da5c14e8390bbb47957bcce49584 --- /dev/null +++ b/thirdparty/libtess2/README.OpenSource @@ -0,0 +1,11 @@ +[ + { + "Name": "libtess2", + "License": "SGI FREE SOFTWARE LICENSE B", + "License File": "LICENSE.txt", + "Version Number": "v1.0.2",: + "Owner": "chenbaodi@huawei.com", + "Upstream URL": "https://github.com/memononen/libtess2/archive/refs/tags/v1.0.2.tar.gz", + "Description": "Game and tools oriented refactored version of GLU tesselator." + } +] diff --git a/thirdparty/libtess2/README_zh.md b/thirdparty/libtess2/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..bfce4c519c53ccc1c92dfdcf46c1d833d96ec2f4 --- /dev/null +++ b/thirdparty/libtess2/README_zh.md @@ -0,0 +1,12 @@ +# libtess2三方库说明 +## 功能简介 +libtess2 可以对复杂多边形进行曲面细分。 +## 使用约束 +- IDE版本:DevEco Studio 3.1 Release +- SDK版本:ohos_sdk_public 3.2.11.9 (API Version 9 Release) +- 三方库版本:1.3.1 +- 当前适配的功能:支持对复杂多边形进行曲面细分 +- [SGI FREE SOFTWARE LICENSE B](https://github.com/memononen/libtess2/blob/master/LICENSE.txt) + +## 集成方式 ++ [应用hap包集成](docs/hap_integrate.md) diff --git a/thirdparty/libtess2/SHA512SUM b/thirdparty/libtess2/SHA512SUM new file mode 100644 index 0000000000000000000000000000000000000000..f5650c64ab7762a267cddeb3ea4c55721206ac21 --- /dev/null +++ b/thirdparty/libtess2/SHA512SUM @@ -0,0 +1 @@ +c2b3385c0c54f2f38a01f757c89ae32152f01cc1615a3857a002a1928b0fa1b5344a778de73ef0b53c2131adbf0c3918935ac38781dceefb5daa97cfac8ba231 libtess2-1.0.2.tar.gz diff --git a/thirdparty/libtess2/docs/hap_integrate.md b/thirdparty/libtess2/docs/hap_integrate.md new file mode 100644 index 0000000000000000000000000000000000000000..76eb46236b5ce3849ac01f20040173a0d055ddfe --- /dev/null +++ b/thirdparty/libtess2/docs/hap_integrate.md @@ -0,0 +1,91 @@ +# libtess2 集成到应用hap + +本库是在RK3568开发板上基于OpenHarmony3.2 Release版本的镜像验证的,如果是从未使用过RK3568,可以先查看[润和RK3568开发板标准系统快速上手](https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/docs/rk3568_helloworld)。 + +## 开发环境 + +- ubuntu20.04 +- [OpenHarmony3.2Release镜像](https://gitee.com/link?target=https%3A%2F%2Frepo.huaweicloud.com%2Fopenharmony%2Fos%2F3.2-Release%2Fdayu200_standard_arm32.tar.gz) +- [ohos_sdk_public 3.2.11.9 (API Version 9 Release)](https://gitee.com/link?target=https%3A%2F%2Frepo.huaweicloud.com%2Fopenharmony%2Fos%2F3.2-Release%2Fohos-sdk-windows_linux-public.tar.gz) +- [DevEco Studio 3.1 Beta2](https://gitee.com/link?target=https%3A%2F%2Fcontentcenter-vali-drcn.dbankcdn.cn%2Fpvt_2%2FDeveloperAlliance_package_901_9%2Ff3%2Fv3%2FuJyuq3syQ2ak4hE1QZmAug%2Fdevecostudio-windows-3.1.0.400.zip%3FHW-CC-KV%3DV1%26HW-CC-Date%3D20230408T013335Z%26HW-CC-Expire%3D315360000%26HW-CC-Sign%3D96262721EDC9B34E6F62E66884AB7AE2A94C2A7B8C28D6F7FC891F46EB211A70) +- [准备三方库构建环境](../../../tools/README.md#编译环境准备) +- [准备三方库测试环境](../../../tools/README.md#ci环境准备) + +## 编译三方库 + +- 下载本仓库 + + ```shell + git clone https://gitee.com/openharmony-sig/tpc_c_cplusplus.git --depth=1 + ``` + +- 三方库目录结构 + + ```shell + tpc_c_cplusplus/thirdparty/libtess2 #三方库libtess2的目录结构如下 + ├── docs #三方库相关文档的文件夹 + ├── HPKBUILD #构建脚本 + ├── SHA512SUM #三方库校验文件 + ├── README.OpenSource #说明三方库源码的下载地址,版本,license等信息 + ├── README_zh.md + ├── libtess2_oh_pkg.patch + ``` + +- 将libtess2拷贝至tools/main目录下 + + ```shell + cd tpc_c_cplusplus + cp thirdparty/libtess2 tools/main -rf + ``` + +- 在tools目录下编译三方库 + + 编译环境的搭建参考[准备三方库构建环境](../../../tools/README.md#编译环境准备) + + ```shell + cd tools + ./build.sh libtess2 + ``` + +- 三方库头文件及生成的库 + + 在tools目录下会生成usr目录,该目录下存在已编译完成的32位和64位三方库 + + ```shell + libtess2/arm64-v8a libtess2/armeabi-v7a + ``` + +- [测试三方库](#测试三方库) + +## 应用中使用三方库 + +- 在IDE的cpp目录下新增thirdparty目录,将编译生成的库拷贝到该目录下,如下图所示 +   + + ![thirdparty_install_dir](pic/libtess2_install_dir.png) + +- 在最外层(cpp目录下)CMakeLists.txt中添加如下语句 + + ```shell + #将三方库加入工程中 + target_link_libraries(entry PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/libtess2/${OHOS_ARCH}/lib/libtess2.a) + #将三方库的头文件加入工程中 + target_include_directories(entry PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/libtess2/${OHOS_ARCH}/include) + ``` + + ![libtess2_usage](pic/libtess2_usage.png) + +## 测试三方库 + +三方库的测试使用原库自带的可执行文件来做测试 + +进入到构建目录,再进入tools目录,执行./example(arm64-v8a-build为构建64位的目录,armeabi-v7a-build为构建32位的目录) + + ![libtess2_test](pic/libtess2_test.png) + +## 参考资料 + +- [润和RK3568开发板标准系统快速上手](https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/docs/rk3568_helloworld) +- [OpenHarmony三方库地址](https://gitee.com/openharmony-tpc) +- [OpenHarmony知识体系](https://gitee.com/openharmony-sig/knowledge) +- [通过DevEco Studio开发一个NAPI工程](https://gitee.com/openharmony-sig/knowledge_demo_temp/blob/master/docs/napi_study/docs/hello_napi.md) \ No newline at end of file diff --git a/thirdparty/libtess2/docs/pic/libtess2_install_dir.png b/thirdparty/libtess2/docs/pic/libtess2_install_dir.png new file mode 100644 index 0000000000000000000000000000000000000000..acafb7b6b55b7d3ad2ae7a9944809295807bbb2e Binary files /dev/null and b/thirdparty/libtess2/docs/pic/libtess2_install_dir.png differ diff --git a/thirdparty/libtess2/docs/pic/libtess2_test.png b/thirdparty/libtess2/docs/pic/libtess2_test.png new file mode 100644 index 0000000000000000000000000000000000000000..2a7986c9e85013dcf97d513118c683a52d1bb55d Binary files /dev/null and b/thirdparty/libtess2/docs/pic/libtess2_test.png differ diff --git a/thirdparty/libtess2/docs/pic/libtess2_usage.png b/thirdparty/libtess2/docs/pic/libtess2_usage.png new file mode 100644 index 0000000000000000000000000000000000000000..a49a7e3810f6f32db867977f6aed1cd617c1b34e Binary files /dev/null and b/thirdparty/libtess2/docs/pic/libtess2_usage.png differ diff --git a/thirdparty/libtess2/libtess2_oh_pkg.patch b/thirdparty/libtess2/libtess2_oh_pkg.patch new file mode 100644 index 0000000000000000000000000000000000000000..d1d6a6f5a80d2598a032b81af193f0d22540d559 --- /dev/null +++ b/thirdparty/libtess2/libtess2_oh_pkg.patch @@ -0,0 +1,532 @@ +diff -Naur libtess2-1.0.2-old/Example/example.c libtess2-1.0.2-diff/Example/example.c +--- libtess2-1.0.2-old/Example/example.c 2023-05-09 09:05:10.003166275 +0800 ++++ libtess2-1.0.2-diff/Example/example.c 2023-05-09 09:51:02.808161326 +0800 +@@ -3,7 +3,7 @@ + #include + #include + #include +-#include ++//#include + #include "nanosvg.h" + #include "tesselator.h" + +@@ -52,28 +52,28 @@ + + + // Undefine this to see non-interactive heap allocator version. +-#define USE_POOL 1 ++#define USE_POOL 0 + + + int run = 1; + int cdt = 0; + +-static void key(GLFWwindow* window, int key, int scancode, int action, int mods) +-{ +- TESS_NOTUSED(scancode); +- TESS_NOTUSED(mods); +- if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) +- glfwSetWindowShouldClose(window, GL_TRUE); +- if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) +- run = !run; +- if (key == GLFW_KEY_C && action == GLFW_PRESS) +- cdt = !cdt; +-} ++//static void key(GLFWwindow* window, int key, int scancode, int action, int mods) ++//{ ++// TESS_NOTUSED(scancode); ++// TESS_NOTUSED(mods); ++// if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) ++// glfwSetWindowShouldClose(window, GL_TRUE); ++// if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) ++// run = !run; ++// if (key == GLFW_KEY_C && action == GLFW_PRESS) ++// cdt = !cdt; ++//} + + int main(int argc, char *argv[]) + { +- GLFWwindow* window; +- const GLFWvidmode* mode; ++// GLFWwindow* window; ++// const GLFWvidmode* mode; + int width,height,i,j; + struct SVGPath* bg; + struct SVGPath* fg; +@@ -84,21 +84,21 @@ + TESStesselator* tess = 0; + const int nvp = 3; + unsigned char* vflags = 0; +-#ifdef USE_POOL +- struct MemPool pool; +- unsigned char mem[1024*1024]; +- int nvflags = 0; +-#else ++//#ifdef USE_POOL ++// struct MemPool pool; ++// unsigned char mem[1024*1024]; ++// int nvflags = 0; ++//#else + int allocated = 0; + double t0 = 0, t1 = 0; +-#endif +- TESS_NOTUSED(argc); +- TESS_NOTUSED(argv); +- +- if (!glfwInit()) { +- printf("Failed to init GLFW."); +- return -1; +- } ++//#endif ++ TESS_NOTUSED(argc); ++ TESS_NOTUSED(argv); ++ ++// if (!glfwInit()) { ++// printf("Failed to init GLFW."); ++// return -1; ++// } + + printf("loading...\n"); + // Load assets +@@ -159,20 +159,20 @@ + } + } + +-#ifdef USE_POOL +- +- pool.size = 0; +- pool.cap = sizeof(mem); +- pool.buf = mem; +- memset(&ma, 0, sizeof(ma)); +- ma.memalloc = poolAlloc; +- ma.memfree = poolFree; +- ma.userData = (void*)&pool; +- ma.extraVertices = 256; // realloc not provided, allow 256 extra vertices. ++//#ifdef USE_POOL ++// ++// pool.size = 0; ++// pool.cap = sizeof(mem); ++// pool.buf = mem; ++// memset(&ma, 0, sizeof(ma)); ++// ma.memalloc = poolAlloc; ++// ma.memfree = poolFree; ++// ma.userData = (void*)&pool; ++// ma.extraVertices = 256; // realloc not provided, allow 256 extra vertices. ++// ++//#else + +-#else +- +- t0 = glfwGetTime(); ++// t0 = glfwGetTime(); + + memset(&ma, 0, sizeof(ma)); + ma.memalloc = stdAlloc; +@@ -206,26 +206,26 @@ + if (!tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_POLYGONS, nvp, 2, 0)) + return -1; + +- t1 = glfwGetTime(); +- +- printf("Time: %.3f ms\n", (t1 - t0) * 1000.0f); +- printf("Memory used: %.1f kB\n", allocated/1024.0f); ++// t1 = glfwGetTime(); ++// ++// printf("Time: %.3f ms\n", (t1 - t0) * 1000.0f); ++// printf("Memory used: %.1f kB\n", allocated/1024.0f); ++ ++//#endif ++ ++// mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); ++// width = mode->width - 40; ++// height = mode->height - 80; ++// window = glfwCreateWindow(width, height, "Libtess2 Demo", NULL, NULL); ++// if (!window) { ++// glfwTerminate(); ++// return -1; ++// } + +-#endif ++// glfwSetKeyCallback(window, key); ++// glfwMakeContextCurrent(window); + +- mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); +- width = mode->width - 40; +- height = mode->height - 80; +- window = glfwCreateWindow(width, height, "Libtess2 Demo", NULL, NULL); +- if (!window) { +- glfwTerminate(); +- return -1; +- } +- +- glfwSetKeyCallback(window, key); +- glfwMakeContextCurrent(window); +- +- // Adjust bounds so that we get nice view of the bg. ++ // Adjust bounds so that we get nice view of the bg. + cx = (bounds[0]+bounds[2])/2; + cy = (bounds[3]+bounds[1])/2; + w = (bounds[2]-bounds[0])/2; +@@ -233,176 +233,178 @@ + view[2] = cx + w*1.2f; + view[1] = cy - w*1.2f*(float)height/(float)width; + view[3] = cy + w*1.2f*(float)height/(float)width; ++ ++ printf("view0: %f\n", view[0]); ++ printf("view1: %f\n", view[2]); ++// glfwSetTime(0); ++// ++// while (!glfwWindowShouldClose(window)) ++// { ++// int winWidth, winHeight; ++// int fbWidth, fbHeight; ++// float pxr, ct; ++// ++// glfwGetWindowSize(window, &winWidth, &winHeight); ++// glfwGetFramebufferSize(window, &fbWidth, &fbHeight); ++// ++// // Calculate pixel ration for hi-dpi devices. ++// pxr = (float)fbWidth / (float)winWidth; ++// ++// ct = (float)glfwGetTime(); ++// if (run) t += ct - pt; ++// pt = ct; ++// ++// // Update and render ++// glViewport(0, 0, fbWidth, fbHeight); ++// glClearColor(0.3f, 0.3f, 0.32f, 1.0f); ++// glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); ++// glEnable(GL_BLEND); ++// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); ++// glDisable(GL_TEXTURE_2D); ++// glMatrixMode(GL_PROJECTION); ++// glLoadIdentity(); ++// glOrtho(view[0],view[2],view[1],view[3],-1,1); ++// glMatrixMode(GL_MODELVIEW); ++// glLoadIdentity(); ++// glDisable(GL_DEPTH_TEST); ++// glEnable(GL_BLEND); ++// glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); ++// ++//#ifdef USE_POOL ++// pool.size = 0; // reset pool ++// tess = tessNewTess(&ma); ++// if (tess) ++// { ++// tessSetOption(tess, TESS_CONSTRAINED_DELAUNAY_TRIANGULATION, cdt); ++// ++// offx = (view[2]+view[0])/2 + sinf(t) * (view[2]-view[0])/2; ++// offy = (view[3]+view[1])/2 + cosf(t*3.13f) * (view[3]-view[1])/6; ++// ++// for (it = fg; it != NULL; it = it->next) ++// { ++// for (i = 0; i < it->npts; ++i) ++// { ++// it->pts[i*2] += offx; ++// it->pts[i*2+1] += offy; ++// } ++// } ++// ++// for (it = bg; it != NULL; it = it->next) ++// tessAddContour(tess, 2, it->pts, sizeof(float)*2, it->npts); ++// for (it = fg; it != NULL; it = it->next) ++// tessAddContour(tess, 2, it->pts, sizeof(float)*2, it->npts); ++// ++// for (it = fg; it != NULL; it = it->next) ++// { ++// for (i = 0; i < it->npts; ++i) ++// { ++// it->pts[i*2] -= offx; ++// it->pts[i*2+1] -= offy; ++// } ++// } ++// ++// // First combine contours and then triangulate, this removes unnecessary inner vertices. ++// if (tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_BOUNDARY_CONTOURS, 0, 0, 0)) ++// { ++// const float* verts = tessGetVertices(tess); ++// const int* vinds = tessGetVertexIndices(tess); ++// const int nverts = tessGetVertexCount(tess); ++// const int* elems = tessGetElements(tess); ++// const int nelems = tessGetElementCount(tess); ++// ++// if (nverts > nvflags) ++// { ++// if (vflags) ++// free(vflags); ++// nvflags = nverts; ++// vflags = (unsigned char*)malloc(sizeof(unsigned char)*nvflags); ++// } ++// ++// if (vflags) ++// { ++// // Vertex indices describe the order the indices were added and can be used ++// // to map the tesselator output to input. Vertices marked as TESS_UNDEF ++// // are the ones that were created at the intersection of segments. ++// // That is, if vflags is set it means that the vertex comes from intersegment. ++// for (i = 0; i < nverts; ++i) ++// vflags[i] = vinds[i] == TESS_UNDEF ? 1 : 0; ++// } ++// ++// for (i = 0; i < nelems; ++i) ++// { ++// int b = elems[i*2]; ++// int n = elems[i*2+1]; ++// tessAddContour(tess, 2, &verts[b*2], sizeof(float)*2, n); ++// } ++// if (!tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_POLYGONS, nvp, 2, 0)) ++// tess = 0; ++// } ++// else ++// tess = 0; ++// } ++//#endif ++// ++// // Draw tesselated pieces. ++// if (tess) ++// { ++// const float* verts = tessGetVertices(tess); ++// const int* vinds = tessGetVertexIndices(tess); ++// const int* elems = tessGetElements(tess); ++// const int nverts = tessGetVertexCount(tess); ++// const int nelems = tessGetElementCount(tess); ++// ++// // Draw polygons. ++// glColor4ub(255,255,255,128); ++// for (i = 0; i < nelems; ++i) ++// { ++// const int* p = &elems[i*nvp]; ++// glBegin(GL_TRIANGLE_FAN); ++// for (j = 0; j < nvp && p[j] != TESS_UNDEF; ++j) ++// glVertex2f(verts[p[j]*2], verts[p[j]*2+1]); ++// glEnd(); ++// } ++// ++// glLineWidth(1.0f * pxr); ++// glPointSize(3.0f * pxr); ++// ++// glColor4ub(0,0,0,16); ++// for (i = 0; i < nelems; ++i) ++// { ++// const int* p = &elems[i*nvp]; ++// glBegin(GL_LINE_LOOP); ++// for (j = 0; j < nvp && p[j] != TESS_UNDEF; ++j) ++// glVertex2f(verts[p[j]*2], verts[p[j]*2+1]); ++// glEnd(); ++// } ++// ++// glColor4ub(0,0,0,128); ++// glBegin(GL_POINTS); ++// for (i = 0; i < nverts; ++i) ++// { ++// if (vflags && vflags[vinds[i]]) ++// glColor4ub(255,0,0,192); ++// else ++// glColor4ub(0,0,0,128); ++// glVertex2f(verts[i*2], verts[i*2+1]); ++// } ++// glEnd(); ++// ++// glPointSize(1.0f); ++// } ++// ++// glEnable(GL_DEPTH_TEST); ++// glfwSwapBuffers(window); ++// glfwPollEvents(); ++// } ++// ++// if (tess) tessDeleteTess(tess); ++// ++// if (vflags) ++// free(vflags); ++// ++// svgDelete(bg); ++// svgDelete(fg); + +- glfwSetTime(0); +- +- while (!glfwWindowShouldClose(window)) +- { +- int winWidth, winHeight; +- int fbWidth, fbHeight; +- float pxr, ct; +- +- glfwGetWindowSize(window, &winWidth, &winHeight); +- glfwGetFramebufferSize(window, &fbWidth, &fbHeight); +- +- // Calculate pixel ration for hi-dpi devices. +- pxr = (float)fbWidth / (float)winWidth; +- +- ct = (float)glfwGetTime(); +- if (run) t += ct - pt; +- pt = ct; +- +- // Update and render +- glViewport(0, 0, fbWidth, fbHeight); +- glClearColor(0.3f, 0.3f, 0.32f, 1.0f); +- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); +- glEnable(GL_BLEND); +- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +- glDisable(GL_TEXTURE_2D); +- glMatrixMode(GL_PROJECTION); +- glLoadIdentity(); +- glOrtho(view[0],view[2],view[1],view[3],-1,1); +- glMatrixMode(GL_MODELVIEW); +- glLoadIdentity(); +- glDisable(GL_DEPTH_TEST); +- glEnable(GL_BLEND); +- glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); +- +-#ifdef USE_POOL +- pool.size = 0; // reset pool +- tess = tessNewTess(&ma); +- if (tess) +- { +- tessSetOption(tess, TESS_CONSTRAINED_DELAUNAY_TRIANGULATION, cdt); +- +- offx = (view[2]+view[0])/2 + sinf(t) * (view[2]-view[0])/2; +- offy = (view[3]+view[1])/2 + cosf(t*3.13f) * (view[3]-view[1])/6; +- +- for (it = fg; it != NULL; it = it->next) +- { +- for (i = 0; i < it->npts; ++i) +- { +- it->pts[i*2] += offx; +- it->pts[i*2+1] += offy; +- } +- } +- +- for (it = bg; it != NULL; it = it->next) +- tessAddContour(tess, 2, it->pts, sizeof(float)*2, it->npts); +- for (it = fg; it != NULL; it = it->next) +- tessAddContour(tess, 2, it->pts, sizeof(float)*2, it->npts); +- +- for (it = fg; it != NULL; it = it->next) +- { +- for (i = 0; i < it->npts; ++i) +- { +- it->pts[i*2] -= offx; +- it->pts[i*2+1] -= offy; +- } +- } +- +- // First combine contours and then triangulate, this removes unnecessary inner vertices. +- if (tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_BOUNDARY_CONTOURS, 0, 0, 0)) +- { +- const float* verts = tessGetVertices(tess); +- const int* vinds = tessGetVertexIndices(tess); +- const int nverts = tessGetVertexCount(tess); +- const int* elems = tessGetElements(tess); +- const int nelems = tessGetElementCount(tess); +- +- if (nverts > nvflags) +- { +- if (vflags) +- free(vflags); +- nvflags = nverts; +- vflags = (unsigned char*)malloc(sizeof(unsigned char)*nvflags); +- } +- +- if (vflags) +- { +- // Vertex indices describe the order the indices were added and can be used +- // to map the tesselator output to input. Vertices marked as TESS_UNDEF +- // are the ones that were created at the intersection of segments. +- // That is, if vflags is set it means that the vertex comes from intersegment. +- for (i = 0; i < nverts; ++i) +- vflags[i] = vinds[i] == TESS_UNDEF ? 1 : 0; +- } +- +- for (i = 0; i < nelems; ++i) +- { +- int b = elems[i*2]; +- int n = elems[i*2+1]; +- tessAddContour(tess, 2, &verts[b*2], sizeof(float)*2, n); +- } +- if (!tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_POLYGONS, nvp, 2, 0)) +- tess = 0; +- } +- else +- tess = 0; +- } +-#endif +- +- // Draw tesselated pieces. +- if (tess) +- { +- const float* verts = tessGetVertices(tess); +- const int* vinds = tessGetVertexIndices(tess); +- const int* elems = tessGetElements(tess); +- const int nverts = tessGetVertexCount(tess); +- const int nelems = tessGetElementCount(tess); +- +- // Draw polygons. +- glColor4ub(255,255,255,128); +- for (i = 0; i < nelems; ++i) +- { +- const int* p = &elems[i*nvp]; +- glBegin(GL_TRIANGLE_FAN); +- for (j = 0; j < nvp && p[j] != TESS_UNDEF; ++j) +- glVertex2f(verts[p[j]*2], verts[p[j]*2+1]); +- glEnd(); +- } +- +- glLineWidth(1.0f * pxr); +- glPointSize(3.0f * pxr); +- +- glColor4ub(0,0,0,16); +- for (i = 0; i < nelems; ++i) +- { +- const int* p = &elems[i*nvp]; +- glBegin(GL_LINE_LOOP); +- for (j = 0; j < nvp && p[j] != TESS_UNDEF; ++j) +- glVertex2f(verts[p[j]*2], verts[p[j]*2+1]); +- glEnd(); +- } +- +- glColor4ub(0,0,0,128); +- glBegin(GL_POINTS); +- for (i = 0; i < nverts; ++i) +- { +- if (vflags && vflags[vinds[i]]) +- glColor4ub(255,0,0,192); +- else +- glColor4ub(0,0,0,128); +- glVertex2f(verts[i*2], verts[i*2+1]); +- } +- glEnd(); +- +- glPointSize(1.0f); +- } +- +- glEnable(GL_DEPTH_TEST); +- glfwSwapBuffers(window); +- glfwPollEvents(); +- } +- +- if (tess) tessDeleteTess(tess); +- +- if (vflags) +- free(vflags); +- +- svgDelete(bg); +- svgDelete(fg); +- +- glfwTerminate(); ++// glfwTerminate(); + return 0; + } +diff -Naur libtess2-1.0.2-old/premake4.lua libtess2-1.0.2-diff/premake4.lua +--- libtess2-1.0.2-old/premake4.lua 2023-05-09 09:05:10.003166275 +0800 ++++ libtess2-1.0.2-diff/premake4.lua 2023-05-09 09:17:09.481460783 +0800 +@@ -32,9 +32,7 @@ + targetdir("Build") + + configuration { "linux" } +- linkoptions { "`pkg-config --libs glfw3`" } +- links { "GL", "GLU", "m", "GLEW" } +- defines { "NANOVG_GLEW" } ++ links {"m"} + + configuration { "windows" } + links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32" }