def load(self,fname): mtllines = resource.location(fname).open(fname,"r") mname = None mat_dl = None mat_params = {'Ka':GL_AMBIENT, 'Kd': GL_DIFFUSE, 'Ks':GL_SPECULAR} tname = None for line in mtllines: tokens = line.split() if not tokens or line[0] == '#': continue if tokens[0] == 'newmtl': if mname: if not tname: glDisable(GL_TEXTURE_2D) glEndList() tname = None mname = tokens[1] mat_dl = self.mat_dls.get(mname) if mat_dl is None: mat_dl = self.mat_dls[mname] = glGenLists(2) glNewList(mat_dl, GL_COMPILE) elif tokens[0] == 'Ns': glMaterialf(GL_FRONT, GL_SHININESS, float(tokens[1])) elif tokens[0] in mat_params: params = map(float,tokens[1:]) floats4 = Mat4Floats(1.0,1.0,1.0,1.0) for i,f in enumerate(params): floats4[i] = f self.mat_trans[mname] = (floats4[3] < 1.0) glMaterialfv(GL_FRONT, mat_params[tokens[0]],floats4) elif tokens[0] == 'map_Kd' and not NOTEXTURES: # need a texture glEnable(GL_TEXTURE_2D) glCallList(mat_dl+1) # will bind texture glEndList() tname = tokens[1] tex = resource.texture(tokens[1]) glNewList(mat_dl+1,GL_COMPILE) if tex: self.mat_textures[tname] = tex trans = self.mat_trans.get(mname,False) self.mat_trans[mname] = trans glEnable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D,tex.id) # will end list before starting next one, or at end if mname: if not tname: glDisable(GL_TEXTURE_2D) glEndList()
def load_obj(self,fname,swapyz=False,on_polygon=None): """ Load the .obj file, drawing each sub-object into a display list, and setting each material into a display list A piece called xxx_Origin has one vertex which marks the origin for piece 'xxx', and just adds a glTranslate before and after drawing 'xxx'. """ objlines = resource.location(fname).open(fname,"r") self.origins = {} def int0(s): if s: return int(s) else: return 0 piece = '' mesh_dl = None npoints = 0 primitives = {1:GL_POINTS, 2: GL_LINES, 3:GL_TRIANGLES, 4:GL_QUADS} vertices = [] normals = [] tcoords = [] for line in objlines: tokens = line.split() if not tokens or line[0] == '#': continue key = tokens[0] if key == 'mtllib': if self.mname: self.mat_dls.load(self.mname) else: self.mat_dls.load(tokens[1]) elif key == 'o': if piece.endswith("_Origin") and len(vertices): self.origins[piece[:-7]] = vertices[-1] elif npoints: glEnd() npoints = 0 if mesh_dl: glEndList() piece = tokens[1] if piece.endswith("_Origin"): mesh_dl = None else: mesh_dl = self.mesh_dls[piece] = glGenLists(1) self.mesh_trans[piece] = False glNewList(mesh_dl,GL_COMPILE) elif key == 'v': vx,vy,vz = map(float,tokens[1:4]) if swapyz: vx,vy,vz = vx,vz,vy vertices.append((vx,vy,vz)) elif key == 'vn': normals.append(map(float,tokens[1:4])) elif key == 'vt': tcoords.append(map(float,tokens[1:3])) elif key == 'usemtl': if npoints: glEnd() npoints = 0 mdl = self.mat_dls.get(tokens[1]) if mdl is not None: # a material we have loaded glCallList(mdl) self.mesh_trans[piece] |= self.mat_dls.is_transparent(tokens[1]) elif key == 'f': points = [map(int0, s.split('/')) for s in tokens[1:]] if len(points) != npoints: if npoints: glEnd() npoints = len(points) prim = primitives.get(npoints, GL_POLYGON) glBegin(prim) for v, t, n in points: if n: glNormal3f(*normals[n-1]) if t: glTexCoord2f(*tcoords[t-1]) glVertex3f(*vertices[v-1]) if on_polygon: on_polygon(piece,[vertices[v-1] for v,t,n in points]) if npoints > 4: # GL_POLYGON npoints = -1 # can't continue without a glEnd() if piece.endswith("_Origin") and len(vertices): self.origins[piece[:-7]] = vertices[-1] elif npoints: glEnd() npoints = 0 if mesh_dl: glEndList() # Now wrap extra glTranslatef around the pieces with origins for piece,(vx,vy,vz) in self.origins.items(): dl_old = self.mesh_dls.get(piece) if not dl_old: continue dl_new = glGenLists(1) self.mesh_dls[piece] = dl_new self.mesh_dls[dl_old] = dl_old # stash it so __del__ can release it later with gl_compile(dl_new): glTranslatef(-vx,-vy,-vz) glCallList(dl_old) glTranslatef(vx,vy,vz)
def load_obj(self, fname, swapyz=False, on_polygon=None): """ Load the .obj file, drawing each sub-object into a display list, and setting each material into a display list A piece called xxx_Origin has one vertex which marks the origin for piece 'xxx', and just adds a glTranslate before and after drawing 'xxx'. """ objlines = resource.location(fname).open(fname, "r") self.origins = {} def int0(s): if s: return int(s) else: return 0 piece = '' mesh_dl = None npoints = 0 primitives = {1: GL_POINTS, 2: GL_LINES, 3: GL_TRIANGLES, 4: GL_QUADS} vertices = [] normals = [] tcoords = [] for line in objlines: tokens = line.split() if not tokens or line[0] == '#': continue key = tokens[0] if key == 'mtllib': if self.mname: self.mat_dls.load(self.mname) else: self.mat_dls.load(tokens[1]) elif key == 'o': if piece.endswith("_Origin") and len(vertices): self.origins[piece[:-7]] = vertices[-1] elif npoints: glEnd() npoints = 0 if mesh_dl: glEndList() piece = tokens[1] if piece.endswith("_Origin"): mesh_dl = None else: mesh_dl = self.mesh_dls[piece] = glGenLists(1) self.mesh_trans[piece] = False glNewList(mesh_dl, GL_COMPILE) elif key == 'v': vx, vy, vz = map(float, tokens[1:4]) if swapyz: vx, vy, vz = vx, vz, vy vertices.append((vx, vy, vz)) elif key == 'vn': normals.append(map(float, tokens[1:4])) elif key == 'vt': tcoords.append(map(float, tokens[1:3])) elif key == 'usemtl': if npoints: glEnd() npoints = 0 mdl = self.mat_dls.get(tokens[1]) if mdl is not None: # a material we have loaded glCallList(mdl) self.mesh_trans[piece] |= self.mat_dls.is_transparent( tokens[1]) elif key == 'f': points = [map(int0, s.split('/')) for s in tokens[1:]] if len(points) != npoints: if npoints: glEnd() npoints = len(points) prim = primitives.get(npoints, GL_POLYGON) glBegin(prim) for v, t, n in points: if n: glNormal3f(*normals[n - 1]) if t: glTexCoord2f(*tcoords[t - 1]) glVertex3f(*vertices[v - 1]) if on_polygon: on_polygon(piece, [vertices[v - 1] for v, t, n in points]) if npoints > 4: # GL_POLYGON npoints = -1 # can't continue without a glEnd() if piece.endswith("_Origin") and len(vertices): self.origins[piece[:-7]] = vertices[-1] elif npoints: glEnd() npoints = 0 if mesh_dl: glEndList() # Now wrap extra glTranslatef around the pieces with origins for piece, (vx, vy, vz) in self.origins.items(): dl_old = self.mesh_dls.get(piece) if not dl_old: continue dl_new = glGenLists(1) self.mesh_dls[piece] = dl_new self.mesh_dls[ dl_old] = dl_old # stash it so __del__ can release it later with gl_compile(dl_new): glTranslatef(-vx, -vy, -vz) glCallList(dl_old) glTranslatef(vx, vy, vz)