Example #1
0
    def __init__(self, filename):
        # First, we create a window; this also creates an OpenGL context.
        self.window = GlutWindow(double=True, multisample=True)

        # Then, we set the GLUT display callback function which will be defined later.
        self.window.display_callback = self.display

        # In the OpenGL core profile, there is no such thing as a "standard pipeline"
        # any more. We use the minimalistic <code>defaultpipeline</code> from the
        # <code>glitter.convenience</code> module to create a shader program instead:
        self.shader = get_default_program()

        # We open the HDF5 file specified on the command line for reading:
        if filename.endswith(".dat"):
            data = loadtxt(filename)
            assert data.ndim == 2 and data.shape[1] in (3, 6)

            vertices = data[:, :3]
            vertices -= vertices.min()
            vertices /= vertices.max()
            vertices -= 0.5
            
            colors = data[:, 3:] if data.shape[1] == 6 else None
            colors -= colors.min()
            colors /= colors.max()
            
            elements = None
        else:
            with h5py.File(filename, "r") as f:
                # The vertices, colors and indices of the mesh are read from the
                # corresponding datasets in the HDF5 file. Note that the names of the
                # datasets are mere convention. Colors and indices are allowed to be
                # undefined.
                vertices = f["vertices"]
                colors = f.get("colors", None)
                elements = f.get("indices", None)
                if vertices is not None:
                    vertices = vertices.value
                if colors is not None:
                    colors = colors.value
                if elements is not None:
                    elements = elements.value

        # If no colors were specified, we generate random ones so we can
        # distinguish the triangles without fancy shading.
        if colors is None:
            colors = random((len(vertices), 3))[:, None, :][:, [0] * vertices.shape[1], :]

        # Here, we create a vertex array that contains buffers for two vertex array
        # input variables as well as an index array. If <code>elements</code>
        # is <code>None</code>, the vertex array class will draw all vertices
        # in order.
        self.vao = VertexArray(vertices, colors, elements=elements)
Example #2
0
 def __init__(self):
     self.window = GlutWindow(double=True, multisample=True)
     self.window.display_callback = self.display
     self.window.mouse_callback = self.mouse
     self.shader = ShaderProgram(vertex=vertex_shader,
                                 fragment=fragment_shader)
     self.shader.colormap = Texture1D(cm.spectral(linspace(0, 1, 256)),
                                      wrap_s="MIRRORED_REPEAT")
     self.shader.minval = (-2.5, -1.75)
     self.shader.maxval = (1.0, 1.75)
     self.vao = get_fullscreen_quad()
     self.history = []
Example #3
0
    def __init__(self):
        # First, we create a window; this also creates an OpenGL context.
        self.window = GlutWindow(double=True, alpha=True, depth=True)

        # Then, we set the GLUT display and keyboard callback functions which
        # will be defined later.
        self.window.display_callback = self.display
        self.window.keyboard_callback = self.keyboard

        # Here, we generate numpy arrays to hold the positions, colors, and
        # velocities of the particles:
        num = 200000
        positions = numpy.empty((num, 4), dtype=numpy.float32)
        colors = numpy.empty((num, 4), dtype=numpy.float32)
        velocities = numpy.empty((num, 4), dtype=numpy.float32)

        # So far, the array contents are undefined. We have to initialize them with meaningful values:
        positions[:, 0] = numpy.sin(numpy.arange(0, num) * 2 * numpy.pi /
                                    num) * (numpy.random.random_sample(
                                        (num, )) / 3 + 0.2)
        positions[:, 1] = numpy.cos(numpy.arange(0, num) * 2 * numpy.pi /
                                    num) * (numpy.random.random_sample(
                                        (num, )) / 3 + 0.2)
        positions[:, 2:] = 0, 1
        colors[:] = 0, 1, 0, 1
        velocities[:, :2] = 2 * positions[:, :2]
        velocities[:, 2] = 3
        velocities[:, 3] = numpy.random.random_sample((num, ))

        # Instead of simply generating a vertex array from the position and color
        # data, we first generate array buffers for them:
        gl_positions = ArrayBuffer(data=positions, usage="DYNAMIC_DRAW")
        gl_colors = ArrayBuffer(data=colors, usage="DYNAMIC_DRAW")
        # These array buffers will later also be used by OpenCL. We do not need to
        # wrap <code>velocities</code> in this way, as it will only be used by
        # OpenCL and can be wrapped in an OpenCL buffer directly.

        # We now create a vertex array that will pass the position and color data
        # to the shader. The vertex array constructor accepts
        # <code>ArrayBuffer</code> instances:
        self.vao = VertexArray(gl_positions, gl_colors)

        # In the OpenGL core profile, there is no such thing as a "standard pipeline"
        # any more. We use the minimalistic <code>defaultpipeline</code> from the
        # <code>glitter.convenience</code> module to create a shader program instead:
        self.shader = get_default_program()

        # Here, we create the <code>CLCode</code> object that manages OpenCL
        # interaction. It is passed the OpenGL buffer objects as well as a numpy
        # array of velocities.
        self.clcode = CLCode(gl_positions, gl_colors, velocities)
    def __init__(self):
        self.window = GlutWindow(double=True,
                                 multisample=True,
                                 shape=(100, 800))
        self.window.display_callback = self.display

        self.shader = ShaderProgram(vertex=vertex_shader,
                                    fragment=fragment_shader)
        self.shader.dimy, self.shader.dimx = self.window.shape
        self.fbo = Framebuffer(
            RectangleTexture(shape=self.window.shape + (3, )))

        self.vao = VertexArray(
            ((-1.0, -1.0), (-1.0, 1.0), (1.0, 1.0), (1.0, -1.0)),
            elements=((0, 1, 2), (0, 2, 3)))
    def create_default_context():
        """Create a default offscreen rendering context.

        @todo: This is window system dependent; create an appropriate context
        dynamically.
        @todo: When no context exists, create a raw offscreen context instead of a
        hidden GLUT window so that rendering is possible without an X connection.
        """

        try:
            from glitter.contexts.glx import GLXContext
            return GLXContext()
        except ImportError:
            from glitter.contexts.glut import GlutWindow
            return GlutWindow(shape=(1, 1), hide=True)
