diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-09-11 14:23:26 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-09-11 14:23:26 +0400 |
commit | 64aa651b1b95362fe7d3c57917bd50199cc4843c (patch) | |
tree | 963e4c480725638675ef9721bdbb033742481985 /source/blender | |
parent | 933a19c9970331eb7615677b30fdd4de016ea5a0 (diff) |
speedup for editmesh drawing.
- avoid needless context switching quad/tri, flat/smooth.
- dont call glNormal3vf() lighting is disabled.
gives ~2x speedup with a subdivided cube, but thats probably the best case, quad/tri smooth/flat mix will slow down a bit.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 150 |
1 files changed, 109 insertions, 41 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index ff7f2586767..7d14ec9dec2 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -643,13 +643,22 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditFace *efa; int i, draw; - + const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */ + + /* GL_ZERO is used to detect if drawing has started or not */ + GLenum poly_prev= GL_ZERO; + GLenum shade_prev= GL_ZERO; + (void)setMaterial; /* unused */ /* currently unused -- each original face is handled separately */ (void)compareDrawOptions; if (emdm->vertexCos) { + /* add direct access */ + float (*vertexCos)[3]= emdm->vertexCos; + float (*vertexNos)[3]= emdm->vertexNos; + float (*faceNos)[3]= emdm->faceNos; EditVert *eve; for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) @@ -659,75 +668,134 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us int drawSmooth = (efa->flag & ME_SMOOTH); draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); if(draw) { + const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES; if (draw==2) { /* enabled with stipple */ - glEnable(GL_POLYGON_STIPPLE); - glPolygonStipple(stipple_quarttone); + + if(poly_prev != GL_ZERO) glEnd(); + poly_prev= GL_ZERO; /* force glBegin */ + + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); } - glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); + if(skip_normals) { + if(poly_type != poly_prev) { + if(poly_prev != GL_ZERO) glEnd(); + glBegin((poly_prev= poly_type)); + } + glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); + if(poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); + } + else { + const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT; + if (shade_type != shade_prev) { + glShadeModel((shade_prev= shade_type)); + } + if(poly_type != poly_prev) { + if(poly_prev != GL_ZERO) glEnd(); + glBegin((poly_prev= poly_type)); + } - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - if (!drawSmooth) { - glNormal3fv(emdm->faceNos[i]); - glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]); - if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]); - } else { - glNormal3fv(emdm->vertexNos[(int) efa->v1->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]); - glNormal3fv(emdm->vertexNos[(int) efa->v2->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]); - glNormal3fv(emdm->vertexNos[(int) efa->v3->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]); - if(efa->v4) { - glNormal3fv(emdm->vertexNos[(int) efa->v4->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]); + if (!drawSmooth) { + glNormal3fv(faceNos[i]); + glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); + if(poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); + } else { + glNormal3fv(vertexNos[(int) efa->v1->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); + glNormal3fv(vertexNos[(int) efa->v2->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); + glNormal3fv(vertexNos[(int) efa->v3->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); + if(poly_type == GL_QUADS) { + glNormal3fv(vertexNos[(int) efa->v4->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); + } } } - glEnd(); + - if (draw==2) + if (draw==2) { + glEnd(); + poly_prev= GL_ZERO; /* force glBegin */ + glDisable(GL_POLYGON_STIPPLE); + } } } - } else { + } + else { for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { int drawSmooth = (efa->flag & ME_SMOOTH); draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); if(draw) { + const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES; if (draw==2) { /* enabled with stipple */ + + if(poly_prev != GL_ZERO) glEnd(); + poly_prev= GL_ZERO; /* force glBegin */ + glEnable(GL_POLYGON_STIPPLE); glPolygonStipple(stipple_quarttone); } - glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - if (!drawSmooth) { - glNormal3fv(efa->n); - glVertex3fv(efa->v1->co); - glVertex3fv(efa->v2->co); - glVertex3fv(efa->v3->co); - if(efa->v4) glVertex3fv(efa->v4->co); - } else { - glNormal3fv(efa->v1->no); + if(skip_normals) { + if(poly_type != poly_prev) { + if(poly_prev != GL_ZERO) glEnd(); + glBegin((poly_prev= poly_type)); + } glVertex3fv(efa->v1->co); - glNormal3fv(efa->v2->no); glVertex3fv(efa->v2->co); - glNormal3fv(efa->v3->no); glVertex3fv(efa->v3->co); - if(efa->v4) { - glNormal3fv(efa->v4->no); - glVertex3fv(efa->v4->co); + if(poly_type == GL_QUADS) glVertex3fv(efa->v4->co); + } + else { + const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT; + if (shade_type != shade_prev) { + glShadeModel((shade_prev= shade_type)); + } + if(poly_type != poly_prev) { + if(poly_prev != GL_ZERO) glEnd(); + glBegin((poly_prev= poly_type)); + } + + if (!drawSmooth) { + glNormal3fv(efa->n); + glVertex3fv(efa->v1->co); + glVertex3fv(efa->v2->co); + glVertex3fv(efa->v3->co); + if(poly_type == GL_QUADS) glVertex3fv(efa->v4->co); + } else { + glNormal3fv(efa->v1->no); + glVertex3fv(efa->v1->co); + glNormal3fv(efa->v2->no); + glVertex3fv(efa->v2->co); + glNormal3fv(efa->v3->no); + glVertex3fv(efa->v3->co); + if(poly_type == GL_QUADS) { + glNormal3fv(efa->v4->no); + glVertex3fv(efa->v4->co); + } } } - glEnd(); + - if (draw==2) + if (draw==2) { + glEnd(); + poly_prev= GL_ZERO; + glDisable(GL_POLYGON_STIPPLE); + } } } } + + /* if non zero we know a face was rendered */ + if(poly_prev != GL_ZERO) glEnd(); } static void emDM_drawFacesTex_common(DerivedMesh *dm, |