From a6899a3f7c3e9390a31b5815f9af94b682206232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Tue, 19 Apr 2022 20:04:08 +0200 Subject: [PATCH] Add poly2tri and C++ wrapper for polygon tesselation. --- .gitmodules | 3 + 3rdparty/poly2tri | 1 + CMakeLists.txt | 6 +- preview-rendering/CMakeLists.txt | 5 +- .../poly2tri-wrapper/CMakeLists.txt | 11 +++ .../poly2tri-wrapper/poly2tri-wrapper.h | 16 ++++ .../poly2tri-wrapper/src/poly2tri-wrapper.cpp | 58 +++++++++++++ preview-rendering/src/preview-rendering-gui.c | 84 ++++++++++++++++--- resources/preview-window.glade | 2 +- 9 files changed, 171 insertions(+), 15 deletions(-) create mode 160000 3rdparty/poly2tri create mode 100644 preview-rendering/poly2tri-wrapper/CMakeLists.txt create mode 100644 preview-rendering/poly2tri-wrapper/include/poly2tri-wrapper/poly2tri-wrapper.h create mode 100644 preview-rendering/poly2tri-wrapper/src/poly2tri-wrapper.cpp diff --git a/.gitmodules b/.gitmodules index f455687..0ce78e3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,3 +6,6 @@ path = 3rdparty/libfort url = https://git.shimatta.de/3rd-party/libfort branch = develop +[submodule "3rdparty/poly2tri"] + path = 3rdparty/poly2tri + url = https://git.shimatta.de/3rd-party/poly2tri.git diff --git a/3rdparty/poly2tri b/3rdparty/poly2tri new file mode 160000 index 0000000..3380f5c --- /dev/null +++ b/3rdparty/poly2tri @@ -0,0 +1 @@ +Subproject commit 3380f5c805dd25a06de21f7dacd4db529dbe07e7 diff --git a/CMakeLists.txt b/CMakeLists.txt index 818be16..4ba51a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ if (POLICY CMP0048) cmake_policy(SET CMP0048 NEW) endif (POLICY CMP0048) -project(gds-render LANGUAGES C) +project(gds-render LANGUAGES C CXX) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "/usr/" CACHE PATH "..." FORCE) @@ -75,8 +75,6 @@ SET_SOURCE_FILES_PROPERTIES(${SOURCE_GENERATED} PROPERTIES GENERATED 1) add_subdirectory(test) -add_compile_options(-Wall -Wextra -Wold-style-declaration -Wuninitialized -Wmaybe-uninitialized -Wunused-parameter) - add_subdirectory(resources) add_subdirectory(doxygen) add_subdirectory(translations) @@ -91,6 +89,8 @@ if(OPENGL_PREVIEW) add_subdirectory(preview-rendering) endif(OPENGL_PREVIEW) +add_compile_options(-Wall -Wextra -Wold-style-declaration -Wuninitialized -Wmaybe-uninitialized -Wunused-parameter) + link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS}) add_definitions(${GLIB2_CFLAGS_OTHER}) diff --git a/preview-rendering/CMakeLists.txt b/preview-rendering/CMakeLists.txt index 2927aee..26eaf5f 100644 --- a/preview-rendering/CMakeLists.txt +++ b/preview-rendering/CMakeLists.txt @@ -8,8 +8,11 @@ pkg_check_modules(GTK3 REQUIRED gtk+-3.0) aux_source_directory("src" SRCS) +add_subdirectory(poly2tri-wrapper) + add_library(${PROJECT_NAME} STATIC ${SRCS}) target_include_directories(${PROJECT_NAME} PUBLIC "include") target_include_directories(${PROJECT_NAME} PRIVATE ${EPOXY_INCLUDE_DIRS} ${GLIB_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS}) target_link_directories(${PROJECT_NAME} PUBLIC ${EPOXY_LINK_DIRS} ${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS}) -target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${EPOXY_LDFLAGS} ${GTK3_LDFLAGS}) +target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${EPOXY_LDFLAGS} ${GTK3_LDFLAGS} poly2tri-wrapper) + diff --git a/preview-rendering/poly2tri-wrapper/CMakeLists.txt b/preview-rendering/poly2tri-wrapper/CMakeLists.txt new file mode 100644 index 0000000..05b9856 --- /dev/null +++ b/preview-rendering/poly2tri-wrapper/CMakeLists.txt @@ -0,0 +1,11 @@ +project(poly2tri-wrapper LANGUAGES CXX) +cmake_minimum_required(VERSION 3.12) + +add_subdirectory(../../3rdparty/poly2tri poly2tri) +set(CMAKE_CXX_STANDARD 14) + +aux_source_directory("src" WRAPPER_SOURCES) + +add_library(${PROJECT_NAME} STATIC ${WRAPPER_SOURCES}) +target_link_libraries(${PROJECT_NAME} poly2tri) +target_include_directories(${PROJECT_NAME} PUBLIC "include") diff --git a/preview-rendering/poly2tri-wrapper/include/poly2tri-wrapper/poly2tri-wrapper.h b/preview-rendering/poly2tri-wrapper/include/poly2tri-wrapper/poly2tri-wrapper.h new file mode 100644 index 0000000..25370ff --- /dev/null +++ b/preview-rendering/poly2tri-wrapper/include/poly2tri-wrapper/poly2tri-wrapper.h @@ -0,0 +1,16 @@ +#ifndef _POLY2TRI_WRAPPER_H_ +#define _POLY2TRI_WRAPPER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +int tesselator_triangulate_polygon(const struct gds_graphics *gfx, double scale, float **output_vertices, size_t *vertex_count); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* _POLY2TRI_WRAPPER_H_ */ diff --git a/preview-rendering/poly2tri-wrapper/src/poly2tri-wrapper.cpp b/preview-rendering/poly2tri-wrapper/src/poly2tri-wrapper.cpp new file mode 100644 index 0000000..506d284 --- /dev/null +++ b/preview-rendering/poly2tri-wrapper/src/poly2tri-wrapper.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +//#include +#include + +int tesselator_triangulate_polygon(const struct gds_graphics *gfx, double scale, float** output_vertices, size_t *vertex_count) +{ + GList *vertex_iter; + std::vector polyline; + + if (gfx->gfx_type != GRAPHIC_POLYGON) + return -1; + + for (vertex_iter = gfx->vertices; vertex_iter; vertex_iter = g_list_next(vertex_iter)) { + struct gds_point *gds_pt = (struct gds_point *)vertex_iter->data; + auto pt = new p2t::Point((double)gds_pt->x/scale, (double)gds_pt->y/scale); + polyline.push_back(pt); + } + + auto my_cdt = p2t::CDT(polyline); + + my_cdt.Triangulate(); + + auto triangles = my_cdt.GetTriangles(); + + + + /* Free the triangles */ + for (auto it = triangles.begin(); it != triangles.end(); it++) { + auto triangle = *it; + std::cout << "Triangle: " << + triangle->GetPoint(0)->x << "|" << triangle->GetPoint(0)->y << "," + << triangle->GetPoint(1)->x << "|" << triangle->GetPoint(1)->x << "," + << triangle->GetPoint(2)->x << "|" << triangle->GetPoint(2)->y + << std::endl; + } + + /* Get the amount of triangles */ + auto count = triangles.size(); + *output_vertices = (float *)malloc(2*sizeof(float)*3*count); + + *vertex_count = count * 3; + /* Free the points in the vector */ + for (unsigned int i = 0; i < count; i++) { + for (int j = 0; j < 3; j++) { + auto pt = triangles[i]->GetPoint(j); + unsigned int idx = i * 6 + j * 2; + (*output_vertices)[idx] = (float)pt->x; + (*output_vertices)[idx + 1] = (float)pt->y; + } + } + + for (auto it = polyline.begin(); it != polyline.end(); it++) + delete *it; + + return 0; +} diff --git a/preview-rendering/src/preview-rendering-gui.c b/preview-rendering/src/preview-rendering-gui.c index a3a1cab..489bf59 100644 --- a/preview-rendering/src/preview-rendering-gui.c +++ b/preview-rendering/src/preview-rendering-gui.c @@ -1,4 +1,5 @@ #include +#include #include struct _OpenGlPreviewGui { @@ -9,6 +10,7 @@ struct _OpenGlPreviewGui { unsigned int vao; unsigned int vbo; float color[4]; + gboolean line; }; G_DEFINE_TYPE(OpenGlPreviewGui, opengl_preview_gui, G_TYPE_OBJECT) @@ -47,12 +49,12 @@ static gboolean gl_area_render(GtkGLArea *area, GdkGLContext *context, gpointer glClearColor (0, 0, 0, 1.0); glClear (GL_COLOR_BUFFER_BIT); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glPolygonMode(GL_FRONT_AND_BACK, gui->line ? GL_LINE : GL_FILL); glUseProgram(gui->polygon_shader_prog); glBindVertexArray(gui->vao); loc = glGetUniformLocation(gui->polygon_shader_prog, "const_color"); glUniform4fv(loc, 1, gui->color); - glDrawArrays(GL_TRIANGLES, 0, 3); + glDrawArrays(GL_TRIANGLES, 0, 10*3); glFlush(); @@ -78,6 +80,7 @@ static int compile_shader_from_resource(GLenum shader_type, const char *res_name g_bytes_unref(res_bytes); if (shader) *shader = sh; + return success; } @@ -90,6 +93,9 @@ static gboolean gl_area_realize(GtkGLArea *area, gpointer user) unsigned int vao; OpenGlPreviewGui *gui; int success; + struct gds_graphics gfx; + struct gds_point points[12]; + size_t vertex_count; gui = GDS_RENDER_OPENGL_PREVIEW_GUI(user); @@ -120,30 +126,85 @@ static gboolean gl_area_realize(GtkGLArea *area, gpointer user) glDeleteShader(fs); - float vertices[] = { - -0.5f, -0.5f, - 0.5f, -0.5f, - 0.0f, 0.5f, - }; + + + + + gui->polygon_shader_prog = prog; + + + gfx.vertices = NULL; + points[0].x = -100; + points[0].y = -100; + + points[1].x = -100; + points[1].y = +100; + + points[2].x = +0; + points[2].y = +100; + + points[3].x = +0; + points[3].y = 20; + + points[4].x = -20; + points[4].y = 20; + + points[5].x = -20; + points[5].y = -20; + + points[6].x = 20; + points[6].y = -20; + + points[7].x = 20; + points[7].y = 20; + + points[8].x = 1; + points[8].y = 20; + + points[9].x = 1; + points[9].y = 100; + + points[10].x = 100; + points[10].y = 100; + + points[11].x = 100; + points[11].y = -100; + + gfx.gfx_type = GRAPHIC_POLYGON; + + for (int i = 0; i < 12; i++) { + gfx.vertices = g_list_append(gfx.vertices, &points[i]); + } + + float *vertices = NULL; + + tesselator_triangulate_polygon(&gfx, 180.0, &vertices, &vertex_count); + glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, vertex_count*2*sizeof(float), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void *)0); glEnableVertexAttribArray(0); + free(vertices); - - gui->polygon_shader_prog = prog; gui->vao = vao; gui->vbo = vbo; + g_list_free(gfx.vertices); + return TRUE; } +static void on_clicked(GtkWidget *sender, gboolean *p) +{ + *p = !*p; +} + static void opengl_preview_gui_init(OpenGlPreviewGui *self) { GtkBuilder *builder; @@ -153,6 +214,9 @@ static void opengl_preview_gui_init(OpenGlPreviewGui *self) self->gl_area = GTK_GL_AREA(gtk_builder_get_object(builder, "gl-area")); g_signal_connect(self->gl_area, "render", G_CALLBACK(gl_area_render), self); g_signal_connect(self->gl_area, "realize", G_CALLBACK(gl_area_realize), self); + + g_signal_connect(gtk_builder_get_object(builder, "test-button"), "clicked", G_CALLBACK(on_clicked), &self->line); + self->line = FALSE; g_object_ref(self->gl_area); } diff --git a/resources/preview-window.glade b/resources/preview-window.glade index dcebed2..e5b1eac 100644 --- a/resources/preview-window.glade +++ b/resources/preview-window.glade @@ -12,7 +12,7 @@ False bottom - + button True True