(I think you should bring this up in the OpenGl community; if the with-statement supports the usage I don't see why not. GvR)
(Doing so. -- Andrew Dalke)
OpenGL programmers have complained about using Python because the code indentation doesn't follow the display tree. For an example pulled from one of my (Andrew Dalke) projects
glBegin(GL_QUAD_STRIP)
glColor3f(1.0,1.0,1.0) #corner 1
glNormal3f(0.57735027, 0.57735027, 0.57735027)
glVertex3f(0.5, 0.5, 0.5)
glColor3f(1.0,0.0,1.0) #corner 2
glNormal3f(0.57735027, -0.57735027, 0.57735027)
glVertex3f(0.5, -0.5, 0.5)
...
glEnd()Some people write this as some variant of
glBegin(GL_QUAD_STRIP)
if 1:
glColor3f(1.0,1.0,1.0) #corner 1
glNormal3f(0.57735027, 0.57735027, 0.57735027)
glVertex3f(0.5, 0.5, 0.5)
glColor3f(1.0,0.0,1.0) #corner 2
glNormal3f(0.57735027, -0.57735027, 0.57735027)
glVertex3f(0.5, -0.5, 0.5)
...
glEnd()and sometimes using try/finally so that errors don't cause the gl state to become corrupted.
Would an appropriate use of this proposal be to allow
with QUAD_STRIP:
glColor3f(1.0,1.0,1.0) #corner 1
glNormal3f(0.57735027, 0.57735027, 0.57735027)
glVertex3f(0.5, 0.5, 0.5)
glColor3f(1.0,0.0,1.0) #corner 2
glNormal3f(0.57735027, -0.57735027, 0.57735027)
glVertex3f(0.5, -0.5, 0.5)
....where there are a bunch of small classes for each of the possible glBegins, such as
class QUAD_STRIP:
@staticmethod
def __enter__():
glBegin(GL_QUAD_STRIP)
@staticmethod
def __exit__(*args):
glEnd()If so, I rather like that ability as it makes the graphics programmer's intent clearer and prevents problems balancing glBegin and glEnd - even in the face of code errors in the actual code block! -- Andrew Dalke
I'm (Andrew Dalke) often one to resist change to Python. The WithStatement is a counter-example. I really like how it cleans up some OpenGL programming. Consider this example from OpenGLContext's indexlineset.py
dl = displaylist.DisplayList()
...
# compile the color-friendly ILS
dl.start()
try:
glEnable( GL_COLOR_MATERIAL )
for polyline, color in zip(indices, colorIndices):
if type(color) == int:
glColor3d( *colors[color] )
glBegin( GL_LINE_STRIP )
try:
for i in polyline:
glVertex3f(*points[i])
finally:
glEnd()
else:
glBegin( GL_LINE_STRIP )
try:
for i,c in zip(polyline, color):
glColor3d( *colors[c] )
glVertex3f(*points[i])
finally:
glEnd()
glDisable( GL_COLOR_MATERIAL )
finally:
dl.end()Assuming a few minor helper classes and a couple of new __enter__/__exit__ methods and it can be rewritten using 'with' statements like this:
dl = displaylist.DisplayList()
...
with dl:
with GLEnable( GL_COLOR_MATERIAL ):
for polyline, color in zip(indices, colorIndices):
if type(color) == int:
glColor3d( *colors[color] )
with GLGeometry( GL_LINE_STRIP ):
for i in polyline:
glVertex3f(*points[i])
else:
with GLBegin( GL_LINE_STRIP ):
for i,c in zip(polyline, color):
glColor3d( *colors[c] )
glVertex3f(*points[i])Shorter, cleaner, less error-prone, easier to read and maintain. +1 from me! -- Andrew Dalke
