def initialize(self): glutPositionWindow(0, 600) GLRealtimeProgram.initialize(self) colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (0, 1, 1), (1, 0, 1)] for (i, cloud) in enumerate(self.clouds): point_list = glGenLists(i + 1) self.point_lists.append(point_list) # compile the point cloud glNewList(point_list, GL_COMPILE) glDisable(GL_LIGHTING) glBegin(GL_POINTS) for point in cloud: if len(point) == 2: xyz = point[0] rgb = point[1] else: xyz = point[:3] if len(point) == 4: rgb = point[3] elif len(point) > 4: rgb = point[3:6] else: rgb = None if rgb is not None: glColor3f(*map(lambda x: x / 255.0, rgb)) else: glColor3f(*colors[i % len(colors)]) glVertex3f(*xyz[:3]) glEnd() glEndList() logging.debug("compiled {} points for cloud {}".format(len(cloud), i))
def show_geometry(): glNewList(1, GL_COMPILE) glBegin(GL_TRIANGLES) glColor3f(1, 1, 1) vnum = dm.np_get_vertices(np_verts) tnum = dm.np_get_triangles_vertices(np_tris) dm.np_get_triangles_intensity(np_int) move_scale(np_verts[:vnum, :]) coords = np_verts[np_tris[:tnum, :], :] mi = coords[:, :, 0].min(axis=0) ma = coords[:, :, 0].max(axis=0) for f, vv in enumerate(coords): v1 = vv[2, :] - vv[0, :] v2 = vv[1, :] - vv[0, :] n = cross(v2, v1).squeeze() n /= norm(n) glNormal3f(*n) c = np_int[f] glColor3f(c, c, c) glVertex3f(*vv[0, :].squeeze()) glVertex3f(*vv[1, :].squeeze()) glVertex3f(*vv[2, :].squeeze()) glEnd() glEndList() return concatenate((mi, ma))
def make_sphere(): """ 创建球形的渲染函数列表 """ glNewList(G_OBJ_SPHERE, GL_COMPILE) quad = gluNewQuadric() gluSphere(quad, 0.5, 30, 30) gluDeleteQuadric(quad) glEndList()
def _make_list( self ): """generate opengl display list to draw triangles in mesh """ # get available list name self.list_name = glGenLists( 1 ) # start new display list glNewList( self.list_name, GL_COMPILE ) # set material glMaterialfv( GL_FRONT, GL_SPECULAR, self.specular ) glMaterialfv( GL_FRONT, GL_SHININESS, self.shininess ) glMaterialfv( GL_FRONT, GL_DIFFUSE, self.diffuse ) # start list of triangles in mesh glBegin( GL_TRIANGLES ) # for each triangle give normal and 3 vertices for triangle in self.triangles: glNormal3f( *triangle[0] ) for i in range( 1, 4 ): glVertex3f( *triangle[i] ) glEnd() glEndList()
def make_cube(): glNewList(G_OBJ_CUBE, GL_COMPILE) vertices = [((-0.5, -0.5, -0.5), (-0.5, -0.5, 0.5), (-0.5, 0.5, 0.5), (-0.5, 0.5, -0.5)), ((-0.5, -0.5, -0.5), (-0.5, 0.5, -0.5), (0.5, 0.5, -0.5), (0.5, -0.5, -0.5)), ((0.5, -0.5, -0.5), (0.5, 0.5, -0.5), (0.5, 0.5, 0.5), (0.5, -0.5, 0.5)), ((-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, 0.5)), ((-0.5, -0.5, 0.5), (-0.5, -0.5, -0.5), (0.5, -0.5, -0.5), (0.5, -0.5, 0.5)), ((-0.5, 0.5, -0.5), (-0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (0.5, 0.5, -0.5))] normals = [(-1.0, 0.0, 0.0), (0.0, 0.0, -1.0), (1.0, 0.0, 0.0), (0.0, 0.0, 1.0), (0.0, -1.0, 0.0), (0.0, 1.0, 0.0)] glBegin(GL_QUADS) for i in range(6): glNormal3f(normals[i][0], normals[i][1], normals[i][2]) for j in range(4): glVertex3f(vertices[i][j][0], vertices[i][j][1], vertices[i][j][2]) glEnd() glEndList()
def compile_total_list(self): if self.total_list is not None: glNewList(self.total_list, GL_COMPILE) # reset a few things glDisable(GL_DEPTH_TEST) glDisable(GL_LIGHTING) glMatrixMode(GL_PROJECTION) glLoadIdentity() glMatrixMode(GL_MODELVIEW) glLoadIdentity() # change the modelview to camera coordinates viewport = glGetIntegerv(GL_VIEWPORT) width = viewport[2] - viewport[0] height = viewport[3] - viewport[1] if width > height: w = float(width) / float(height) h = 1.0 else: w = 1.0 h = float(height) / float(width) glScalef(2/w, 2/h, 1.0) glCallList(self.draw_list) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) glEndList()
def make_Cylinder(): #2 #glNewList(G_OBJ_PLANE, GL_COMPILE) #2 #glLineWidth(50.0) #2 #glColor3f(0.0, 0.0, 0.0) #2 #glBegin(GL_LINES) #2 #glVertex3f(1.0, 0.0, 0.0) #2 #glVertex3f(0.0, 1.0, 0.0) #2 #glEnd() #2 #2 #glColor3f(1.0, 0.0, 0.0) #2 #glBegin(GL_TRIANGLE_STRIP) #2 #glVertex3f(1.000000 ,0.000000, 0.000000) #glVertex3f(0.000000, 1.000000, 0.000000) #glVertex3f(1.000000, 1.000000, 1.000000) #glEnd() glNewList(G_OBJ_CYLINDER, GL_COMPILE) quad = gluNewQuadric() gluCylinder(quad, 0.2, 0.2, 2.0, 32, 32) #半径半径长切分次数切分次数 #glRotatef(2, 0, 0, 1) gluDeleteQuadric(quad) glEndList() #2
def compile_total_list(self): if self.total_list is not None: glNewList(self.total_list, GL_COMPILE) # reset a few things glDisable(GL_DEPTH_TEST) glDisable(GL_LIGHTING) glMatrixMode(GL_PROJECTION) glLoadIdentity() glMatrixMode(GL_MODELVIEW) glLoadIdentity() # change the modelview to camera coordinates viewport = glGetIntegerv(GL_VIEWPORT) width = viewport[2] - viewport[0] height = viewport[3] - viewport[1] if width > height: w = float(width) / float(height) h = 1.0 else: w = 1.0 h = float(height) / float(width) glScalef(2 / w, 2 / h, 1.0) glCallList(self.draw_list) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) glEndList()
def make_plane(): glNewList(G_OBJ_PLANE, GL_COMPILE) glBegin(GL_LINES) glColor3f(0, 0, 0) for i in range(41): glVertex3f(-10.0 + 0.5* i, 0, -10) glVertex3f(-10.0 + 0.5* i, 0, 10) glVertex3f(-10.0, 0, -10+0.5*i) glVertex3f(10.0, 0, -10+0.5*i) #Axes glEnd() glLineWidth(5) glBegin(GL_LINES) glColor3f(0.5, 0.7, 0.5) glVertex3f(0.0, 0.0, 0.0) glVertex3f(5, 0.0, 0.0) glEnd() glBegin(GL_LINES) glColor3f(0.5, 0.7, 0.5) glVertex3f(0.0, 0.0, 0.0) glVertex3f(0.0, 5, 0.0) glBegin(GL_LINES) glColor3f(0.5, 0.7, 0.5) glVertex3f(0.0, 0.0, 0.0) glVertex3f(0.0, 0.0, 5)
def make_sphere(): """create ball's rend function list""" glNewList(G_OBJ_SPHERE, GL_COMPILE) quad = gluNewQuadric() gluSphere(quad, 0.5, 30, 30) gluDeleteQuadric(quad) glEndList()
def make_plane(): glNewList(G_OBJ_PLANE, GL_COMPILE) glBegin(GL_LINES) glColor3f(0, 0, 0) for i in xrange(41): glVertex3f(-10.0 + 0.5 * i, 0, -10) glVertex3f(-10.0 + 0.5 * i, 0, 10) glVertex3f(-10.0, 0, -10 + 0.5 * i) glVertex3f(10.0, 0, -10 + 0.5 * i) # Axes glEnd() glLineWidth(5) glBegin(GL_LINES) glColor3f(0.5, 0.7, 0.5) glVertex3f(0.0, 0.0, 0.0) glVertex3f(5, 0.0, 0.0) glEnd() glBegin(GL_LINES) glColor3f(0.5, 0.7, 0.5) glVertex3f(0.0, 0.0, 0.0) glVertex3f(0.0, 5, 0.0) glEnd() glBegin(GL_LINES) glColor3f(0.5, 0.7, 0.5) glVertex3f(0.0, 0.0, 0.0) glVertex3f(0.0, 0.0, 5) glEnd() # Draw the Y. glBegin(GL_LINES) glColor3f(0.0, 0.0, 0.0) glVertex3f(0.0, 5.0, 0.0) glVertex3f(0.0, 5.5, 0.0) glVertex3f(0.0, 5.5, 0.0) glVertex3f(-0.5, 6.0, 0.0) glVertex3f(0.0, 5.5, 0.0) glVertex3f(0.5, 6.0, 0.0) # Draw the Z. glVertex3f(-0.5, 0.0, 5.0) glVertex3f(0.5, 0.0, 5.0) glVertex3f(0.5, 0.0, 5.0) glVertex3f(-0.5, 0.0, 6.0) glVertex3f(-0.5, 0.0, 6.0) glVertex3f(0.5, 0.0, 6.0) # Draw the X. glVertex3f(5.0, 0.0, 0.5) glVertex3f(6.0, 0.0, -0.5) glVertex3f(5.0, 0.0, -0.5) glVertex3f(6.0, 0.0, 0.5) glEnd() glLineWidth(1) glEndList()
def __call__(self, name, *args, **kwargs): da = context.application.main.drawing_area if not da.get_gl_drawable().gl_begin(da.get_gl_context()): return glNewList(self.draw_list, GL_COMPILE) self.tools[name](*args, **kwargs) glEndList() da.get_gl_drawable().gl_end() da.queue_draw()
def compile(self): '''Compile the mesh in display list''' if self.list: return gllist = glGenLists(1) glNewList(gllist, GL_COMPILE) self.draw() glEndList() self.list = gllist
def start(self): '''Start recording GL operation''' global gl_displaylist_generate if gl_displaylist_generate: self.do_compile = False else: gl_displaylist_generate = True self.do_compile = True glNewList(self.dl, self.mode)
def _build(self): DisplayList.checkForInvalidCall("Nesting a display list construction inside a display lsit") DisplayList.isBuildingList = True glNewList(self.id, GL_COMPILE) try: self.builder() finally: glEndList() DisplayList.isBuildingList = False
def start(self, pickstate): #bruce 090224 split this out of caller """ Clear self and start collecting new primitives for use inside it. (They are collected by staticmethods in the ColorSorter singleton class, and saved partly in ColorSorter class attributes, partly in self by direct assignment (maybe not anymore), and partly in self by methods ColorSorter calls in self.) [meant to be called only by ColorSorter.start, for now] """ if pickstate is not None: # todo: refactor to remove this deprecated argument ### review: is it correct to not reset self.selected when this is None?? self.selectPick(pickstate) pass # Russ 080915: This supports lazily updating drawing caches. self.changed = drawing_constants.eventStamp() # Clear the primitive data to start collecting a new set. # REVIEW: is it good that we don't also deallocate DLs here? # Guess: yes if we reuse them, no if we don't. # It looks like finish calls _reset, which deallocates them, # so we might as well do that right here instead. Also, that # way I can remove _reset from finish, which is good since # I've made _reset clearPrimitives, which is a bug if done # in finish (when were added between start and finish). # [bruce 090224 comment and revision] ## self._clearPrimitives() self._reset() if 0: # keep around, in case we want a catchall DL in the future #bruce 090114 removed support for # [note: later: these are no longer in drawing_globals] # (not (drawing_globals.allow_color_sorting and # drawing_globals.use_color_sorted_dls)): # This is the beginning of the single display list created when # color sorting is turned off. It is ended in # ColorSorter.finish . In between, the calls to # draw{sphere,cylinder,polycone} methods pass through # ColorSorter.schedule_* but are immediately sent to *_worker # where they do OpenGL drawing that is captured into the display # list. try: if self.dl == 0: self.activate() # Allocate a display list for our use. pass # Start a single-level list. glNewList(self.dl, GL_COMPILE) except: print("data related to following exception: self.dl = %r" % (self.dl, )) #bruce 070521 raise pass return
def _compile(self, gl_id): global compiling_display_list compiling_display_list = True glNewList(gl_id, GL_COMPILE) try: self.do_setup() finally: glEndList() compiling_display_list = False
def start(self, pickstate): # bruce 090224 split this out of caller """ Clear self and start collecting new primitives for use inside it. (They are collected by staticmethods in the ColorSorter singleton class, and saved partly in ColorSorter class attributes, partly in self by direct assignment (maybe not anymore), and partly in self by methods ColorSorter calls in self.) [meant to be called only by ColorSorter.start, for now] """ if pickstate is not None: # todo: refactor to remove this deprecated argument ### review: is it correct to not reset self.selected when this is None?? self.selectPick(pickstate) pass # Russ 080915: This supports lazily updating drawing caches. self.changed = drawing_constants.eventStamp() # Clear the primitive data to start collecting a new set. # REVIEW: is it good that we don't also deallocate DLs here? # Guess: yes if we reuse them, no if we don't. # It looks like finish calls _reset, which deallocates them, # so we might as well do that right here instead. Also, that # way I can remove _reset from finish, which is good since # I've made _reset clearPrimitives, which is a bug if done # in finish (when were added between start and finish). # [bruce 090224 comment and revision] ## self._clearPrimitives() self._reset() if 0: # keep around, in case we want a catchall DL in the future # bruce 090114 removed support for # [note: later: these are no longer in drawing_globals] # (not (drawing_globals.allow_color_sorting and # drawing_globals.use_color_sorted_dls)): # This is the beginning of the single display list created when # color sorting is turned off. It is ended in # ColorSorter.finish . In between, the calls to # draw{sphere,cylinder,polycone} methods pass through # ColorSorter.schedule_* but are immediately sent to *_worker # where they do OpenGL drawing that is captured into the display # list. try: if self.dl == 0: self.activate() # Allocate a display list for our use. pass # Start a single-level list. glNewList(self.dl, GL_COMPILE) except: print("data related to following exception: self.dl = %r" % (self.dl,)) # bruce 070521 raise pass return
def create_obb_gl_list(obb): from OpenGL.GL import glGenLists, glNewList, glFrontFace, glBegin, glEnd, glEndList, glColor3fv, glVertex3fv, \ GL_CCW, GL_COMPILE, GL_LINES gl_list = glGenLists(1) glNewList(gl_list, GL_COMPILE) glFrontFace(GL_CCW) glBegin(GL_LINES) glColor3fv((1, 0, 0)) def input_vertex(x, y, z): glVertex3fv((obb.rotation[0][0] * x + obb.rotation[0][1] * y + obb.rotation[0][2] * z, obb.rotation[1][0] * x + obb.rotation[1][1] * y + obb.rotation[1][2] * z, obb.rotation[2][0] * x + obb.rotation[2][1] * y + obb.rotation[2][2] * z)) input_vertex(*obb.max) input_vertex(obb.max[0], obb.min[1], obb.max[2]) input_vertex(obb.max[0], obb.min[1], obb.max[2]) input_vertex(obb.min[0], obb.min[1], obb.max[2]) input_vertex(obb.min[0], obb.min[1], obb.max[2]) input_vertex(obb.min[0], obb.max[1], obb.max[2]) input_vertex(obb.min[0], obb.max[1], obb.max[2]) input_vertex(*obb.max) input_vertex(obb.max[0], obb.max[1], obb.max[2]) input_vertex(obb.max[0], obb.max[1], obb.min[2]) input_vertex(obb.max[0], obb.min[1], obb.max[2]) input_vertex(obb.max[0], obb.min[1], obb.min[2]) input_vertex(obb.min[0], obb.max[1], obb.max[2]) input_vertex(obb.min[0], obb.max[1], obb.min[2]) input_vertex(obb.min[0], obb.min[1], obb.max[2]) input_vertex(obb.min[0], obb.min[1], obb.min[2]) input_vertex(obb.max[0], obb.max[1], obb.min[2]) input_vertex(obb.max[0], obb.min[1], obb.min[2]) input_vertex(obb.max[0], obb.min[1], obb.min[2]) input_vertex(*obb.min) input_vertex(*obb.min) input_vertex(obb.min[0], obb.max[1], obb.min[2]) input_vertex(obb.min[0], obb.max[1], obb.min[2]) input_vertex(obb.max[0], obb.max[1], obb.min[2]) glEnd() glEndList() return gl_list
def render(self): if self.display_list is None: self.display_list = glGenLists(1) glNewList(self.display_list, GL_COMPILE) for cube in self.cubes: cube.render() glEndList() else: glCallList(self.display_list)
def build_from_render_function(self, name: str, f: callable, *args): """Uses an externally provided function to create 3d geometry to store in the view. :param name: the key this pre-computed geometry can be draw from. :param f: the function used to create the 3d geometry. :param args: any parameters the supplied function is expecting. """ new_gl_list = glGenLists(1) # pylint: disable=assignment-from-no-return glNewList(new_gl_list, GL_COMPILE) f(*args) glEndList() self._display_lists[name] = new_gl_list
def _setup_shaderCubeList(self): # not used self.shaderCubeList = glGenLists(1) glNewList(self.shaderCubeList, GL_COMPILE) verts = self.shaderCubeVerts indices = self.shaderCubeIndices glBegin(GL_QUADS) for i in range(6): for j in range(4): glVertex3fv(A(verts[indices[i][j]])) continue continue glEnd() glEndList()
def make_man(): glNewList(G_OBJ_MAN, GL_COMPILE) obj=OBJ('./OBJ/smpl_np.obj') vertices=obj.vertices face=obj.faces for i in range(len(face)): glColor3f(216 / 255, 186 / 255, 160 / 255) glBegin(GL_TRIANGLES) glNormal3f(face[i][1][0],face[i][1][1],face[i][1][2]) for j in range(3): glVertex3f(vertices[face[i][0][j]-1][0],vertices[face[i][0][j]-1][1],vertices[face[i][0][j]-1][2]) glEnd() glEndList()
def makeObject(self): genList = glGenLists(1) glNewList(genList, GL_COMPILE) glBegin(GL_QUADS) x1 = +0.06 y1 = -0.14 x2 = +0.14 y2 = -0.06 x3 = +0.08 y3 = +0.00 x4 = +0.30 y4 = +0.22 self.quad(x1, y1, x2, y2, y2, x2, y1, x1) self.quad(x3, y3, x4, y4, y4, x4, y3, x3) self.extrude(x1, y1, x2, y2) self.extrude(x2, y2, y2, x2) self.extrude(y2, x2, y1, x1) self.extrude(y1, x1, x1, y1) self.extrude(x3, y3, x4, y4) self.extrude(x4, y4, y4, x4) self.extrude(y4, x4, y3, x3) Pi = 3.14159265358979323846 NumSectors = 200 for i in range(NumSectors): angle1 = (i * 2 * Pi) / NumSectors x5 = 0.30 * math.sin(angle1) y5 = 0.30 * math.cos(angle1) x6 = 0.20 * math.sin(angle1) y6 = 0.20 * math.cos(angle1) angle2 = ((i + 1) * 2 * Pi) / NumSectors x7 = 0.20 * math.sin(angle2) y7 = 0.20 * math.cos(angle2) x8 = 0.30 * math.sin(angle2) y8 = 0.30 * math.cos(angle2) self.quad(x5, y5, x6, y6, x7, y7, x8, y8) self.extrude(x6, y6, x7, y7) self.extrude(x8, y8, x5, y5) glEnd() glEndList() return genList
def start(csdl, pickstate = None): """ Start sorting - objects provided to "schedule" and primitives such as "schedule_sphere" and "schedule_cylinder" will be stored for a sort at the time "finish" is called. csdl is a ColorSortedDisplayList or None, in which case immediate drawing is done. pickstate (optional) indicates whether the parent is currently selected. """ #russ 080225: Moved glNewList here for displist re-org. ColorSorter.parent_csdl = csdl # Remember, used by finish(). if pickstate is not None: csdl.selectPick(pickstate) pass if csdl != None: if not (drawing_globals.allow_color_sorting and (drawing_globals.use_color_sorted_dls or drawing_globals.use_color_sorted_vbos)): #russ 080320 # This is the beginning of the single display list created when # color sorting is turned off. It is ended in # ColorSorter.finish . In between, the calls to # draw{sphere,cylinder,polycone} methods pass through # ColorSorter.schedule_* but are immediately sent to *_worker # where they do OpenGL drawing that is captured into the display # list. try: if csdl.dl == 0: csdl.activate() # Allocate a display list for our use. pass # Start a single-level list. glNewList(csdl.dl, GL_COMPILE_AND_EXECUTE) except: print ("data related to following exception: csdl.dl = %r" % (csdl.dl,)) #bruce 070521 raise assert not ColorSorter.sorting, \ "Called ColorSorter.start but already sorting?!" ColorSorter.sorting = True if drawing_globals.use_c_renderer and ColorSorter.sorting: ColorSorter._cur_shapelist = ShapeList_inplace() ColorSorter.sphereLevel = -1 else: ColorSorter.sorted_by_color = {}
def start(csdl, pickstate=None): """ Start sorting - objects provided to "schedule" and primitives such as "schedule_sphere" and "schedule_cylinder" will be stored for a sort at the time "finish" is called. csdl is a ColorSortedDisplayList or None, in which case immediate drawing is done. pickstate (optional) indicates whether the parent is currently selected. """ #russ 080225: Moved glNewList here for displist re-org. ColorSorter.parent_csdl = csdl # Remember, used by finish(). if pickstate is not None: csdl.selectPick(pickstate) pass if csdl != None: if not (drawing_globals.allow_color_sorting and (drawing_globals.use_color_sorted_dls or drawing_globals.use_color_sorted_vbos)): #russ 080320 # This is the beginning of the single display list created when # color sorting is turned off. It is ended in # ColorSorter.finish . In between, the calls to # draw{sphere,cylinder,polycone} methods pass through # ColorSorter.schedule_* but are immediately sent to *_worker # where they do OpenGL drawing that is captured into the display # list. try: if csdl.dl == 0: csdl.activate() # Allocate a display list for our use. pass # Start a single-level list. glNewList(csdl.dl, GL_COMPILE_AND_EXECUTE) except: print("data related to following exception: csdl.dl = %r" % (csdl.dl, )) #bruce 070521 raise assert not ColorSorter.sorting, \ "Called ColorSorter.start but already sorting?!" ColorSorter.sorting = True if drawing_globals.use_c_renderer and ColorSorter.sorting: ColorSorter._cur_shapelist = ShapeList_inplace() ColorSorter.sphereLevel = -1 else: ColorSorter.sorted_by_color = {}
def create_gl_list(shape): from OpenGL.GL import glGenLists, glNewList, glFrontFace, glBegin, glEnd, glEndList, glNormal3fv, glVertex3fv, \ GL_COMPILE, GL_CCW, GL_TRIANGLES vertices = shape['vertices'] normals = shape['normals'] indices = shape['indices'] gl_list = glGenLists(1) glNewList(gl_list, GL_COMPILE) glFrontFace(GL_CCW) glBegin(GL_TRIANGLES) for idx in indices: glNormal3fv(normals[idx]) glVertex3fv(vertices[idx]) glEnd() glEndList() return gl_list
def make_cube(): glNewList(G_OBJ_CUBE, GL_COMPILE) vertices = [((-0.5, -0.5, -0.5), (-0.5, -0.5, 0.5), (-0.5, 0.5, 0.5), (-0.5, 0.5, -0.5)), ((-0.5, -0.5, -0.5), (-0.5, 0.5, -0.5), (0.5, 0.5, -0.5), (0.5, -0.5, -0.5)), ((0.5, -0.5, -0.5), (0.5, 0.5, -0.5), (0.5, 0.5, 0.5), (0.5, -0.5, 0.5)), ((-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, 0.5)), ((-0.5, -0.5, 0.5), (-0.5, -0.5, -0.5), (0.5, -0.5, -0.5), (0.5, -0.5, 0.5)), ((-0.5, 0.5, -0.5), (-0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (0.5, 0.5, -0.5))] normals = [(-1.0, 0.0, 0.0), (0.0, 0.0, -1.0), (1.0, 0.0, 0.0), (0.0, 0.0, 1.0), (0.0, -1.0, 0.0), (0.0, 1.0, 0.0)] glBegin(GL_QUADS) for i in xrange(6): glNormal3f(normals[i][0], normals[i][1], normals[i][2]) for j in xrange(4): glVertex3f(vertices[i][j][0], vertices[i][j][1], vertices[i][j][2]) glEnd() glEndList()
def __init__(self, glpane): """ @param glpane: typically a QGLWidget; used only for its methods glpane.qglColor and glpane.renderText. @warning: the right OpenGL display list context must be current when this constructor is called. """ self.glpane = glpane self._compass_dl = glGenLists(1) glNewList(self._compass_dl, GL_COMPILE) _draw_compass_geometry() glEndList() self._font = QFont( QString("Helvetica"), 12) return
def _anotherDraw(self, layerColor): """ The original way of selecting cookies, but do it layer by layer, so we can control how to display each layer. """ if self.havelist: glCallList(self.displist.dl) return glNewList(self.displist.dl, GL_COMPILE_AND_EXECUTE) for layer in self.layeredCurves.keys(): bbox = self.layeredCurves[layer][0] curves = self.layeredCurves[layer][1:] if not curves: continue color = layerColor[layer] for c in curves: c.draw() try: bblo, bbhi = bbox.data[1], bbox.data[0] allCells = genDiam(bblo - 1.6, bbhi + 1.6, self.latticeType) for cell in allCells: for pp in cell: p1 = p2 = None if self.isin(pp[0], curves): if self.isin(pp[1], curves): p1 = pp[0] p2 = pp[1] else: p1 = pp[0] p2 = ((pp[1] + pp[0]) / 2, ) elif self.isin(pp[1], curves): p1 = pp[1] p2 = ((pp[1] + pp[0]) / 2, ) if p1 and p2: self._cellDraw(color, p1, p2) except: # bruce 041028 -- protect against exceptions while making display # list, or OpenGL will be left in an unusable state (due to the lack # of a matching glEndList) in which any subsequent glNewList is an # invalid operation. (Also done in chem.py; see more comments there.) print_compact_traceback( "bug: exception in shape.draw's displist; ignored: ") glEndList() self.havelist = 1 # return
def prepDraw(self): glNewList(self.dl,GL_COMPILE) c = self.corners for h in c: glPushMatrix( ) glTranslatef(h.x,h.y,h.z) q = gluNewQuadric() gluSphere( q, GLdouble(0.45), GLint(10), GLint(10) ) glPopMatrix( ) glBegin(GL_QUADS) glVertex3fv(adaptVec(c[0])) glVertex3fv(adaptVec(c[2])) glVertex3fv(adaptVec(c[6])) glVertex3fv(adaptVec(c[4])) glVertex3fv(adaptVec(c[1])) glVertex3fv(adaptVec(c[3])) glVertex3fv(adaptVec(c[7])) glVertex3fv(adaptVec(c[5])) glVertex3fv(adaptVec(c[0])) glVertex3fv(adaptVec(c[1])) glVertex3fv(adaptVec(c[3])) glVertex3fv(adaptVec(c[2])) glVertex3fv(adaptVec(c[2])) glVertex3fv(adaptVec(c[3])) glVertex3fv(adaptVec(c[7])) glVertex3fv(adaptVec(c[6])) glVertex3fv(adaptVec(c[7])) glVertex3fv(adaptVec(c[6])) glVertex3fv(adaptVec(c[4])) glVertex3fv(adaptVec(c[5])) glVertex3fv(adaptVec(c[0])) glVertex3fv(adaptVec(c[1])) glVertex3fv(adaptVec(c[5])) glVertex3fv(adaptVec(c[4])) glEnd() glEndList()
def prepDraw(self): glNewList(self.dl, GL_COMPILE) c = self.corners for h in c: glPushMatrix() glTranslatef(h.x, h.y, h.z) q = gluNewQuadric() gluSphere(q, GLdouble(0.45), GLint(10), GLint(10)) glPopMatrix() glBegin(GL_QUADS) glVertex3fv(adaptVec(c[0])) glVertex3fv(adaptVec(c[2])) glVertex3fv(adaptVec(c[6])) glVertex3fv(adaptVec(c[4])) glVertex3fv(adaptVec(c[1])) glVertex3fv(adaptVec(c[3])) glVertex3fv(adaptVec(c[7])) glVertex3fv(adaptVec(c[5])) glVertex3fv(adaptVec(c[0])) glVertex3fv(adaptVec(c[1])) glVertex3fv(adaptVec(c[3])) glVertex3fv(adaptVec(c[2])) glVertex3fv(adaptVec(c[2])) glVertex3fv(adaptVec(c[3])) glVertex3fv(adaptVec(c[7])) glVertex3fv(adaptVec(c[6])) glVertex3fv(adaptVec(c[7])) glVertex3fv(adaptVec(c[6])) glVertex3fv(adaptVec(c[4])) glVertex3fv(adaptVec(c[5])) glVertex3fv(adaptVec(c[0])) glVertex3fv(adaptVec(c[1])) glVertex3fv(adaptVec(c[5])) glVertex3fv(adaptVec(c[4])) glEnd() glEndList()
def orthogonalPass(self): """ display FPS. """ secs = self.passedSecs self.timePassed += secs if self.timePassed>=1.0: self.timePassed -= 1.0 fps = self.getFPS() if fps!=self.FPS: self.FPS = fps glNewList(self.fpsDisplayList, GL_COMPILE) self.printFPS(5, self.fpsY, "FPS %d" % self.FPS) glEndList() # we expect to be in orthogonal projection now glCallList(self.fpsDisplayList)
def glNewList(self, listname, mode, owner=None): """ Execute glNewList, after verifying args are ok and we don't think we're compiling a display list now. (The OpenGL call is illegal if we're *actually* compiling one now. Even if it detects that error (as is likely), it's not a redundant check, since our internal flag about whether we're compiling one could be wrong.) If owner is provided, record it privately (until glEndList) as the owner of the display list being compiled. This allows information to be tracked in owner or using it, like the set of sublists directly called by owner's list. Any initialization of tracking info in owner is up to our caller.###k doit """ #e make our GL context current? no need -- callers already had to know that to safely call the original form of glNewList #e assert it's current? yes -- might catch old bugs -- but not yet practical to do. assert self.compiling_displist == 0 assert self.compiling_displist_owned_by is None assert listname glNewList(listname, mode) self.compiling_displist = listname self.compiling_displist_owned_by = owner # optional arg in general, but required for the tracking done in this module return
def _anotherDraw(self, layerColor): """ The original way of selecting cookies, but do it layer by layer, so we can control how to display each layer. """ if self.havelist: glCallList(self.displist.dl) return glNewList(self.displist.dl, GL_COMPILE_AND_EXECUTE) for layer in self.layeredCurves.keys(): bbox = self.layeredCurves[layer][0] curves = self.layeredCurves[layer][1:] if not curves: continue color = layerColor[layer] for c in curves: c.draw() try: bblo, bbhi = bbox.data[1], bbox.data[0] allCells = genDiam(bblo - 1.6, bbhi + 1.6, self.latticeType) for cell in allCells: for pp in cell: p1 = p2 = None if self.isin(pp[0], curves): if self.isin(pp[1], curves): p1 = pp[0] p2 = pp[1] else: p1 = pp[0] p2 = ((pp[1] + pp[0]) / 2,) elif self.isin(pp[1], curves): p1 = pp[1] p2 = ((pp[1] + pp[0]) / 2,) if p1 and p2: self._cellDraw(color, p1, p2) except: # bruce 041028 -- protect against exceptions while making display # list, or OpenGL will be left in an unusable state (due to the lack # of a matching glEndList) in which any subsequent glNewList is an # invalid operation. (Also done in chem.py; see more comments there.) print_compact_traceback("bug: exception in shape.draw's displist; ignored: ") glEndList() self.havelist = 1 # return
def displayListify(name): global displayLists if name in displayLists: # Hey, we've made this display list before! # Run the existing list, then break out of the with block glCallList(displayLists[name]) try: yield True except LeaveWith: pass else: # Nope, not made this display list. Wrap the block in "work rememberers" displayLists[name] = thisList = glGenLists(1) glNewList(thisList, GL_COMPILE_AND_EXECUTE) try: yield finally: glEndList()
def make_mesh(): glNewList(G_OBJ_MESH,GL_COMPILE) vertices=[[1.0,0.0,1.0],[0.0,0.0,-1.0],[-1.0,0.0,1.0],[0.0,1.0,0.0]] face=[[1,4,3],[1,2,4],[2,3,4],[1,3,2]] for i in range(len(face)): glColor3f(216/255,186/255,160/255) point0=np.array(vertices[face[i][0]-1]) point1 = np.array(vertices[face[i][1]-1]) point2 =np.array(vertices[face[i][2]-1]) A=point1-point0 B=point0-point2 C = np.cross(B, A) N = C/np.linalg.norm(C) glBegin(GL_TRIANGLES) glNormal3f(N[0],N[1],N[2]) for j in range(3): glVertex3f(vertices[face[i][j]-1][0],vertices[face[i][j]-1][1],vertices[face[i][j]-1][2]) glEnd() glEndList()
def generate_disp_list(self): if (self.filename, self.bezier_points) in self._disp_list_cache: self.disp_list, self.width, self.height = self._disp_list_cache[self.filename, self.bezier_points] else: if self.rawdata != None: f = StringIO(self.rawdata) else: if open(self.filename, 'rb').read(3) == '\x1f\x8b\x08': #gzip magic numbers import gzip f = gzip.open(self.filename, 'rb') else: f = open(self.filename, 'rb') self.tree = parse(f) self.parse_doc() self.disp_list = glGenLists(1) glNewList(self.disp_list, GL_COMPILE) self.render_slowly() glEndList() self._disp_list_cache[self.filename, self.bezier_points] = (self.disp_list, self.width, self.height)
def openglSetup(self): glClearColor(0.0, 0.0, 0.0, 0.0) glEnable(GL.GL_DEPTH_TEST) glEnable(GL.GL_COLOR_MATERIAL) glViewport (0, 0, self.surf.get_width(), self.surf.get_height()) glMatrixMode (GL.GL_PROJECTION) glLoadIdentity () glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0) glMatrixMode (GL.GL_MODELVIEW) self.cardList = glGenLists(1) glNewList(self.cardList, GL.GL_COMPILE) glColor3f(1,1,1) with begin(GL.GL_QUADS): glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0) glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0, 0.0) glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 0.0) glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 0.0) glEndList()
def glNewList(self, listname, mode, owner=None): """ Execute glNewList, after verifying args are ok and we don't think we're compiling a display list now. (The OpenGL call is illegal if we're *actually* compiling one now. Even if it detects that error (as is likely), it's not a redundant check, since our internal flag about whether we're compiling one could be wrong.) If owner is provided, record it privately (until glEndList) as the owner of the display list being compiled. This allows information to be tracked in owner or using it, like the set of sublists directly called by owner's list. Any initialization of tracking info in owner is up to our caller.###k doit """ # e make our GL context current? no need -- callers already had to know that to safely call the original form of glNewList # e assert it's current? yes -- might catch old bugs -- but not yet practical to do. assert self.compiling_displist == 0 assert self.compiling_displist_owned_by is None assert listname glNewList(listname, mode) self.compiling_displist = listname self.compiling_displist_owned_by = ( owner ) # optional arg in general, but required for the tracking done in this module return
def setup_draw_grid_lines(): """ This must be called in whichever GL display list context will be drawn in. See comment in drawer.setup_drawer about problems with calling this in more than one GL context. For now, it shouldn't be. """ global SiCGridList SiCGridList = glGenLists(1) glNewList(SiCGridList, GL_COMPILE) glBegin(GL_LINES) glVertex3fv(sic_vpdat[0]) glVertex3fv(sic_vpdat[2]) glEnd() glBegin(GL_LINE_STRIP) for v in sic_vpdat[1:]: glVertex3fv(v) glEnd() glEndList() return
def build_from_mesh_data(self, mesh_data: MeshData): """Uses a loaded mesh to create 3d geometry to store in the view. All groups in the mesh will pre-computed and stored by name. :param mesh_data: the source data that 3d geometry will be pre-computed from. """ material_library = mesh_data.material_library for key in mesh_data.groups: new_gl_list = glGenLists(1) # pylint: disable=assignment-from-no-return glNewList(new_gl_list, GL_COMPILE) group = mesh_data.groups[key] glEnable(GL_TEXTURE_2D) glFrontFace(GL_CCW) for face in group.faces: self._apply_material( material_library.get_material_by_name(face.material)) # Polygon (N verts) with optional normals and tex coords glBegin(GL_POLYGON) for i in range(face.vertex_count): normal_index = face.normal_ids[i] if normal_index > 0: glNormal3fv(mesh_data.normals[normal_index - 1]) tex_coord_index = face.tex_ids[i] if tex_coord_index > 0: glTexCoord2fv(mesh_data.tex_coords[tex_coord_index - 1]) glVertex3fv(mesh_data.vertices[face.position_ids[i] - 1]) glEnd() glDisable(GL_TEXTURE_2D) glEndList() self._display_lists[key] = new_gl_list
def make_sphere(): glNewList(G_OBJ_SPHERE, GL_COMPILE) quad = gluNewQuadric() gluSphere(quad, 0.5, 30, 30) gluDeleteQuadric(quad) glEndList()
def test_drawing(glpane, initOnly = False): """ When TEST_DRAWING is enabled at the start of graphics/widgets/GLPane_rendering_methods.py, and when TestGraphics_Command is run (see its documentation for various ways to do that), this file is loaded and GLPane.paintGL() calls the test_drawing() function instead of the usual body of paintGL(). """ # WARNING: this duplicates some code with test_Draw_model(). # Load the sphere shaders if needed. global _USE_SHADERS if _USE_SHADERS: if not drawing_globals.test_sphereShader: print "test_drawing: Loading sphere shaders." try: from graphics.drawing.gl_shaders import GLSphereShaderObject drawing_globals.test_sphereShader = GLSphereShaderObject() ##### REVIEW: is this compatible with my refactoring in drawing_globals? # If not, use of Test Graphics Performance command might cause subsequent # bugs in other code. Ideally we'd call the new methods that encapsulate # this, to setup shaders. [bruce 090304 comment] print "test_drawing: Sphere-shader initialization is complete.\n" except: _USE_SHADERS = False print "test_drawing: Exception while loading sphere shaders, will reraise and not try again" raise pass global start_pos, first_time if first_time: # Set up the viewing scale, but then let interactive zooming work. glpane.scale = nSpheres * .6 pass # This same function gets called to set up for drawing, and to draw. if not initOnly: glpane._setup_modelview() glpane._setup_projection() ##glpane._compute_frustum_planes() glClearColor(64.0, 64.0, 64.0, 1.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ) ##glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) glMatrixMode(GL_MODELVIEW) pass global test_csdl, test_dl, test_dls, test_ibo, test_vbo, test_spheres global test_DrawingSet, test_endpoints, test_Object # See below for test case descriptions and timings on a MacBook Pro. # The Qt event toploop in NE1 tops out at about 60 frames-per-second. # NE1 with test toploop, single CSDL per draw (test case 1) # . 17,424 spheres (132x132, through the color sorter) 4.8 FPS # Russ 080919: More recently, 12.2 FPS. # . Level 2 spheres have 9 triangles x 20 faces, 162 distinct vertices, # visited on the average 2.3 times, giving 384 tri-strip vertices. # . 17,424 spheres is 6.7 million tri-strip vertices. (6,690,816) if testCase == 1: if test_csdl is None: print ("Test case 1, %d^2 spheres\n %s." % (nSpheres, "ColorSorter")) test_csdl = ColorSortedDisplayList() ColorSorter.start(None, test_csdl) drawsphere([0.5, 0.5, 0.5], # color [0.0, 0.0, 0.0], # pos .5, # radius DRAWSPHERE_DETAIL_LEVEL, testloop = nSpheres ) ColorSorter.finish(draw_now = True) pass else: test_csdl.draw() pass # NE1 with test toploop, single display list per draw (test case 2) # . 10,000 spheres (all drawing modes) 17.5 FPS # . 17,424 spheres (132x132, manual display list) 11.1 FPS # . 40,000 spheres (mode 5 - VBO/IBO spheres from DL's) 2.2 FPS # . 40,000 spheres (mode 6 - Sphere shaders from DL's) 2.5 FPS # . 90,000 spheres (all drawing modes) 1.1 FPS elif testCase == 2: if test_dl is None: print ("Test case 2, %d^2 spheres\n %s." % (nSpheres, "One display list calling primitive dl's")) test_dl = glGenLists(1) glNewList(test_dl, GL_COMPILE_AND_EXECUTE) drawsphere_worker_loop(([0.0, 0.0, 0.0], # pos .5, # radius DRAWSPHERE_DETAIL_LEVEL, nSpheres )) glEndList() pass else: glColor3i(127, 127, 127) glCallList(test_dl) pass # NE1 with test toploop, one big chunk VBO/IBO of box quads (test case 3) # . 17,424 spheres (1 box/shader draw call) 43.7 FPS # . 17,424 spheres (1 box/shader draw call w/ rad/ctrpt attrs) 57.7 FPS # . 40,000 spheres (1 box/shader draw call w/ rad/ctrpt attrs) 56.7 FPS # . 90,000 spheres (1 box/shader draw call w/ rad/ctrpt attrs) 52.7 FPS # . 160,000 spheres (1 box/shader draw call w/ rad/ctrpt attrs) 41.4 FPS # . 250,000 spheres (1 box/shader draw call w/ rad/ctrpt attrs) 27.0 FPS elif int(testCase) == 3: doTransforms = False if test_spheres is None: print ("Test case 3, %d^2 spheres\n %s." % (nSpheres, "One big VBO/IBO chunk buffer")) if testCase == 3.1: print ("Sub-test 3.1, animate partial updates.") elif testCase == 3.2: print ("Sub-test 3.2, animate partial updates" + " w/ C per-chunk array buffering.") elif testCase == 3.3: print ("Sub-test 3.3, animate partial updates" + " w/ Python array buffering.") # . 3.4 - Big batch draw, with transforms indexed by IDs added. # (Second FPS number with debug colors in the vertex shader off.) # - 90,000 (300x300) spheres, TEXTURE_XFORMS = True, 26(29) FPS # - 90,000 (300x300) spheres, N_CONST_XFORMS = 250, 26(29) FPS # - 90,000 (300x300) spheres, N_CONST_XFORMS = 275, 0.3(0.6) FPS # (What happens after 250? CPU usage goes from 40% to 94%.) # -160,000 (400x400) spheres, TEXTURE_XFORMS = True, 26 FPS # -250,000 (500x500) spheres, TEXTURE_XFORMS = True, 26 FPS elif testCase == 3.4: print ("Sub-test 3.4, add transforms indexed by IDs.") from graphics.drawing.gl_shaders import TEXTURE_XFORMS from graphics.drawing.gl_shaders import N_CONST_XFORMS from graphics.drawing.gl_shaders import UNIFORM_XFORMS if TEXTURE_XFORMS: print "Transforms in texture memory." elif UNIFORM_XFORMS: print "%d transforms in uniform memory." % N_CONST_XFORMS pass else: print "transforms not supported, error is likely" doTransforms = True pass centers = [] radius = .5 radii = [] colors = [] if not doTransforms: transformIDs = None else: transformIDs = [] transformChunkID = -1 # Allocate IDs sequentially from 0. # For this test, allow arbitrarily chunking the primitives. primCounter = transformChunkLength transforms = [] # Accumulate transforms as a list of lists. # Initialize transforms with an identity matrix. # Transforms here are lists (or Numpy arrays) of 16 numbers. identity = ([1.0] + 4*[0.0]) * 3 + [1.0] pass for x in range(nSpheres): for y in range(nSpheres): centers += [sphereLoc(x, y)] # Sphere radii progress from 3/4 to full size. t = float(x+y)/(nSpheres+nSpheres) # 0 to 1 fraction. thisRad = radius * (.75 + t*.25) radii += [thisRad] # Colors progress from red to blue. colors += [rainbow(t)] # Transforms go into a texture memory image if needed. # Per-primitive Transform IDs go into an attribute VBO. if doTransforms: primCounter = primCounter + 1 if primCounter >= transformChunkLength: # Start a new chunk, allocating a transform matrix. primCounter = 0 transformChunkID += 1 if 0: # 1 # Debug hack: Label mat[0,0] with the chunk ID. # Vertex shader debug code shows these in blue. # If viewed as geometry, it will be a slight # stretch of the array in the X direction. transforms += [ [1.0+transformChunkID/100.0] + identity[1:]] elif 0: # 1 # Debug hack: Fill mat with mat.element pattern. transforms += [ [transformChunkID + i/100.0 for i in range(16)]] else: transforms += [identity] pass pass # All of the primitives in a chunk have the same ID. transformIDs += [transformChunkID] pass continue continue test_spheres = GLSphereBuffer() test_spheres.addSpheres(centers, radii, colors, transformIDs, None) if doTransforms: print ("%d primitives in %d transform chunks of size <= %d" % (nSpheres * nSpheres, len(transforms), transformChunkLength)) shader = drawing_globals.test_sphereShader shader.setupTransforms(transforms) pass else: shader = drawing_globals.test_sphereShader shader.configShader(glpane) # Update portions for animation. pulse = time.time() pulse -= floor(pulse) # 0 to 1 in each second # Test animating updates on 80% of the radii in 45% of the columns. # . 3.1 - Update radii Python array per-column, send to graphics RAM. # - 2,500 (50x50) spheres 55 FPS # - 10,000 (100x100) spheres 35 FPS # - 17,424 (132x132) spheres 22.2 FPS # - 40,000 (200x200) spheres 12.4 FPS # - 90,000 (300x300) spheres 6.0 FPS if testCase == 3.1: # Not buffered, send each column change. radius = .5 margin = nSpheres/10 for x in range(margin, nSpheres, 2): radii = [] for y in range(margin, nSpheres-margin): t = float(x+y)/(nSpheres+nSpheres) # 0 to 1 fraction. # Sphere radii progress from 3/4 to full size. thisRad = radius * (.75 + t*.25) phase = pulse + float(x+y)/nSpheres radii += 8 * [thisRad-.1 + .1*sin(phase * 2*pi)] continue C_radii = numpy.array(radii, dtype=numpy.float32) offset = x*nSpheres + margin test_spheres.radii_vbo.update(offset * 8, C_radii) continue pass # . 3.2 - Numpy buffered in C array, subscript assignments to C. # - 2,500 (50x50) spheres 48 FPS # - 10,000 (100x100) spheres 17.4 FPS # - 17,424 (132x132) spheres 11.2 FPS # - 40,000 (200x200) spheres 5.5 FPS # - 90,000 (300x300) spheres 2.5 FPS elif testCase == 3.2: # Buffered per-chunk at the C array level. radius = .5 margin = nSpheres/10 global C_array if C_array is None: # Replicate. C_array = numpy.zeros((8 * (nSpheres-(2*margin)),), dtype=numpy.float32) pass for x in range(margin, nSpheres, 2): count = 0 for y in range(margin, nSpheres-margin): t = float(x+y)/(nSpheres+nSpheres) # 0 to 1 fraction. # Sphere radii progress from 3/4 to full size. thisRad = radius * (.75 + t*.25) phase = pulse + float(x+y)/nSpheres C_array[count*8:(count+1)*8] = \ thisRad-.1 + .1*sin(phase * 2*pi) count += 1 continue offset = x*nSpheres + margin test_spheres.radii_vbo.update(offset * 8, C_array) continue pass # . 3.3 - updateRadii in Python array, copy via C to graphics RAM. # - 2,500 (50x50) spheres 57 FPS # - 10,000 (100x100) spheres 32 FPS # - 17,424 (132x132) spheres 20 FPS # - 40,000 (200x200) spheres 10.6 FPS # - 90,000 (300x300) spheres 4.9 FPS elif testCase == 3.3: # Buffered at the Python level, batch the whole-array update. radius = .5 margin = nSpheres/10 for x in range(margin, nSpheres, 2): radii = [] for y in range(margin, nSpheres-margin): t = float(x+y)/(nSpheres+nSpheres) # 0 to 1 fraction. # Sphere radii progress from 3/4 to full size. thisRad = radius * (.75 + t*.25) phase = pulse + float(x+y)/nSpheres radii += [thisRad-.1 + .1*sin(phase * 2*pi)] continue test_spheres.updateRadii( # Update, but don't send yet. x*nSpheres + margin, radii, send = False) continue test_spheres.sendRadii() pass # Options: color = [0.0, 1.0, 0.0], transform_id = 1, radius = 1.0 test_spheres.draw() pass # NE1 with test toploop, separate sphere VBO/IBO box/shader draws (test case 4) # . 17,424 spheres (132x132 box/shader draw quads calls) 0.7 FPS elif testCase == 4: if test_ibo is None: print ("Test case 4, %d^2 spheres\n %s." % (nSpheres, "Separate VBO/IBO shader/box buffer sphere calls, no DL")) # Collect transformed bounding box vertices and offset indices. # Start at the lower-left corner, offset so the whole pattern comes # up centered on the origin. cubeVerts = drawing_globals.shaderCubeVerts cubeIndices = drawing_globals.shaderCubeIndices C_indices = numpy.array(cubeIndices, dtype=numpy.uint32) test_ibo = GLBufferObject( GL_ELEMENT_ARRAY_BUFFER_ARB, C_indices, GL_STATIC_DRAW) test_ibo.unbind() C_verts = numpy.array(cubeVerts, dtype=numpy.float32) test_vbo = GLBufferObject( GL_ARRAY_BUFFER_ARB, C_verts, GL_STATIC_DRAW) test_vbo.unbind() pass else: drawing_globals.test_sphereShader.configShader(glpane) glEnableClientState(GL_VERTEX_ARRAY) test_vbo.bind() # Vertex data comes from the vbo. glVertexPointer(3, GL_FLOAT, 0, None) drawing_globals.test_sphereShader.setActive(True) glDisable(GL_CULL_FACE) glColor3i(127, 127, 127) test_ibo.bind() # Index data comes from the ibo. for x in range(nSpheres): for y in range(nSpheres): # From drawsphere_worker_loop(). pos = start_pos + (x+x/10+x/100) * V(1, 0, 0) + \ (y+y/10+y/100) * V(0, 1, 0) radius = .5 glPushMatrix() glTranslatef(pos[0], pos[1], pos[2]) glScale(radius,radius,radius) glDrawElements(GL_QUADS, 6 * 4, GL_UNSIGNED_INT, None) glPopMatrix() continue continue drawing_globals.test_sphereShader.setActive(False) glEnable(GL_CULL_FACE) test_ibo.unbind() test_vbo.unbind() glDisableClientState(GL_VERTEX_ARRAY) pass # NE1 with test toploop, # One DL around separate VBO/IBO shader/box buffer sphere calls (test case 5) # . 17,424 spheres (1 box/shader DL draw call) 9.2 FPS elif testCase == 5: if test_dl is None: print ("Test case 5, %d^2 spheres\n %s." % (nSpheres, "One DL around separate VBO/IBO shader/box buffer sphere calls")) # Collect transformed bounding box vertices and offset indices. # Start at the lower-left corner, offset so the whole pattern comes # up centered on the origin. cubeVerts = drawing_globals.shaderCubeVerts cubeIndices = drawing_globals.shaderCubeIndices C_indices = numpy.array(cubeIndices, dtype=numpy.uint32) test_ibo = GLBufferObject( GL_ELEMENT_ARRAY_BUFFER_ARB, C_indices, GL_STATIC_DRAW) test_ibo.unbind() C_verts = numpy.array(cubeVerts, dtype=numpy.float32) test_vbo = GLBufferObject( GL_ARRAY_BUFFER_ARB, C_verts, GL_STATIC_DRAW) test_vbo.unbind() # Wrap a display list around the draws. test_dl = glGenLists(1) glNewList(test_dl, GL_COMPILE_AND_EXECUTE) glEnableClientState(GL_VERTEX_ARRAY) test_vbo.bind() # Vertex data comes from the vbo. glVertexPointer(3, GL_FLOAT, 0, None) drawing_globals.test_sphereShader.setActive(True) glDisable(GL_CULL_FACE) glColor3i(127, 127, 127) test_ibo.bind() # Index data comes from the ibo. for x in range(nSpheres): for y in range(nSpheres): # From drawsphere_worker_loop(). pos = start_pos + (x+x/10+x/100) * V(1, 0, 0) + \ (y+y/10+y/100) * V(0, 1, 0) radius = .5 glPushMatrix() glTranslatef(pos[0], pos[1], pos[2]) glScale(radius,radius,radius) glDrawElements(GL_QUADS, 6 * 4, GL_UNSIGNED_INT, None) glPopMatrix() continue continue drawing_globals.test_sphereShader.setActive(False) glEnable(GL_CULL_FACE) test_ibo.unbind() test_vbo.unbind() glDisableClientState(GL_VERTEX_ARRAY) glEndList() else: glColor3i(127, 127, 127) glCallList(test_dl) pass pass # NE1 with test toploop, # N column DL's around VBO/IBO shader/box buffer sphere calls (test case 6) # . 2,500 (50x50) spheres 58 FPS # . 10,000 (100x100) spheres 57 FPS # . 17,424 (132x132) spheres 56 FPS # . 40,000 (200x200) spheres 50 FPS # . 90,000 (300x300) spheres 28 FPS # . 160,000 (400x400) spheres 16.5 FPS # . 250,000 (500x500) spheres 3.2 FPS elif testCase == 6: if test_dls is None: print ("Test case 6, %d^2 spheres\n %s." % (nSpheres, "N col DL's around VBO/IBO shader/box buffer sphere calls")) # Wrap n display lists around the draws (one per column.) test_dls = glGenLists(nSpheres) # Returns ID of first DL in the set. test_spheres = [] for x in range(nSpheres): centers = [] radius = .5 radii = [] colors = [] # Each column is relative to its bottom sphere location. Start # at the lower-left corner, offset so the whole pattern comes up # centered on the origin. start_pos = V(0, 0, 0) # So it doesn't get subtracted twice. pos = sphereLoc(x, 0) - V(nSpheres/2.0, nSpheres/2.0, 0) for y in range(nSpheres): centers += [sphereLoc(0, y)] # Sphere radii progress from 3/4 to full size. t = float(x+y)/(nSpheres+nSpheres) # 0 to 1 fraction. thisRad = radius * (.75 + t*.25) radii += [thisRad] # Colors progress from red to blue. colors += [rainbow(t)] continue test_sphere = GLSphereBuffer() test_sphere.addSpheres(centers, radii, colors, None, None) test_spheres += [test_sphere] glNewList(test_dls + x, GL_COMPILE_AND_EXECUTE) glPushMatrix() glTranslatef(pos[0], pos[1], pos[2]) test_sphere.draw() glPopMatrix() glEndList() continue pass else: shader = drawing_globals.test_sphereShader shader.configShader(glpane) # Turn the lights on. for x in range(nSpheres): glCallList(test_dls + x) continue pass pass # NE1 with test toploop, # N column VBO sets of shader/box buffer sphere calls (test case 7) # . 2,500 (50x50) spheres 50 FPS # . 10,000 (100x100) spheres 30.5 FPS # . 17,424 (132x132) spheres 23.5 FPS # . 40,000 (200x200) spheres 16.8 FPS # . 90,000 (300x300) spheres 10.8 FPS # . 160,000 (400x400) spheres 9.1 FPS # . 250,000 (500x500) spheres 7.3 FPS elif testCase == 7: if test_spheres is None: print ("Test case 7, %d^2 spheres\n %s." % (nSpheres, "Per-column VBO/IBO chunk buffers")) test_spheres = [] for x in range(nSpheres): centers = [] radius = .5 radii = [] colors = [] for y in range(nSpheres): centers += [sphereLoc(x, y)] # Sphere radii progress from 3/4 to full size. t = float(x+y)/(nSpheres+nSpheres) # 0 to 1 fraction. thisRad = radius * (.75 + t*.25) radii += [thisRad] # Colors progress from red to blue. colors += [rainbow(t)] continue _spheres1 = GLSphereBuffer() _spheres1.addSpheres(centers, radii, colors, None, None) test_spheres += [_spheres1] continue pass else: shader = drawing_globals.test_sphereShader shader.configShader(glpane) for chunk in test_spheres: chunk.draw() pass # NE1 with test toploop, # Short chunk VBO sets of shader/box buffer sphere calls (test case 8) # . 625 (25x25) spheres 30 FPS, 79 chunk buffers of length 8. # . 2,500 (50x50) spheres 13.6 FPS, 313 chunk buffers of length 8. # . 10,000 (100x100) spheres 6.4 FPS, 704 chunk buffers of length 8. # . 10,000 (100x100) spheres 3.3 FPS, 1250 chunk buffers of length 8. # . 17,424 (132x132) spheres 2.1 FPS, 2178 chunk buffers of length 8. # . 2,500 (50x50) spheres 33.5 FPS, 105 chunk buffers of length 24. # . 17,424 (132x132) spheres 5.5 FPS, 726 chunk buffers of length 24. # # Subcase 8.1: CSDLs in a DrawingSet. (Initial pass-through version.) # . 2,500 (50x50) spheres 36.5 FPS, 105 chunk buffers of length 24. # . 5,625 (75x75) spheres 16.1 FPS, 235 chunk buffers of length 24. # . 10,000 (100x100) spheres 0.5 FPS?!, 414 chunk buffers of length 24. # Has to be <= 250 chunks for constant memory transforms? # . 10,000 (100x100) spheres 11.8 FPS, 50 chunk buffers of length 200. # After a minute of startup. # . 10,000 (100x100) spheres 9.3 FPS, 200 chunk buffers of length 50. # After a few minutes of startup. # Subcase 8.2: CSDLs in a DrawingSet with transforms. (Pass-through.) # . 10,000 (100x100) spheres 11.5 FPS, 50 chunk buffers of length 200. # # Subcase 8.1: CSDLs in a DrawingSet. (First HunkBuffer version.) # Measured with auto-rotate on, ignoring startup and occasional outliers. # As before, on a 2 core, 2.4 GHz Intel MacBook Pro with GeForce 8600M GT. # HUNK_SIZE = 10000 # . 2,500 (50x50) spheres 140-200 FPS, 105 chunks of length 24. # . 5,625 (75x75) spheres 155-175 FPS, 235 chunks of length 24. # . 10,000 (100x100) spheres 134-145 FPS, 50 chunks of length 200. # . 10,000 (100x100) spheres 130-143 FPS, 200 chunks of length 50. # . 10,000 (100x100) spheres 131-140 FPS, 1,250 chunks of length 8. # Chunks are gathered into hunk buffers, so no chunk size speed diff. # . 17,424 (132x132) spheres 134-140 FPS, 88 chunks of length 200. # . 17,424 (132x132) spheres 131-140 FPS, 2,178 chunks of length 8. # HUNK_SIZE = 20000 # . 17,424 (132x132) spheres 131-140 FPS, 88 chunks of length 200. # . 17,424 (132x132) spheres 130-141 FPS, 2,178 chunks of length 8. # HUNK_SIZE = 10000 # . 40,000 (200x200) spheres 77.5-82.8 FPS, 5,000 chunks of length 8. # . 90,000 (300x300) spheres 34.9-42.6 FPS, 11,2500 chunks of length 8. # Spheres are getting down to pixel size, causing moire patterns. # Rotate the sphere-array off-axis 45 degrees to minimize. # (Try adding multi-sampled anti-aliasing, to the drawing test...) # . 160,000 (400x400) spheres 26.4-27.1 FPS, 20,000 chunks of length 8. # . 250,000 (500x500) spheres 16.8-17.1 FPS, 31,250 chunks of length 8. # The pattern is getting too large, far-clipping is setting in. # . 360,000 (600x600) spheres 11.6-11.8 FPS, 45,000 chunks of length 8. # Extreme far-clipping in the drawing test pattern. # HUNK_SIZE = 20000; no significant speed-up. # . 40,000 (200x200) spheres 75.9-81.5 FPS, 5,000 chunks of length 8. # . 90,000 (300x300) spheres 41.2-42.4 FPS, 11,250 chunks of length 8. # Spheres are getting down to pixel size, causing moire patterns. # . 160,000 (400x400) spheres 26.5-26.9 FPS, 20,000 chunks of length 8. # . 250,000 (500x500) spheres 16.5-17.1 FPS, 31,250 chunks of length 8. # . 360,000 (600x600) spheres 11.8-12.1 FPS, 45,000 chunks of length 8. # HUNK_SIZE = 5000; no significant slowdown or CPU load difference. # . 40,000 (200x200) spheres 81.0-83.8 FPS, 5,000 chunks of length 8. # . 160,000 (400x400) spheres 27.3-29.4 FPS, 20,000 chunks of length 8. # . 360,000 (600x600) spheres 11.7-12.1 FPS, 45,000 chunks of length 8. # # Retest after updating MacOS to 10.5.5, with TestGraphics, HUNK_SIZE = 5000 # . 40,000 (200x200) spheres 68.7-74.4 FPS, 5,000 chunks of length 8. # . 90,000 (300x300) spheres 39.4-42.0 FPS, 11,250 chunks of length 8. # . 160,000 (400x400) spheres 24.4-25.2 FPS, 20,000 chunks of length 8. # Retest with glMultiDrawElements drawing indexes in use, HUNK_SIZE = 5000 # . 40,000 (200x200) spheres 52.8-54.4 FPS, 5,000 chunks of length 8. # . 90,000 (300x300) spheres 22.8-23.3 FPS, 11,250 chunks of length 8. # . 160,000 (400x400) spheres 13.5-15.2 FPS, 20,000 chunks of length 8. # # Retest with reworked halo/sphere shader, HUNK_SIZE = 5000 [setup time] # . 17,424 (132x132) spheres 52.8-53.7 FPS, 2,178 chunks of length 8. [60] # . 40,000 (200x200) spheres 29.3-30.4 FPS, 5,000 chunks of length 8.[156] # . 90,000 (300x300) spheres 18.2-19.2 FPS, 11,250 chunks of length 8.[381] # . 160,000 (400x400) spheres 10.2-11.6 FPS, 20,000 chunks of length 8.[747] # Billboard drawing patterns instead of cubes, HUNK_SIZE = 5000 [setup time] # . 17,424 (132x132) spheres 49.7-55.7 FPS, 2,178 chunks of length 8. [35] # . 40,000 (200x200) spheres 39.6-40.8 FPS, 5,000 chunks of length 8. [88] # . 90,000 (300x300) spheres 18.9-19.5 FPS, 11,250 chunks of length 8.[225] # . 160,000 (400x400) spheres 11.2-11.7 FPS, 20,000 chunks of length 8.[476] # elif int(testCase) == 8: doTransforms = False doCylinders = False if test_spheres is None: # Setup. print ("Test case 8, %d^2 primitives\n %s, length %d." % (nSpheres, "Short VBO/IBO chunk buffers", chunkLength)) if testCase == 8.1: print ("Sub-test 8.1, sphere chunks are in CSDL's in a DrawingSet.") test_DrawingSet = DrawingSet() elif testCase == 8.2: print ("Sub-test 8.2, spheres, rotate with TransformControls.") test_DrawingSet = DrawingSet() doTransforms = True elif testCase == 8.3: print ("Sub-test 8.3, cylinder chunks are in CSDL's in a DrawingSet.") test_DrawingSet = DrawingSet() doCylinders = True pass if test_DrawingSet: # note: doesn't happen in test 8.0, which causes a bug then. [bruce 090223 comment] print "constructed test_DrawingSet =", test_DrawingSet if USE_GRAPHICSMODE_DRAW: print ("Use graphicsMode.Draw_model for DrawingSet in paintGL.") pass t1 = time.time() if doTransforms: # Provide several TransformControls to test separate action. global numTCs, TCs numTCs = 3 TCs = [TransformControl() for i in range(numTCs)] pass def primCSDL(centers, radii, colors): if not doTransforms: csdl = ColorSortedDisplayList() # Transformless. else: # Test pattern for TransformControl usage - vertical columns # of TC domains, separated by X coord of first center point. # Chunking will be visible when transforms are changed. xCoord = centers[0][0] - start_pos[0] # Negate centering X. xPercent = (xCoord / (nSpheres + nSpheres/10 + nSpheres/100 - 1 + (nSpheres <= 1))) xTenth = int(xPercent * 10 + .5) csdl = ColorSortedDisplayList(TCs[xTenth % numTCs]) pass # Test selection using the CSDL glname. ColorSorter.pushName(csdl.glname) ColorSorter.start(glpane, csdl) for (color, center, radius) in zip(colors, centers, radii): if not doCylinders: # Through ColorSorter to the sphere primitive buffer... drawsphere(color, center, radius, DRAWSPHERE_DETAIL_LEVEL) else: # Through ColorSorter to cylinder primitive buffer... if not drawing_globals.cylinderShader_available(): print "warning: not cylinderShader_available(), error is likely:" if (True and # Whether to do tapered shader-cylinders. # Display List cylinders don't support taper. glpane.glprefs.cylinderShader_desired()): ###cylRad = (radius/2.0, (.75-radius)/2.0) cylRad = (radius/1.5 - .167, .3 - radius/1.5) else: cylRad = radius/2.0 pass endPt2 = center + V(0.5, 0.0, 0.0) # 0.5, -0.5) drawcylinder(color, center, endPt2, cylRad) global test_endpoints test_endpoints += [(center, endPt2)] pass continue ColorSorter.popName() ColorSorter.finish(draw_now = True) test_DrawingSet.addCSDL(csdl) return csdl if testCase == 8: #bruce 090223 revised to try to avoid traceback def chunkFn(centers, radii, colors): res = GLSphereBuffer() res.addSpheres(centers, radii, colors, None, None) return res pass else: chunkFn = primCSDL pass test_spheres = [] radius = .5 centers = [] radii = [] colors = [] global test_endpoints test_endpoints = [] for x in range(nSpheres): for y in range(nSpheres): centers += [sphereLoc(x, y)] # Sphere radii progress from 3/4 to full size. t = float(x+y)/(nSpheres+nSpheres) # 0 to 1 fraction. thisRad = radius * (.5 + t*.5) radii += [thisRad] # Colors progress from red to blue. colors += [rainbow(t)] # Put out short chunk buffers. if len(centers) >= chunkLength: test_spheres += [ chunkFn(centers, radii, colors) ] centers = [] radii = [] colors = [] continue continue # Remainder fraction buffer. if len(centers): test_spheres += [chunkFn(centers, radii, colors)] pass print "Setup time", time.time() - t1, "seconds." print "%d chunk buffers" % len(test_spheres) pass elif not initOnly: # Run. test_Draw_8x(glpane) pass elif testCase == 100: #bruce 090102 # before making more of these, modularize it somehow from commands.TestGraphics.test_selection_redraw import test_selection_redraw test_class = test_selection_redraw params = ( nSpheres, ) # note: test size is not directly comparable to other tests with same value of nSpheres if test_Object is None \ or not isinstance(test_Object, test_class) \ or test_Object.current_params() != params: # review: same_vals? # Setup. if test_Object: test_Object.destroy() test_Object = test_class(*params) test_Object.activate() print test_Object pass # review: safe to change elif to if? not sure, GL state is only initialized below elif not initOnly: # Run. test_Object.draw_complete() pass pass if not initOnly: glMatrixMode(GL_MODELVIEW) glFlush() pass first_time = False return
def setup_drawer(): """ Set up the usual constant display lists in the current OpenGL context. WARNING: THIS IS ONLY CORRECT IF ONLY ONE GL CONTEXT CONTAINS DISPLAY LISTS -- or more precisely, only the GL context this has last been called in (or one which shares its display lists) will work properly with the routines in drawer.py, since the allocated display list names are stored in globals set by this function, but in general those names might differ if this was called in different GL contexts. """ spherelistbase = glGenLists(_NUM_SPHERE_SIZES) sphereList = [] for i in range(_NUM_SPHERE_SIZES): sphereList += [spherelistbase+i] glNewList(sphereList[i], GL_COMPILE) glBegin(GL_TRIANGLE_STRIP) # GL_LINE_LOOP to see edges stripVerts = getSphereTriStrips(i) for vertNorm in stripVerts: glNormal3fv(vertNorm) glVertex3fv(vertNorm) continue glEnd() glEndList() continue drawing_globals.sphereList = sphereList # Sphere triangle-strip vertices for each level of detail. # (Cache and re-use the work of making them.) # Can use in converter-wrappered calls like glVertexPointerfv, # but the python arrays are re-copied to C each time. sphereArrays = [] for i in range(_NUM_SPHERE_SIZES): sphereArrays += [getSphereTriStrips(i)] continue drawing_globals.sphereArrays = sphereArrays # Sphere glDrawArrays triangle-strip vertices for C calls. # (Cache and re-use the work of converting a C version.) # Used in thinly-wrappered calls like glVertexPointer. sphereCArrays = [] for i in range(_NUM_SPHERE_SIZES): CArray = numpy.array(sphereArrays[i], dtype = numpy.float32) sphereCArrays += [CArray] continue drawing_globals.sphereCArrays = sphereCArrays # Sphere indexed vertices. # (Cache and re-use the work of making the indexes.) # Can use in converter-wrappered calls like glDrawElementsui, # but the python arrays are re-copied to C each time. sphereElements = [] # Pairs of lists (index, verts) . for i in range(_NUM_SPHERE_SIZES): sphereElements += [indexVerts(sphereArrays[i], .0001)] continue drawing_globals.sphereElements = sphereElements # Sphere glDrawElements index and vertex arrays for C calls. sphereCIndexTypes = [] # numpy index unsigned types. sphereGLIndexTypes = [] # GL index types for drawElements. sphereCElements = [] # Pairs of numpy arrays (Cindex, Cverts) . for i in range(_NUM_SPHERE_SIZES): (index, verts) = sphereElements[i] if len(index) < 256: Ctype = numpy.uint8 GLtype = GL_UNSIGNED_BYTE else: Ctype = numpy.uint16 GLtype = GL_UNSIGNED_SHORT pass sphereCIndexTypes += [Ctype] sphereGLIndexTypes += [GLtype] sphereCIndex = numpy.array(index, dtype = Ctype) sphereCVerts = numpy.array(verts, dtype = numpy.float32) sphereCElements += [(sphereCIndex, sphereCVerts)] continue drawing_globals.sphereCIndexTypes = sphereCIndexTypes drawing_globals.sphereGLIndexTypes = sphereGLIndexTypes drawing_globals.sphereCElements = sphereCElements if glGetString(GL_EXTENSIONS).find("GL_ARB_vertex_buffer_object") >= 0: # A GLBufferObject version for glDrawArrays. sphereArrayVBOs = [] for i in range(_NUM_SPHERE_SIZES): vbo = GLBufferObject(GL_ARRAY_BUFFER_ARB, sphereCArrays[i], GL_STATIC_DRAW) sphereArrayVBOs += [vbo] continue drawing_globals.sphereArrayVBOs = sphereArrayVBOs # A GLBufferObject version for glDrawElements indexed verts. sphereElementVBOs = [] # Pairs of (IBO, VBO) for i in range(_NUM_SPHERE_SIZES): ibo = GLBufferObject(GL_ELEMENT_ARRAY_BUFFER_ARB, sphereCElements[i][0], GL_STATIC_DRAW) vbo = GLBufferObject(GL_ARRAY_BUFFER_ARB, sphereCElements[i][1], GL_STATIC_DRAW) sphereElementVBOs += [(ibo, vbo)] continue drawing_globals.sphereElementVBOs = sphereElementVBOs ibo.unbind() vbo.unbind() pass #bruce 060415 drawing_globals.wiresphere1list = wiresphere1list = glGenLists(1) glNewList(wiresphere1list, GL_COMPILE) didlines = {} # don't draw each triangle edge more than once def shoulddoline(v1,v2): # make sure not list (unhashable) or Numeric array (bug in __eq__) v1 = tuple(v1) v2 = tuple(v2) if (v1,v2) not in didlines: didlines[(v1,v2)] = didlines[(v2,v1)] = None return True return False def doline(v1,v2): if shoulddoline(v1,v2): glVertex3fv(v1) glVertex3fv(v2) return glBegin(GL_LINES) ocdec = getSphereTriangles(1) for tri in ocdec: #e Could probably optim this more, e.g. using a vertex array or VBO or # maybe GL_LINE_STRIP. doline(tri[0], tri[1]) doline(tri[1], tri[2]) doline(tri[2], tri[0]) glEnd() glEndList() drawing_globals.CylList = CylList = glGenLists(1) glNewList(CylList, GL_COMPILE) glBegin(GL_TRIANGLE_STRIP) for (vtop, ntop, vbot, nbot) in drawing_globals.cylinderEdges: glNormal3fv(nbot) glVertex3fv(vbot) glNormal3fv(ntop) glVertex3fv(vtop) glEnd() glEndList() drawing_globals.CapList = CapList = glGenLists(1) glNewList(CapList, GL_COMPILE) glNormal3fv(drawing_globals.cap0n) glBegin(GL_POLYGON) for p in drawing_globals.drum0: glVertex3fv(p) glEnd() glNormal3fv(drawing_globals.cap1n) glBegin(GL_POLYGON) #bruce 060609 fix "ragged edge" bug in this endcap: drum1 -> drum2 for p in drawing_globals.drum2: glVertex3fv(p) glEnd() glEndList() drawing_globals.diamondGridList = diamondGridList = glGenLists(1) glNewList(diamondGridList, GL_COMPILE) glBegin(GL_LINES) for p in drawing_globals.digrid: glVertex(p[0]) glVertex(p[1]) glEnd() glEndList() drawing_globals.lonsGridList = lonsGridList = glGenLists(1) glNewList(lonsGridList, GL_COMPILE) glBegin(GL_LINES) for p in drawing_globals.lonsEdges: glVertex(p[0]) glVertex(p[1]) glEnd() glEndList() drawing_globals.CubeList = CubeList = glGenLists(1) glNewList(CubeList, GL_COMPILE) glBegin(GL_QUAD_STRIP) # note: CubeList has only 4 faces of the cube; only suitable for use in # wireframes; see also solidCubeList [bruce 051215 comment reporting # grantham 20051213 observation] glVertex((-1,-1,-1)) glVertex(( 1,-1,-1)) glVertex((-1, 1,-1)) glVertex(( 1, 1,-1)) glVertex((-1, 1, 1)) glVertex(( 1, 1, 1)) glVertex((-1,-1, 1)) glVertex(( 1,-1, 1)) glVertex((-1,-1,-1)) glVertex(( 1,-1,-1)) glEnd() glEndList() drawing_globals.solidCubeList = solidCubeList = glGenLists(1) glNewList(solidCubeList, GL_COMPILE) glBegin(GL_QUADS) for i in xrange(len(drawing_globals.cubeIndices)): avenormals = V(0,0,0) #bruce 060302 fixed normals for flat shading for j in xrange(4) : nTuple = tuple( drawing_globals.cubeNormals[drawing_globals.cubeIndices[i][j]]) avenormals += A(nTuple) avenormals = norm(avenormals) for j in xrange(4) : vTuple = tuple( drawing_globals.cubeVertices[drawing_globals.cubeIndices[i][j]]) #bruce 060302 made size compatible with glut.glutSolidCube(1.0) vTuple = A(vTuple) * 0.5 glNormal3fv(avenormals) glVertex3fv(vTuple) glEnd() glEndList() drawing_globals.rotSignList = rotSignList = glGenLists(1) glNewList(rotSignList, GL_COMPILE) glBegin(GL_LINE_STRIP) for ii in xrange(len(drawing_globals.rotS0n)): glVertex3fv(tuple(drawing_globals.rotS0n[ii])) glEnd() glBegin(GL_LINE_STRIP) for ii in xrange(len(drawing_globals.rotS1n)): glVertex3fv(tuple(drawing_globals.rotS1n[ii])) glEnd() glBegin(GL_TRIANGLES) for v in drawing_globals.arrow0Vertices + drawing_globals.arrow1Vertices: glVertex3f(v[0], v[1], v[2]) glEnd() glEndList() drawing_globals.linearArrowList = linearArrowList = glGenLists(1) glNewList(linearArrowList, GL_COMPILE) glBegin(GL_TRIANGLES) for v in drawing_globals.linearArrowVertices: glVertex3f(v[0], v[1], v[2]) glEnd() glEndList() drawing_globals.linearLineList = linearLineList = glGenLists(1) glNewList(linearLineList, GL_COMPILE) glEnable(GL_LINE_SMOOTH) glBegin(GL_LINES) glVertex3f(0.0, 0.0, -drawing_globals.halfHeight) glVertex3f(0.0, 0.0, drawing_globals.halfHeight) glEnd() glDisable(GL_LINE_SMOOTH) glEndList() drawing_globals.circleList = circleList = glGenLists(1) glNewList(circleList, GL_COMPILE) glBegin(GL_LINE_LOOP) for ii in range(60): x = cos(ii*2.0*pi/60) y = sin(ii*2.0*pi/60) glVertex3f(x, y, 0.0) glEnd() glEndList() # piotr 080405 drawing_globals.filledCircleList = filledCircleList = glGenLists(1) glNewList(filledCircleList, GL_COMPILE) glBegin(GL_POLYGON) for ii in range(60): x = cos(ii*2.0*pi/60) y = sin(ii*2.0*pi/60) glVertex3f(x, y, 0.0) glEnd() glEndList() drawing_globals.lineCubeList = lineCubeList = glGenLists(1) glNewList(lineCubeList, GL_COMPILE) glBegin(GL_LINES) cvIndices = [0,1, 2,3, 4,5, 6,7, 0,3, 1,2, 5,6, 4,7, 0,4, 1,5, 2,6, 3,7] for i in cvIndices: glVertex3fv(tuple(drawing_globals.cubeVertices[i])) glEnd() glEndList() #initTexture('C:\\Huaicai\\atom\\temp\\newSample.png', 128,128) return # from setup_drawer
def initializeGL(self): glClearColor(0.85, 0.85, 0.85, 1.0) glClearDepth(1.0) glDepthFunc(GL_LESS) glEnable(GL_DEPTH_TEST) glEnable(GL_CULL_FACE) glShadeModel(GL_SMOOTH) glEnable(GL_NORMALIZE) glEnable(GL_COLOR_MATERIAL) glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE) glLightfv(GL_LIGHT0, GL_POSITION, (0.0, 0.0, 1.0, 0.0)) glEnable(GL_LIGHT0) glMatrixMode(GL_PROJECTION) glLoadIdentity() glMatrixMode(GL_MODELVIEW) glLoadIdentity() self.display_list = glGenLists(1) glNewList(self.display_list, GL_COMPILE) glScalef(0.5, 0.5, 0.5) glEnable(GL_LIGHTING) # board glColor3f(0.0, 0.0, 0.0) self.draw_cuboid(4.0, 4.0, 0.16) # USB connector glPushMatrix() glColor3f(0.5, 0.51, 0.58) glTranslatef(0.0, -1.6, 0.28) self.draw_cuboid(0.75, 0.9, 0.4) glPopMatrix() # right button glPushMatrix() glColor3f(0.5, 0.51, 0.58) glTranslatef(1.15, -1.85, 0.16) self.draw_cuboid(0.4, 0.3, 0.16) glColor3f(0.0, 0.0, 0.0) glTranslatef(0.0, -0.155, 0.025) self.draw_cuboid(0.18, 0.1, 0.08) glPopMatrix() # left button glPushMatrix() glColor3f(0.5, 0.51, 0.58) glTranslatef(-1.15, -1.85, 0.16) self.draw_cuboid(0.4, 0.3, 0.16) glColor3f(0.0, 0.0, 0.0) glTranslatef(0.0, -0.155, 0.025) self.draw_cuboid(0.18, 0.1, 0.08) glPopMatrix() # left btb top glPushMatrix() glColor3f(1.0, 1.0, 1.0) glTranslatef(-1.65, 0.0, 0.38) self.draw_cuboid(0.5, 1.4, 0.9) glPopMatrix() # right btb top glPushMatrix() glColor3f(1.0, 1.0, 1.0) glTranslatef(1.65, 0.0, 0.38) self.draw_cuboid(0.5, 1.4, 0.9) glPopMatrix() # left btb bottom glPushMatrix() glColor3f(1.0, 1.0, 1.0) glTranslatef(-1.65, 0.0, -0.33) self.draw_cuboid(0.5, 1.4, 0.5) glPopMatrix() # right btb bottom glPushMatrix() glColor3f(1.0, 1.0, 1.0) glTranslatef(1.65, 0.0, -0.33) self.draw_cuboid(0.5, 1.4, 0.5) glPopMatrix() # left bricklet port glPushMatrix() glColor3f(1.0, 1.0, 1.0) glTranslatef(-0.85, 1.8, -0.23) self.draw_cuboid(1.2, 0.4, 0.3) glPopMatrix() # right bricklet port glPushMatrix() glColor3f(1.0, 1.0, 1.0) glTranslatef(0.85, 1.8, -0.23) self.draw_cuboid(1.2, 0.4, 0.3) glPopMatrix() # left direction LED glPushMatrix() glColor3f(0.0, 0.5, 0.0) glTranslatef(-1.05, 1.425, 0.115) self.draw_cuboid(0.1, 0.2, 0.07) glPopMatrix() # top direction LED glPushMatrix() glColor3f(0.0, 0.5, 0.0) glTranslatef(-0.675, 1.8, 0.115) self.draw_cuboid(0.2, 0.1, 0.07) glPopMatrix() # right direction LED glPushMatrix() glColor3f(0.0, 0.5, 0.0) glTranslatef(-0.3, 1.425, 0.115) self.draw_cuboid(0.1, 0.2, 0.07) glPopMatrix() # bottom direction LED glPushMatrix() glColor3f(0.0, 0.5, 0.0) glTranslatef(-0.675, 1.05, 0.115) self.draw_cuboid(0.2, 0.1, 0.07) glPopMatrix() # left y orientation LED glPushMatrix() glColor3f(0.0, 0.0, 1.0) glTranslatef(0.275, 1.7, 0.115) self.draw_cuboid(0.1, 0.2, 0.07) glPopMatrix() # right y orientation LED glPushMatrix() glColor3f(1.0, 0.0, 0.0) glTranslatef(0.425, 1.7, 0.115) self.draw_cuboid(0.1, 0.2, 0.07) glPopMatrix() # top z orientation LED glPushMatrix() glColor3f(1.0, 0.0, 0.0) glTranslatef(0.35, 1.15, 0.115) self.draw_cuboid(0.2, 0.1, 0.07) glPopMatrix() # bottom z orientation LED glPushMatrix() glColor3f(0.0, 0.0, 1.0) glTranslatef(0.35, 1.0, 0.115) self.draw_cuboid(0.2, 0.1, 0.07) glPopMatrix() # top x orientation LED glPushMatrix() glColor3f(1.0, 0.0, 0.0) glTranslatef(1.0, 1.15, 0.115) self.draw_cuboid(0.2, 0.1, 0.07) glPopMatrix() # bottom x orientation LED glPushMatrix() glColor3f(0.0, 0.0, 1.0) glTranslatef(1.0, 1.0, 0.115) self.draw_cuboid(0.2, 0.1, 0.07) glPopMatrix() # top alignment corner glPushMatrix() glColor3f(1.0, 1.0, 1.0) glBegin(GL_TRIANGLES) glNormal3f(0.0, 0.0, 1.0) glVertex3f(-2.0, -2.0, 0.09) glVertex3f(-1.1, -2.0, 0.09) glVertex3f(-2.0, -1.1, 0.09) glEnd() glPopMatrix() # bottom alignment corner glPushMatrix() glColor3f(1.0, 1.0, 1.0) glBegin(GL_TRIANGLES) glNormal3f(0.0, 0.0, -1.0) glVertex3f(-2.0, -2.0, -0.09) glVertex3f(-2.0, -1.1, -0.09) glVertex3f(-1.1, -2.0, -0.09) glEnd() glPopMatrix() glDisable(GL_LIGHTING) # axis glPushMatrix() glTranslatef(-2.3, -2.3, -0.38) glLineWidth(3.0) glBegin(GL_LINES) glColor3f(1,0,0) # x axis is red glVertex3f(0,0,0) glVertex3f(3,0,0) glColor3f(0,0.5,0) # y axis is green glVertex3f(0,0,0) glVertex3f(0,3,0) glColor3f(0,0,1) # z axis is blue glVertex3f(0,0,0) glVertex3f(0,0,3) glEnd() glLineWidth(1.0) glPopMatrix() glEndList()
def begin_list(self, l): glNewList(l, GL_COMPILE)
def display(self): if self.knowledge_base: # update the world if self.knowledge_base.shelf_xform: # load the shelf once a transform is available if not self.shelf: self.shelf = self.world.loadRigidObject("klampt_models/north_shelf/shelf_with_bins.obj") logger.info("spawned shelf model") self.shelf.setTransform(*self.knowledge_base.shelf_xform) if self.knowledge_base.order_bin_xform: # load the order bin once a transform is available if not self.order_bin: self.order_bin = self.world.loadRigidObject("klampt_models/apc_bin/apc_bin.obj") logger.info("spawned order bin model") self.order_bin.setTransform(*self.knowledge_base.order_bin_xform) # spawn/update objects for (name, xform) in self.knowledge_base.object_xforms.items(): # load the object once a transform is availale if name not in self.objects: body = self.world.loadRigidObject("klampt_models/items/{0}/{0}.obj".format(name)) logger.info("spawned {} model".format(name)) # load the point cloud if name in self.knowledge_base.object_clouds: self.n += 1 display_list = glGenLists(self.n) # compile the display list glNewList(display_list, GL_COMPILE) glDisable(GL_LIGHTING) glBegin(GL_POINTS) points = self.knowledge_base.object_clouds[name] for point in points: if len(point) == 2: xyz = point[0] rgb = point[1] else: xyz = point[:3] if len(point) == 4: rgb = point[3] elif len(point) > 3: rgb = point[3:6] else: rgb = None if rgb is not None: glColor3f(*map(lambda x: x / 255.0, rgb)) else: glColor3f(*colors[i % len(colors)]) glVertex3f(*xyz[:3]) glEnd() glEndList() logging.debug("compiled {} points for {}".format(len(points), name)) else: display_list = None self.objects[name] = {"body": body, "display_list": display_list} # self.objects[name]['body'].setTransform(*xform) # delete objects for (name, props) in self.objects.items(): if name not in self.knowledge_base.object_xforms: # remove the object # XXX: cannot actually delete object... so move it far away... very far away props["body"].setTransform(so3.identity(), [1e3, 1e3, 1e3]) del self.objects[name] # update the robot state if self.robot_state: try: self.robot.setConfig(self.robot_state.sensed_config) except TypeError as e: logger.error("error visualizing config: {}".format(self.robot_state.sensed_config)) logger.error(traceback.format_exc()) sys.exit(-1) self.world.drawGL() # draw commanded configurations glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [0, 1, 0, 0.5]) if self.robot_state: qi = self.robot.getConfig() self.robot.setConfig(self.robot_state.commanded_config) self.robot.drawGL(False) self.robot.setConfig(qi) glDisable(GL_BLEND) # draw the point clouds glPointSize(2) for (name, props) in self.objects.items(): if "display_list" in props: glCallList(props["display_list"]) # draw gripper link transforms for name in ["left_gripper", "right_gripper"]: gldraw.xform_widget(self.robot.getLink(name).getTransform(), 0.1, 0.01) # draw axis-aligned axes for reference gldraw.xform_widget((so3.identity(), [0, 0, 1]), 0.1, 0.01) # draw local origins of objects if self.knowledge_base: for xform in self.knowledge_base.object_xforms.values(): gldraw.xform_widget(xform, 0.1, 0.01)
def finish(self, sorted_by_color): # bruce 090224 split this out of caller """ Finish collecting new primitives for use in self, and store them all in self, ready to be drawn in various ways. [meant to be called only by ColorSorter.start, for now] """ ## self._reset() ## # (note: this deallocates any existing display lists) if self.transformControl and (self.spheres or self.cylinders): self.updateTransform() # needed to do the transform for the first time, # even if it didn't change. Review: refactor to # whereever we first compile these down? That # might be a different place in self.draw vs. # draw from DrawingSet. selColor = env.prefs[selectionColor_prefs_key] # Note: if sorted_by_color is empty, current code still builds all # toplevel display lists, though they are noops. This may be needed # by some client code which uses those dls directly. Client code # wanting to know if it needs to draw our dls should test # self.has_nonempty_DLs(), which tests self._per_color_dls, # or self.has_nonshader_drawing(), which reports on that or any # other kind of nonshader (immediate mode opengl) drawing we might # have. [bruce 090225/090312 comment] # First build the lower level per-color sublists of primitives. for color, funcs in sorted_by_color.iteritems(): sublists = [glGenLists(1), 0] # Remember the display list ID for this color. self._per_color_dls.append([color, sublists]) glNewList(sublists[0], GL_COMPILE) opacity = color[3] if opacity == -1: # russ 080306: "Unshaded colors" for lines are signaled # by an opacity of -1 (4th component of the color.) glDisable(GL_LIGHTING) # Don't forget to re-enable it! pass for func, params, name in funcs: if name: glPushName(name) else: pass ## print "bug_2: attempt to push non-glname", name func(params) # Call the draw worker function. if name: glPopName() pass continue if opacity == -1: # Enable lighting after drawing "unshaded" objects. glEnable(GL_LIGHTING) pass glEndList() if opacity == -2: # piotr 080419: Special case for drawpolycone_multicolor # create another display list that ignores # the contents of color_array. # Remember the display list ID for this color. sublists[1] = glGenLists(1) glNewList(sublists[1], GL_COMPILE) for func, params, name in funcs: if name: glPushName(name) else: pass ## print "bug_3: attempt to push non-glname", name if func == drawpolycone_multicolor_worker: # Just to be sure, check if the func # is drawpolycone_multicolor_worker # and call drawpolycone_worker instead. # I think in the future we can figure out # a more general way of handling the # GL_COLOR_MATERIAL objects. piotr 080420 pos_array, color_array_junk, rad_array = params drawpolycone_worker((pos_array, rad_array)) elif func == drawtriangle_strip_worker: # piotr 080710: Multi-color modification # for triangle_strip primitive (used by # reduced protein style). pos_array, normal_array, color_array_junk = params drawtriangle_strip_worker((pos_array, normal_array, None)) if name: glPopName() pass continue glEndList() continue # Now the upper-level lists call all of the per-color sublists. #### REVIEW: these are created even when empty. Is that necessary? # [bruce 090224 Q] # One with colors. color_dl = self.color_dl = glGenLists(1) glNewList(color_dl, GL_COMPILE) for color, dls in self._per_color_dls: opacity = color[3] if opacity < 0: # russ 080306: "Unshaded colors" for lines are signaled # by a negative alpha. glColor3fv(color[:3]) # piotr 080417: for opacity == -2, i.e. if # GL_COLOR_MATERIAL is enabled, the color is going # to be ignored, anyway, so it is not necessary # to be tested here else: apply_material(color) glCallList(dls[0]) continue glEndList() # A second one without any colors. nocolor_dl = self.nocolor_dl = glGenLists(1) glNewList(nocolor_dl, GL_COMPILE) for color, dls in self._per_color_dls: opacity = color[3] if opacity == -2 and dls[1] > 0: # piotr 080420: If GL_COLOR_MATERIAL is enabled, # use a regular, single color dl rather than the # multicolor one. Btw, dls[1] == 0 should never # happen. glCallList(dls[1]) else: glCallList(dls[0]) glEndList() # A third DL implements the selected appearance. selected_dl = self.selected_dl = glGenLists(1) glNewList(selected_dl, GL_COMPILE) # russ 080530: Support for patterned selection drawing modes. patterned = isPatternedDrawing(select=True) if patterned: # Patterned drawing needs the colored dl drawn first. glCallList(color_dl) startPatternedDrawing(select=True) pass # Draw solid color (unpatterned) or an overlay pattern, in the # selection color. apply_material(selColor) glCallList(nocolor_dl) if patterned: # Reset from patterning drawing mode. endPatternedDrawing(select=True) glEndList() pass