[Bf-committers] OpenGL optimisation
Richard Berry
bf-committers@blender.org
Mon, 24 May 2004 13:56:44 +0100
>> A few choice expletives and a fresh CVS later:
>>
>> http://www.warwick.ac.uk/student/R.J.Berry/customblender.zip
>
> I gave this a try on OSX 10.3 with a file with some high poly subsurfs.
> Speed increased from 3.1 FPS (2.33) to 6.5 FPS on this version. Not
> bad! One thing I did notice though, it that all my objects that were
> 'set smooth' were not in your version, they were displayed flat shaded.
> Is this a limitation in the OpenGL display lists? Could it also be a
> factor in speeding it up?
>
> Matt
The main change that I've made to the code is to alter the displistmesh_dra=
w_solid routine from drawobject.c (apologies if this is formatted badly):
static void displistmesh_draw_solid(DispListMesh *dlm, int drawsmooth, =
float *nors) {
/* rick: the authors really should be shot... */
int lmode, lshademodel=3D GL_FLAT, lmat_nr=3D -1;
int i;
#define PASSVERT(ind) { =
\
if (drawsmooth && lshademodel=3D=3DGL_SMOOTH) =
\
glNormal3sv(dlm->mvert[(ind)].no); =
\
glVertex3fv(dlm->mvert[(ind)].co); =
\
}
/* rick: draw a display list if we've already got one */
if (dlm->dispList) {
glCallList(dlm->dispList);
return;
}
/* rick: no OpenGL display list defined, so make one */
dlm->dispList =3D glGenLists(1);
glNewList(dlm->dispList, GL_COMPILE_AND_EXECUTE);
glBegin(lmode=3D GL_QUADS);
for (i=3D0; i<dlm->totface; i++) {
MFace *mf=3D &dlm->mface[i];
=09
if (mf->v3) {
int nmode=3D mf->v4?GL_QUADS:GL_TRIANGLES;
=09
if (nmode!=3Dlmode) {
glEnd();
glBegin(lmode=3D nmode);
}
=09
/* rick: state changes mess performance up at the =
moment */
/*
if (drawsmooth) {
int nshademodel=3D (mf->flag&ME_SMOOTH)?GL_=
SMOOTH:GL_FLAT;
if (nshademodel!=3Dlshademodel) {
glEnd();
glShadeModel(lshademodel=3D =
nshademodel);
glBegin(lmode);
}
=09
if (mf->mat_nr!=3Dlmat_nr)
set_gl_material((lmat_nr=3D =
mf->mat_nr)+1);
}
*/
=09
if (drawsmooth && lshademodel=3D=3DGL_FLAT)
glNormal3fv(&nors[i*3]);
=09
PASSVERT(mf->v1);
PASSVERT(mf->v2);
PASSVERT(mf->v3);
if (mf->v4)
PASSVERT(mf->v4);
}
}
glEnd();
/* rick: done creating OpenGL display list */
glEndList();
=09
#undef PASSVERT
}
As you can see, I've commented out the bits that deal with smooth shading =
and materials. I've done this because if there are a lot of state changes =
while compiling / drawing the display list a lot of the performance is =
lost. In the final version the materials / smooth shading should work; =
display lists allow you to do everything that you could normally do.
The problem is that that the state changes have to be grouped together, so =
that there are a minimal number of changes. I'm currently figuring out the =
best way to do this and will be asking on some OpenGL forums and the Apple =
OpenGL mailing list (mac-opengl). I think that these optimisations will =
probably be similar for most implementations.
Also note that with Catmull-Clark subdivision you end up with all the =
faces as quads, so there are no changes between glBegin(GL_TRIANGLES) and =
glBegin(GL_QUADS). For generic meshes I guess I'm going to have to sort =
between triangles and quads as well otherwise there will be a lot of calls =
to glEnd / glBegin.
r i c k