Example #6
0
    def __init__(self):
        # First, we create a window; this also creates an OpenGL context.
        self.window = GlutWindow(double=True, multisample=True)

        # Then, we set the GLUT display callback function which will be defined later.
        self.window.display_callback = self.display

        # In the OpenGL core profile, there is no such thing as a "standard pipeline"
        # any more. We use the minimalistic <code>defaultpipeline</code> from the
        # <code>glitter.convenience</code> module to create a shader program instead:
        self.shader = get_default_program()

        # Here, we create a vertex array that contains buffers for two vertex array
        # input variables as well as an index array:
        n_points = 100000
        self.vao = VertexArray(randn(n_points, 3), randn(n_points, 3))
Example #7
0
 def __init__(self, images):
     self.window = GlutWindow(double=True, multisample=True)
     self.window.display_callback = self.display
     self.window.keyboard_callback = self.keyboard
     self.window.special_callback = self.special
     self.images = images
     self.window.shape = self.images[0].shape[:2]
     self.render_pipeline = get_copy_pipeline_2d(
         context=self.window,
         sampler_type="isampler2D",
         maxval=255,
         yscale=-1,
         use_framebuffer=False,
         image=Texture2D(self._prepare_image(0)))
     self.current_index = 0
     self.fps = 25
     self.playing = False
Example #8
0
 def __init__(self, filename):
     self.window = GlutWindow(double=True, multisample=True)
     self.window.display_callback = self.display
     self.shader = get_default_program()
     self.fbo = Framebuffer(
         depth=Texture2D(shape=self.window.shape + (1, ), depth=True))
     self.copy_pipeline = get_copy_pipeline_2d(image=self.fbo.depth,
                                               use_framebuffer=False)
     with h5py.File(filename, "r") as f:
         vertices = f["vertices"]
         colors = f.get("colors", None)
         elements = f.get("indices", None)
         if colors is None:
             colors = random(
                 (len(vertices), 3))[:, None, :][:,
                                                 [0] * vertices.shape[1], :]
         self.vao = VertexArray(vertices, colors, elements=elements)
Example #9
0
def get_gl_context(option="g"):
    """Returns an OpenGL context. Options: g(lut), q(t)"""
    if "g" == option:
        print "Creating GLUT context."
        from glitter.contexts.glut import GlutWindow
        gl_context = GlutWindow(shape=(1, 1), hide=True)
    elif "q" == option:
        print "Creating QT context."
        from PySide import QtGui
        from glitter.contexts.qt import QtWidget
        app = QtGui.QApplication.instance()
        if app is None:
            app = QtGui.QApplication(sys.argv)
        gl_context = QtWidget(None)
    else:
        raise Exception("Unknown option: %s" % option)
    return gl_context
Example #10
0
    def __init__(self):
        # First, we create a window; this also creates an OpenGL context.
        self.window = GlutWindow(double=True, multisample=True)

        # Then, we set the GLUT display callback function which will be defined
        # later.
        self.window.display_callback = self.display

        # We also set mouse callbacks that will display the pixel color in the
        # title bar.
        self.window.mouse_callback = self.mouse
        self.window.motion_callback = self.motion

        # In the OpenGL core profile, there is no such thing as a "standard pipeline"
        # any more. We use the minimalistic <code>defaultpipeline</code> from the
        # <code>glitter.convenience</code> module to create a shader program instead:
        self.shader = get_default_program()

        # Here, we create a vertex array that contains buffers for two vertex array
        # input variables as well as an index array:
        self.vao = VertexArray(vertices, colors, elements=indices)
Example #11
0
    # clear the screen
    window.clear(color=True, depth=True)
    # display the backbuffer
    window.swap_buffers()


def keyboard(key, x, y):
    # if F1 or ALT-Enter is pressed, toggle fullscreen
    # TODO: key constants like GLUT_KEY_F1 should be available as an enum
    if key == _gl.GLUT_KEY_F1 or (get_alt_state() and key == ord('\r')):
        window.toggle_full_screen()
    elif key == 27:  # escape key
        raise SystemExit  # makes program quit out of main_loop


