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.
This commit is contained in:
Campbell Barton 2011-09-11 10:23:26 +00:00
parent 933a19c997
commit 64aa651b1b

@ -643,13 +643,22 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditFace *efa; EditFace *efa;
int i, draw; 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 */ (void)setMaterial; /* unused */
/* currently unused -- each original face is handled separately */ /* currently unused -- each original face is handled separately */
(void)compareDrawOptions; (void)compareDrawOptions;
if (emdm->vertexCos) { if (emdm->vertexCos) {
/* add direct access */
float (*vertexCos)[3]= emdm->vertexCos;
float (*vertexNos)[3]= emdm->vertexNos;
float (*faceNos)[3]= emdm->faceNos;
EditVert *eve; EditVert *eve;
for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) 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); int drawSmooth = (efa->flag & ME_SMOOTH);
draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
if(draw) { if(draw) {
const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
if (draw==2) { /* enabled with stipple */ 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) {
if (!drawSmooth) { glNormal3fv(faceNos[i]);
glNormal3fv(emdm->faceNos[i]); glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]); glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]); glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]); if(poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]); } else {
} else { glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
glNormal3fv(emdm->vertexNos[(int) efa->v1->tmp.l]); glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]); glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
glNormal3fv(emdm->vertexNos[(int) efa->v2->tmp.l]); glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]); glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
glNormal3fv(emdm->vertexNos[(int) efa->v3->tmp.l]); glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]); if(poly_type == GL_QUADS) {
if(efa->v4) { glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
glNormal3fv(emdm->vertexNos[(int) efa->v4->tmp.l]); glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]); }
} }
} }
glEnd();
if (draw==2) if (draw==2) {
glEnd();
poly_prev= GL_ZERO; /* force glBegin */
glDisable(GL_POLYGON_STIPPLE); glDisable(GL_POLYGON_STIPPLE);
}
} }
} }
} else { }
else {
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
int drawSmooth = (efa->flag & ME_SMOOTH); int drawSmooth = (efa->flag & ME_SMOOTH);
draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
if(draw) { if(draw) {
const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
if (draw==2) { /* enabled with stipple */ if (draw==2) { /* enabled with stipple */
if(poly_prev != GL_ZERO) glEnd();
poly_prev= GL_ZERO; /* force glBegin */
glEnable(GL_POLYGON_STIPPLE); glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone); glPolygonStipple(stipple_quarttone);
} }
glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); if(skip_normals) {
if (!drawSmooth) { if(poly_type != poly_prev) {
glNormal3fv(efa->n); if(poly_prev != GL_ZERO) glEnd();
glBegin((poly_prev= poly_type));
}
glVertex3fv(efa->v1->co); glVertex3fv(efa->v1->co);
glVertex3fv(efa->v2->co); glVertex3fv(efa->v2->co);
glVertex3fv(efa->v3->co); glVertex3fv(efa->v3->co);
if(efa->v4) glVertex3fv(efa->v4->co); if(poly_type == GL_QUADS) glVertex3fv(efa->v4->co);
} else { }
glNormal3fv(efa->v1->no); else {
glVertex3fv(efa->v1->co); const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
glNormal3fv(efa->v2->no); if (shade_type != shade_prev) {
glVertex3fv(efa->v2->co); glShadeModel((shade_prev= shade_type));
glNormal3fv(efa->v3->no); }
glVertex3fv(efa->v3->co); if(poly_type != poly_prev) {
if(efa->v4) { if(poly_prev != GL_ZERO) glEnd();
glNormal3fv(efa->v4->no); glBegin((poly_prev= poly_type));
glVertex3fv(efa->v4->co); }
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); 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, static void emDM_drawFacesTex_common(DerivedMesh *dm,