[Bf-committers] OpenGL optimisation
Richard Berry
bf-committers@blender.org
Sat, 19 Jun 2004 14:36:27 +0100
A small update for OpenGL display list meshes. I've made a version that =
also accelerates wireframe meshes. You can get it at (Mac OS X binary =
only):
http://wwww.warwick.ac.uk/student/R.J.Berry/blender/blender1-cvs.zip
And relevant patches (against CVS) at:
http://www.warwick.ac.uk/student/R.J.Berry/blender/drawobject.diff
http://www.warwick.ac.uk/student/R.J.Berry/blender/displist.diff
http://www.warwick.ac.uk/student/R.J.Berry/blender/BKE_displist.diff
I've also got a version which is patched against 2.33a, so you can see the =
difference that removing glFinish has (change made recently in CVS):
http://www.warwick.ac.uk/student/R.J.Berry/blender/blender1-2.33a.zip
However, there is a small problem with the wireframe drawing. Because I =
couldn't find a clean way to do it, OpenGL display lists are not compiled =
for a subdivided mesh unless you have already gone through the "OpenGL =
Solid" draw mode.
For example, if you open the default Blender scene of a cube (in wireframe =
mode) and subdivide it you won't see any benefit. If you switch to "OpenGL =
Solid" mode and then back to "Wireframe" a display list will have been =
compiled.
I'm currently trawling my way through the OpenGL rendering code (all =
several thousand lines of it) to try and find a solution, but someone who =
knows Blender display lists could probably help.
If you look at the patches, the new code for solid drawing looks like =
this:
if (dl->mesh->dispList)
glCallList(dl->mesh->dispList);
else {
dl->mesh->dispList =3D glGenLists(1);
glNewList(dl->mesh->dispList, GL_COMPILE_AND_EXECUTE);
displistmesh_draw_solid(dl->mesh, drawsmooth, dl->nors);
glEndList();
}
and for drawing wireframes:
if (dl->mesh->dispList) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glCallList(dl->mesh->dispList);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
} else
displistmesh_draw_wire(dl->mesh);
whereas previously just displistmesh_draw_solid or displist_mesh_wire =
would be called.
The idea is to create a display list that can be used for both solid and =
wireframe drawing (and potentially shaded and textured modes as well) and =
then just switch between polygon drawing modes, so the display list needs =
vertex normals. I tried:
if (dl->mesh->dispList) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glCallList(dl->mesh->dispList);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
else {
if (!dl->nors)
addnormalsDispList(ob, dlbase);
=20
dl->mesh->dispList =3D glGenLists(1);
glNewList(dl->mesh->dispList, GL_COMPILE_AND_EXECUTE);
displistmesh_draw_solid(dl->mesh, !(G.f & G_BACKBUFSEL), =
dl->nors);
glEndList();
}
=20
(and changing drawDispListwire so that I had access to the Object). This =
correctly creates the mesh but the normals seem incorrect as "OpenGL =
Solid" mode always draws an entirely black mesh.
What I'm trying to do is seperate the drawing code into seperate render =
paths. So, for example, the same mesh display list (or vertex array) could =
be used in many different ways by just switch the drawing state (i.e. =
GL_FILL for solids, GL_LINE for wireframes, GL_LINE for vertex points). =
This would eliminate a lot of the redundancy that's in the current drawing =
code.
This would also make it simple to implement accelerated shaded and =
textured drawing modes (realtime shaded mode is going to have to wait =
until vertex / fragment shaders are implemented, otherwise render modes =
such as Phong and Toon shading aren't going to be possible).
Oh, and there might be a bug on Mac OS X 10.3.4 which causes wireframe =
drawing to be slow (note the above "feature" though). I ran into this on a =
PowerBook with ATI Mobility 9600.
r i c k