def init_model(self, scene): """ Add the pyramid normals and vertices to the View :param scene: The view to render the model to. :type scene: pyglet_helper.objects.View """ # Note that this model is also used by arrow! scene.pyramid_model.gl_compile_begin() vertices = [[0, .5, .5], [0, -.5, .5], [0, -.5, -.5], [0, .5, -.5], [1, 0, 0]] triangle_indices = [0, 0, 0] * 6 triangle_indices[0] = [3, 0, 4] # top triangle_indices[1] = [1, 2, 4] # bottom triangle_indices[2] = [0, 1, 4] # front triangle_indices[3] = [3, 4, 2] # back triangle_indices[4] = [0, 3, 2] # left (base) 1 triangle_indices[5] = [0, 2, 1] # left (base) 2 normals = [[1, 2, 0], [1, -2, 0], [1, 0, 2], [1, 0, -2], [-1, 0, 0], [-1, 0, 0]] gl.glEnable(gl.GL_CULL_FACE) gl.glBegin(gl.GL_TRIANGLES) # Inside for face in range(0, 6): gl.glNormal3f(-normals[face][0], -normals[face][1], -normals[face][2]) for vertex in range(0, 3): #print triangle_indices[face] #print vertices[triangle_indices[face]][2 - vertex] vert = [gl.GLfloat(i) for i in vertices[triangle_indices[face][2 - vertex]]] gl.glVertex3f(*vert) # Outside for face in range(0, 6): gl.glNormal3fv(*[gl.GLfloat(i) for i in normals[face]]) for vertex in range(0, 3): gl.glVertex3f(*[gl.GLfloat(i) for i in vertices[triangle_indices[ face][vertex]]]) gl.glEnd() gl.glDisable(gl.GL_CULL_FACE) self.compiled = True scene.pyramid_model.gl_compile_end()
def render_disk(self, radius, slices, rings, rotation): """ Generate the polygons for a disk :param radius: The disk's radius :type radius: float :param slices: The number of longitudinal lines :type slices: float :param rings: The number of concentric rings in the disk, for rendering :type rings: int :param rotation: The rotation of the disk along the z-axis :type rotation: float """ # rotate the disk so that it is drawn along the VPython axis convention gl.glRotatef(90, 0, gl.GLfloat(rotation), 0) gl.glu.gluDisk(self.quadric, 0.0, radius, slices, rings) gl.glRotatef(-90, 0, gl.GLfloat(rotation), 0)
def createLight(params=()): """Create a point light source. """ # setup light mode/value slots lightDesc = Light( { mode: None for mode in (GL.GL_AMBIENT, GL.GL_DIFFUSE, GL.GL_SPECULAR, GL.GL_POSITION, GL.GL_SPOT_CUTOFF, GL.GL_SPOT_DIRECTION, GL.GL_SPOT_EXPONENT, GL.GL_CONSTANT_ATTENUATION, GL.GL_LINEAR_ATTENUATION, GL.GL_QUADRATIC_ATTENUATION) }, dict()) # configure lights if params: for mode, value in params: if value is not None: if mode in [ GL.GL_AMBIENT, GL.GL_DIFFUSE, GL.GL_SPECULAR, GL.GL_POSITION ]: lightDesc.params[mode] = (GL.GLfloat * 4)(*value) elif mode == GL.GL_SPOT_DIRECTION: lightDesc.params[mode] = (GL.GLfloat * 3)(*value) else: lightDesc.params[mode] = GL.GLfloat(value) return lightDesc
def getFloatv(parName): """Get a single float parameter value, return it as a Python float. Parameters ---------- pName : :obj:`float' OpenGL property enum to query. Returns ------- int """ val = GL.GLfloat() GL.glGetFloatv(parName, val) return float(val.value)
def useMaterial(material): """Use a material for proceeding vertex draws. Parameters ---------- material : :obj:`Material` or None Material descriptor to use. Materials will be disabled if None is specified. Returns ------- None Notes ----- 1. If a material mode has a value of None, a color with all components 0.0 will be assigned. 2. Material colors and shininess values are accessible from shader programs after calling 'useMaterial'. Values can be accessed via built-in 'gl_FrontMaterial' and 'gl_BackMaterial' structures (e.g. gl_FrontMaterial.diffuse). Examples -------- # use the material when drawing useMaterial(matDesc) drawVertexbuffers( ... ) # all meshes will be gold useMaterial(None) # turn off material when done """ nullColor = (GL.GLfloat * 4)(0.0, 0.0, 0.0, 0.0) if material: GL.glEnable(GL.GL_COLOR_MATERIAL) for mode, param in material.params.items(): if param is not None: GL.glMaterialfv(material.face, mode, param) else: GL.glMaterialfv( material.face, mode, nullColor if mode != GL.GL_SHININESS else GL.GLfloat(0)) else: GL.glDisable(GL.GL_COLOR_MATERIAL)
def on_mouse_motion(self, x, y, dx, dy): depth = gl.GLfloat(0.0) gl.glReadPixels(x, y, 1, 1, gl.GL_DEPTH_COMPONENT, gl.GL_FLOAT, ctypes.pointer(depth)) xn = 2.0 * x / self.vp_width - 1.0 yn = 2.0 * y / self.vp_height - 1.0 zn = 2.0 * depth.value - 1.0 xs = 2.5 * xn + 5.0 * zn ys = -2.5 * xn + 5.0 * zn u = xs - int(xs) v = ys - int(ys) if u < 0.5 and v < 0.5: c = 2 elif u < 0.5: c = 1 elif v < 0.5: c = 3 else: c = 0 self.pointed = (int(xs), int(ys), c)
def createMaterial(params=(), face=GL.GL_FRONT_AND_BACK): """Create a new material. Parameters ---------- params : :obj:`list` of :obj:`tuple`, optional List of material modes and values. Each mode is assigned a value as (mode, color). Modes can be GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, GL_SHININESS or GL_AMBIENT_AND_DIFFUSE. Colors must be a tuple of 4 floats which specify reflectance values for each RGBA component. The value of GL_SHININESS should be a single float. If no values are specified, an empty material will be created. face : :obj:`int`, optional Faces to apply material to. Values can be GL_FRONT_AND_BACK, GL_FRONT and GL_BACK. The default is GL_FRONT_AND_BACK. Returns ------- Material A descriptor with material properties. Examples -------- # The values for the material below can be found at # http://devernay.free.fr/cours/opengl/materials.html # create a gold material gold = createMaterial([ (GL.GL_AMBIENT, (0.24725, 0.19950, 0.07450, 1.0)), (GL.GL_DIFFUSE, (0.75164, 0.60648, 0.22648, 1.0)), (GL.GL_SPECULAR, (0.628281, 0.555802, 0.366065, 1.0)) (GL.GL_SHININESS, 0.4 * 128.0)]) # use the material when drawing useMaterial(gold) drawVertexbuffers( ... ) # all meshes will be gold useMaterial(None) # turn off material when done # create a red plastic material, but define reflectance and shine later red_plastic = createMaterial() # you need to convert values to ctypes! red_plastic.values[GL_AMBIENT] = (GLfloat * 4)(0.0, 0.0, 0.0, 1.0) red_plastic.values[GL_DIFFUSE] = (GLfloat * 4)(0.5, 0.0, 0.0, 1.0) red_plastic.values[GL_SPECULAR] = (GLfloat * 4)(0.7, 0.6, 0.6, 1.0) red_plastic.values[GL_SHININESS] = 0.25 * 128.0 # set and draw useMaterial(red_plastic) drawVertexbuffers( ... ) # all meshes will be red plastic useMaterial(None) """ # setup material mode/value slots matDesc = Material( face, { mode: None for mode in (GL.GL_AMBIENT, GL.GL_DIFFUSE, GL.GL_SPECULAR, GL.GL_EMISSION, GL.GL_SHININESS, GL.GL_AMBIENT_AND_DIFFUSE) }, dict()) if params: for mode, param in params: matDesc.params[mode] = \ (GL.GLfloat * 4)(*param) \ if mode != GL.GL_SHININESS else GL.GLfloat(param) return matDesc
def generate_model(self): """ Generate the vertices and normals. """ corner = 0.5 vertices = [ [[+corner, +corner, +corner], [+corner, -corner, +corner], [+corner, -corner, -corner], [+corner, +corner, -corner]], # Right face [[-corner, +corner, -corner], [-corner, -corner, -corner], [-corner, -corner, +corner], [-corner, +corner, +corner]], # Left face [[-corner, -corner, +corner], [-corner, -corner, -corner], [+corner, -corner, -corner], [+corner, -corner, +corner]], # Bottom face [[-corner, +corner, -corner], [-corner, +corner, +corner], [+corner, +corner, +corner], [+corner, +corner, -corner]], # Top face [[+corner, +corner, +corner], [-corner, +corner, +corner], [-corner, -corner, +corner], [+corner, -corner, +corner]], # Front face [[-corner, -corner, -corner], [-corner, +corner, -corner], [+corner, +corner, -corner], [+corner, -corner, -corner]] # Back face ] normals = [[+1, 0, 0], [-1, 0, 0], [0, -1, 0], [0, +1, 0], [0, 0, +1], [0, 0, -1]] # Draw inside (reverse winding and normals) for face in range(self.skip_right_face, 6): gl.glNormal3f(-normals[face][0], -normals[face][1], -normals[face][2]) for vertex in range(0, 3): gl.glVertex3f(gl.GLfloat(vertices[face][3 - vertex][0]), gl.GLfloat(vertices[face][3 - vertex][1]), gl.GLfloat(vertices[face][3 - vertex][2])) for vertex in (0, 2, 3): gl.glVertex3f(gl.GLfloat(vertices[face][3 - vertex][0]), gl.GLfloat(vertices[face][3 - vertex][1]), gl.GLfloat(vertices[face][3 - vertex][2])) # Draw outside for face in range(self.skip_right_face, 6): gl.glNormal3f(gl.GLfloat(normals[face][0]), gl.GLfloat(normals[face][1]), gl.GLfloat(normals[face][2])) for vertex in range(0, 3): gl.glVertex3f(gl.GLfloat(vertices[face][vertex][0]), gl.GLfloat(vertices[face][vertex][1]), gl.GLfloat(vertices[face][vertex][2])) for vertex in (0, 2, 3): gl.glVertex3f(gl.GLfloat(vertices[face][vertex][0]), gl.GLfloat(vertices[face][vertex][1]), gl.GLfloat(vertices[face][vertex][2]))