def on_draw():
    a = 1.6
    b = a * sqrt(3) / 3
    r = sqrt(1 - b * b)
    R = Vector3(a, a, a).normalized() * b
    cs = Matrix4.new_translate(R[0], R[1], R[2]) * Matrix4.new_look_at(
        Vector3(0, 0, 0), R, Vector3(0, 1, 0))

    glDisable(GL_DEPTH_TEST)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()
    draw_coords(Matrix4.new_identity(), 2)
    draw_line((0, 0, 0), R, (1, 1, 0))
    draw_coords(cs, r, 3)
    glEnable(GL_DEPTH_TEST)
    draw_triangle((a, 0, 0), (0, a, 0), (0, 0, a), (.5, .5, 1), .2)
    draw_sphere(3, (1, .5, .5), .2)
Esempio n. 2
0
    def on_draw(self):

        # Prevent trying to draw before things have been set up
        if not hasattr(self, "offscreen_buffer"):
            return

        # Model matrix we'll use to position the main model
        suzanne_model_matrix = (Matrix4.new_identity().rotatex(
            -math.pi / 2).rotatez(time()))  # Rotate over time
        plane_model_matrix = Matrix4.new_rotatey(math.pi).translate(0, 0, 2)

        # Render to an offscreen buffer
        with self.offscreen_buffer, self.view_program, \
                enabled(gl.GL_DEPTH_TEST), disabled(gl.GL_CULL_FACE):

            gl.glDepthMask(gl.GL_TRUE)

            w, h = self.size
            aspect = h / w

            # Calculate a view frustum; this is basically our camera.
            near = 5
            far = 15
            width = 2
            height = 2 * aspect
            frustum = (Matrix4.new(near / width, 0, 0, 0, 0, near / height, 0,
                                   0, 0, 0, -(far + near) / (far - near), -1,
                                   0, 0, -2 * far * near / (far - near), 0))

            # The view matrix positions the camera in the scene
            view_matrix = (Matrix4.new_identity().translate(0, 0, -8))

            # Send the matrices to GL
            gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE,
                                  gl_matrix(frustum * view_matrix))
            gl.glUniformMatrix4fv(1, 1, gl.GL_FALSE,
                                  gl_matrix(suzanne_model_matrix))

            gl.glUniform4f(2, 0.3, 0.3, 1,
                           1)  # Set the "color" uniform to blue
            self.suzanne.draw()

            # We'll also draw a simple plane behind the main model
            gl.glUniformMatrix4fv(1, 1, gl.GL_FALSE,
                                  gl_matrix(plane_model_matrix))
            gl.glUniform4f(2, 0.3, 1, 0.3,
                           1)  # Set the "color" uniform to green
            self.plane.draw(mode=gl.GL_TRIANGLE_STRIP)

        # Render shadow buffer
        # Basically the same scene as above, but to a different buffer and from a different view
        with self.shadow_buffer, self.view_program, enabled(
                gl.GL_DEPTH_TEST), disabled(gl.GL_CULL_FACE):
            gl.glDepthMask(gl.GL_TRUE)

            frustum = Matrix4.new_perspective(1, 1, 1, 12)
            view_matrix = (Matrix4.new_identity().translate(
                0, 0, -4).rotatey(0.5).rotatex(0.3))
            light_pos = (view_matrix.inverse() * Point3(0, 0, 0))
            light_view_matrix = frustum * view_matrix
            gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE,
                                  gl_matrix(light_view_matrix))
            gl.glUniformMatrix4fv(1, 1, gl.GL_FALSE,
                                  gl_matrix(suzanne_model_matrix))
            gl.glUniform4f(2, 0.9, 0.3, 0.4, 1)
            self.suzanne.draw()

            gl.glUniformMatrix4fv(1, 1, gl.GL_FALSE,
                                  gl_matrix(plane_model_matrix))
            self.plane.draw(mode=gl.GL_TRIANGLE_STRIP)

        # Now draw the offscreen buffer to another buffer, combining it with the
        # lighting information to get a nice image.
        # Note: This step is pretty pointless here, as we might just draw directly to screen.
        # Just demonstrates how to do it.
        with self.vao, self.offscreen_buffer2, self.lighting_program, disabled(
                gl.GL_CULL_FACE, gl.GL_DEPTH_TEST):
            gl.glUniform3f(0, *light_pos)
            gl.glUniformMatrix4fv(1, 1, gl.GL_FALSE,
                                  gl_matrix(light_view_matrix))
            # Bind some of the offscreen buffer's textures so the shader can read them.
            with self.offscreen_buffer["color"], self.offscreen_buffer["normal"], \
                    self.offscreen_buffer["position"], self.shadow_buffer["depth"]:
                gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)

        # Now render the finished image to the screen
        with self.vao, self.copy_program, disabled(gl.GL_CULL_FACE,
                                                   gl.GL_DEPTH_TEST):
            with self.offscreen_buffer2["color"]:
                gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)