[Bf-committers] OpenGL optimisation

Richard Berry bf-committers@blender.org
Mon, 24 May 2004 16:14:16 +0100


Okay, I've restored it (with a slight alteration) so that it supports =
per-face materials / smooth shading; it looks as though it gives identical =
performance. The new binary is at:

http://www.warwick.ac.uk/student/R.J.Berry/customblender2.zip

The code now looks like:



static void displistmesh_draw_solid(DispListMesh *dlm, int drawsmooth, =
float *nors) {
	/* int lmode, lshademodel=3D GL_FLAT, lmat_nr=3D -1; */
	GLenum lmode, lshademodel =3D GL_FLAT;
	int 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; */
			GLenum nmode=3D mf->v4?GL_QUADS:GL_TRIANGLES;
		=09
			if (nmode!=3Dlmode) {
				glEnd();
				glBegin(lmode=3D nmode);
			}
		=09
			if (drawsmooth) {
				/* int nshademodel=3D (mf->flag&ME_SMOOTH)?=
GL_SMOOTH:GL_FLAT; */
				GLenum 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) {
					glEnd();
					set_gl_material((lmat_nr=3D =
mf->mat_nr)+1);
					glBegin(lmode);
				}
			}
		=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
}



I also got the following response from someone at ATI on the mac-opengl =
mailing list:

> Setting material properties between begin/end pairs is bad for performanc=
e:
> so avoid it as much as possible. You can set them all you want outside =
of
> begin/end pairs without performance penalties, but not inside the pair.
>
> Having seperate display lists for different OpenGL primitives isn't
> necessary, and probably won't help performance. There really isn't any =
kind
> of performance hit switching from one to the other, at least at our =
layer of
> the OpenGL driver stack.
>
> If you're looking into batching state together, start by batching OpenGL
> objects together as much as possible: start with vertex & pixel program
> objects, then group by texture objects, then by vertex array objects.
>
> Finally, I don't see why switching from smooth to flat rendering, and =
vice
> versa, would cause performance penalties, at least for our hardware.

As he says, this is specific to their hardware (and possibly the Apple =
OpenGL driver as well) but I think this is the sort of thing that will be =
common on similar cards. I'll try and get some patches together so people =
can test this on different architectures.

Also, could someone point me in the direction (or mail me) some example =
Blender scenes with large polygon counts that someone is likely to use so =
I can test this in a real world environment.

r i c k