import math import gtk import gtk.gtkgl from OpenGL.GL import * from Line import Line from Circle import Circle class SketchWidget: def __init__(self, sketch): self.sketch = sketch try: # try double-buffered self.glconfig = gtk.gdkgl.Config(mode = (gtk.gdkgl.MODE_RGB | gtk.gdkgl.MODE_DOUBLE | gtk.gdkgl.MODE_DEPTH)) except gtk.gdkgl.NoMatches: # try single-buffered self.glconfig = gtk.gdkgl.Config(mode = (gtk.gdkgl.MODE_RGB | gtk.gdkgl.MODE_DEPTH)) self.widget = gtk.gtkgl.DrawingArea(self.glconfig) self.widget.connect_after('realize', self.init) self.widget.connect('configure_event', self.reshape) self.widget.connect('expose_event', self.draw) def init(self, glarea): # get GLContext and GLDrawable glcontext = glarea.get_gl_context() gldrawable = glarea.get_gl_drawable() # GL calls if not gldrawable.gl_begin(glcontext): return glLightfv(GL_LIGHT0, GL_POSITION, (1, 1, 1, 0)) glEnable(GL_CULL_FACE) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glEnable(GL_DEPTH_TEST) gldrawable.gl_end() def reshape(self, glarea, event): # get GLContext and GLDrawable glcontext = glarea.get_gl_context() gldrawable = glarea.get_gl_drawable() # GL calls if not gldrawable.gl_begin(glcontext): return x, y, width, height = glarea.get_allocation() glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glOrtho(-2, 2, -1.5, 1.5, 1.0, -1.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() gldrawable.gl_end() return True def draw(self, glarea, event): # get GLContext and GLDrawable glcontext = glarea.get_gl_context() gldrawable = glarea.get_gl_drawable() # GL calls if not gldrawable.gl_begin(glcontext): return glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) for shape in self.sketch: if isinstance(shape, Line): self.drawLine(shape) elif isinstance(shape, Circle): self.drawCircle(shape) if gldrawable.is_double_buffered(): gldrawable.swap_buffers() else: glFlush() gldrawable.gl_end() return True def drawLine(self, shape): self.drawFilledLine(shape.vars[0], shape.vars[1], shape.vars[2], shape.vars[3], 0.03) def drawCircle(self, shape): glBegin(GL_LINE_LOOP) for i in range(24): glVertex(shape.vars[0] + shape.vars[2] * math.sin(i * 2 * math.pi / 24.0), shape.vars[1] + shape.vars[2] * math.cos(i * 2 * math.pi / 24.0)) glEnd() def drawFilledLine(self, x0, y0, x1, y1, size): glBegin(GL_QUADS) angle = math.atan2(y1 - y0, x1 - x0) ninety = math.pi / 2 glVertex(x0 + size * math.cos(angle + ninety), y0 + size * math.sin(angle + ninety)) glVertex(x0 + size * math.cos(angle - ninety), y0 + size * math.sin(angle - ninety)) glVertex(x1 + size * math.cos(angle - ninety), y1 + size * math.sin(angle - ninety)) glVertex(x1 + size * math.cos(angle + ninety), y1 + size * math.sin(angle + ninety)) glEnd() def drawFilledCircle(self, x, y, radius, steps): pass