From c562b3271ee3644b6fdb4282535e43152656cf41 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Mon, 17 Oct 2011 07:57:35 +0000 Subject: [PATCH] Improve performance of GritsPoly Use separate display lists, and only create them and perform tessellation when they are actually used. This is especially useful for large number of polygons which aren't always displayed (or may never be displayed). Generating the display lists from the first draw() also avoids a large number of idle callbacks. --- src/objects/grits-poly.c | 52 +++++++++++++++++----------------------- src/objects/grits-poly.h | 2 +- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/objects/grits-poly.c b/src/objects/grits-poly.c index da35b36..1a1e614 100644 --- a/src/objects/grits-poly.c +++ b/src/objects/grits-poly.c @@ -35,8 +35,8 @@ static void grits_poly_tess(gdouble (**points)[3]) gluTessCallback(tess, GLU_TESS_BEGIN, (_GLUfuncptr)glBegin); gluTessCallback(tess, GLU_TESS_VERTEX, (_GLUfuncptr)glVertex3dv); gluTessCallback(tess, GLU_TESS_END, (_GLUfuncptr)glEnd); - gluTessBeginPolygon(tess, NULL); for (int pi = 0; points[pi]; pi++) { + gluTessBeginPolygon(tess, NULL); gluTessBeginContour(tess); for (int ci = 0; points[pi][ci][0]; ci++) { gluTessVertex(tess, @@ -44,8 +44,8 @@ static void grits_poly_tess(gdouble (**points)[3]) points[pi][ci]); } gluTessEndContour(tess); + gluTessEndPolygon(tess); } - gluTessEndPolygon(tess); gluDeleteTess(tess); } @@ -53,13 +53,7 @@ static void grits_poly_outline(gdouble (**points)[3]) { //g_debug("GritsPoly: outline"); for (int pi = 0; points[pi]; pi++) { - glBegin(GL_LINE_LOOP); - for (int ci = 0; points[pi][ci][0] && - points[pi][ci][1] && - points[pi][ci][2]; ci++) - glVertex3dv(points[pi][ci]); - glEnd(); - glBegin(GL_POINTS); + glBegin(GL_POLYGON); for (int ci = 0; points[pi][ci][0] && points[pi][ci][1] && points[pi][ci][2]; ci++) @@ -67,18 +61,20 @@ static void grits_poly_outline(gdouble (**points)[3]) glEnd(); } } -static gboolean grits_poly_genlist(gpointer _poly) + +static gboolean grits_poly_runlist(GritsPoly *poly, int i, + void (*render)(gdouble(**)[3])) { //g_debug("GritsPoly: genlist"); - GritsPoly *poly = GRITS_POLY(_poly); - guint list = glGenLists(2); - glNewList(list+0, GL_COMPILE); - grits_poly_tess(poly->points); - glEndList(); - glNewList(list+1, GL_COMPILE); - grits_poly_outline(poly->points); - glEndList(); - poly->list = list; + if (poly->list[i]) { + glCallList(poly->list[i]); + } else { + guint list = glGenLists(1); + glNewList(list, GL_COMPILE_AND_EXECUTE); + render(poly->points); + glEndList(); + poly->list[i] = list; + } return FALSE; } @@ -87,9 +83,6 @@ static void grits_poly_draw(GritsObject *_poly, GritsOpenGL *opengl) //g_debug("GritsPoly: draw"); GritsPoly *poly = GRITS_POLY(_poly); - if (!poly->list) - return; - glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT); glDisable(GL_TEXTURE_2D); glDisable(GL_ALPHA_TEST); @@ -99,14 +92,15 @@ static void grits_poly_draw(GritsObject *_poly, GritsOpenGL *opengl) glPolygonOffset(1, 1); if (poly->color[3]) { glColor4dv(poly->color); - glCallList(poly->list+0); + grits_poly_runlist(poly, 0, grits_poly_tess); } + glLineWidth(poly->width); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); if (poly->border[3]) { - glPointSize(poly->width); - glLineWidth(poly->width); glColor4dv(poly->border); - glCallList(poly->list+1); + grits_poly_runlist(poly, 1, grits_poly_outline); } + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPopAttrib(); } @@ -114,11 +108,9 @@ static void grits_poly_pick(GritsObject *_poly, GritsOpenGL *opengl) { //g_debug("GritsPoly: pick"); GritsPoly *poly = GRITS_POLY(_poly); - if (!poly->list) - return; glPushAttrib(GL_ENABLE_BIT); glDisable(GL_CULL_FACE); - glCallList(poly->list+0); + grits_poly_runlist(poly, 0, grits_poly_tess); glPopAttrib(); } @@ -136,7 +128,6 @@ GritsPoly *grits_poly_new(gdouble (**points)[3]) //g_debug("GritsPoly: new - %p", points); GritsPoly *poly = g_object_new(GRITS_TYPE_POLY, NULL); poly->points = points; - g_idle_add(grits_poly_genlist, poly); return poly; } @@ -192,6 +183,7 @@ static void grits_poly_init(GritsPoly *poly) poly->border[2] = 1; poly->border[3] = 0.2; poly->width = 1; + GRITS_OBJECT(poly)->skip = GRITS_SKIP_STATE; } static void grits_poly_finalize(GObject *_poly) diff --git a/src/objects/grits-poly.h b/src/objects/grits-poly.h index 608baf3..ad7cefb 100644 --- a/src/objects/grits-poly.h +++ b/src/objects/grits-poly.h @@ -40,7 +40,7 @@ struct _GritsPoly { gdouble color[4]; gdouble border[4]; gdouble width; - guint list; + guint list[2]; }; struct _GritsPolyClass { -- 2.43.2