if __name__ == "__main__":
    # create main window
    window = GlutWindow(name="NeHe's OpenGL Framework", double=True)
    # set background color to black
    # TODO: it would be nice if window.color_clear_value = (0, 0, 0) would
    # implicitly set alpha to 1
    window.color_clear_value = (0, 0, 0, 1)
    # callback for rendering
    window.display_callback = display
    # callback for normal keys and special keys (like F1), both handled by same function here
    window.keyboard_callback = window.special_callback = keyboard
    # render all the time
    window.idle_callback = window.post_redisplay
    # loops until SystemExit is raised or window is closed
    main_loop()
Example #12
0
        triangle.draw(primitive_types.TRIANGLES)
    # display the backbuffer
    window.swap_buffers()


def keyboard(key, x, y):
    # if F1 or ALT-Enter is pressed, toggle fullscreen
    if key == _gl.GLUT_KEY_F1 or (get_alt_state() and key == ord('\r')):
        window.toggle_full_screen()
    elif key == 27:  # escape key
        raise SystemExit  # makes program quit out of main_loop


if __name__ == "__main__":
    # create main window
    window = GlutWindow(name="My First Quad and Triangle", double=True)
    # set background color to black
    window.color_clear_value = (0, 0, 0, 1)
    # callback for rendering
    window.display_callback = display
    # callback for normal keys and special keys (like F1), both handled by same function here
    window.keyboard_callback = window.special_callback = keyboard
    # render all the time
    window.idle_callback = window.post_redisplay
    # shader program for rendering
    shader = get_default_program(modelview=False, color=False)
    quad = VertexArray(((-0.7, 0.3, 0.0, 1.0), (-0.1, 0.3, 0.0, 1.0),
                        (-0.7, -0.3, 0.0, 1.0), (-0.1, -0.3, 0.0, 1.0)))
    triangle = VertexArray(
        ((0.1, -0.2, 0.0, 1.0), (0.7, -0.2, 0.0, 1.0), (0.4, 0.2, 0.0, 1.0)))
    # loops until SystemExit is raised or window is closed
Example #13
0
    def __init__(self):
        # First, we create a window; this also creates an OpenGL context.
        self.window = GlutWindow(double=True, multisample=True)

        # Then, we set the GLUT display and keyboard callback functions which
        # will be defined later.
        self.window.display_callback = self.display
        self.window.keyboard_callback = self.keyboard

        # A shader program is built from the previously defined vertex and
        # fragment codes:
        self.shader = ShaderProgram(vertex=vertex_shader,
                                    fragment=fragment_shader)

        # This shader program is then used to build a pipeline. A pipeline is a
        # convenience object that encapsulates a vertex array for input, a
        # shader program for processing, and a framebuffer for output. The
        # framebuffer is optional (we could render directly to the screen if we
        # wanted), but we will render into a texture and copy the texture to
        # the screen for instructional purposes. The <code>Pipeline</code>
        # constructor automatically creates an empty vertex array and a
        # framebuffer with no attachments. Named constructor arguments are
        # interpreted as attributes of the vertex array and the framebuffer or
        # as named inputs and outputs of the shader. This means we can directly
        # pass in arrays of vertices and colors that will be bound to
        # <code>in_position</code> and <code>in_color</code>, respectivey, as
        # well as the array of element indices to draw and an empty texture to
        # bind to the framebuffer:
        self.render_pipeline = Pipeline(self.shader,
                                        in_position=vertices,
                                        in_color=colors,
                                        elements=indices,
                                        out_color=RectangleTexture(shape=(300,
                                                                          300,
                                                                          3)))

        # Shader uniform variables like textures can also be set directly on
        # the pipeline. Here we initialize two textures with random data:
        self.render_pipeline.texture_0 = Texture2D(random((30, 30, 4)))
        self.render_pipeline.texture_1 = RectangleTexture(random((30, 30, 4)))

        # Many properties, such as the filtering mode for textures, can
        # directly be set as attributes on the corresponding objects:
        self.render_pipeline.texture_0.min_filter = Texture2D.min_filters.NEAREST
        self.render_pipeline.texture_0.mag_filter = Texture2D.mag_filters.NEAREST

        # For copying the texture to the screen, we create another shader
        # program.
        self.copy_shader = ShaderProgram(vertex=copy_vertex_shader,
                                         fragment=copy_fragment_shader)

        # The input texture of this shader program is the output texture of the
        # previous pipeline. Since all textures and framebuffers are
        # automatically bound and unbound, we do not need to worry about
        # whether the framebuffer is still writing to the texture.
        self.copy_shader.image = self.render_pipeline.out_color

        # Instead of using a pipeline with named vertex shader inputs, we can
        # also create a vertex array object directly with a list of vertex
        # shader inputs to use. Here we use only a single vertex shader input:
        # the coordinates of a fullscreen quad. The <code>elements</code>
        # parameter defines two triangles that make up the quad.
        self.vao = VertexArray(
            ((-1.0, -1.0), (-1.0, 1.0), (1.0, 1.0), (1.0, -1.0)),
            elements=((0, 1, 2), (0, 2, 3)))