示例#1
0
    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()
示例#2
0
    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)
示例#3
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
示例#4
0
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)
示例#5
0
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)
示例#6
0
    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)
示例#7
0
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
示例#8
0
 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]))