def test_translation( self ):
        root = SceneNode( '/root' )
        child = SceneNode( '/child' )
        
        root.add_child( child )

        #
        # Initial state
        #
        test_translation( self, root.transform, [0.0, 0.0, 0.0] )
        test_translation( self, root.world_transform, [0.0, 0.0, 0.0] )
        test_translation( self, child.transform, [0.0, 0.0, 0.0] )
        test_translation( self, child.world_transform, [0.0, 0.0, 0.0] )

        #
        # Root Translate += 1.0, 1.0, 1.0
        #
        root.transform.translation += [1.0, 1.0, 1.0]
        test_translation( self, root.transform, [1.0, 1.0, 1.0] )
        test_translation( self, root.world_transform, [1.0, 1.0, 1.0] )
        test_translation( self, child.transform, [0.0, 0.0, 0.0] )
        test_translation( self, child.world_transform, [1.0, 1.0, 1.0] )

        #
        # Child Translate -= 1.0, 1.0, 1.0
        #
        child.transform.translation -= [1.0, 1.0, 1.0]
        test_translation( self, root.transform, [1.0, 1.0, 1.0] )
        test_translation( self, root.world_transform, [1.0, 1.0, 1.0] )
        test_translation( self, child.transform, [-1.0,-1.0,-1.0] )
        test_translation( self, child.world_transform, [0.0, 0.0, 0.0] )
    def test_child( self ):
        root = SceneNode( '/root' )
        child = SceneNode( '/child' )

        root.add_child( child )

        test_initial_state( self, root )
        test_initial_state( self, child )
Exemple #3
0
    def setup_scene( self ):
        # create an fps display
        self.fps_display = pyglet.clock.ClockDisplay()

        # create a list of renderables
        self.renderables = []

        # create a scene
        self.scene_node = SceneNode( 'root' )

        self.grid_node = SceneNode( 'grid' )
        self.scene_node.add_child( self.grid_node )

        self.grid_render_node = RenderCallbackNode(
            'mesh',
            grid.initialise_grid,
            grid.render_grid
            )
        self.grid_node.add_child( self.grid_render_node )

        # add to our list of renderables
        self.renderables.append( self.grid_render_node )

        # move the grid backward so we can see it
        # and move it down so we start above it
        self.grid_node.transform.inertial.translate(
            [ 0.0, 0.0, -80.0 ]
            )
        
        # create a camera and a view matrix
        self.view_matrix = ProjectionViewMatrix(
            self.viewport.aspect_ratio,
            fov = 45.0,
            near_clip = 1.0,
            far_clip = 200.0
            )
        # create a camera
        self.camera = CameraNode(
            'camera',
            self.view_matrix
            )
        self.scene_node.add_child( self.camera )

        # move the camera up so it starts above the grid
        self.camera.transform.inertial.translate(
            [ 0.0, 20.0, 0.0 ]
            )
        
        # assign a camera controller
        # we'll use the 6 degrees of freedom
        # camera for this one
        self.camera_controller = SixDOF_Controller(
            self.camera.transform
            )
        def setup_scene():
            # create a scene
            # we'll create the scene as a tree
            # to demonstrate the depth-first iteration
            # technique we will use to render it
            self.scene_root = SceneNode( 'root' )

            # the letter indicates the tier the node
            # is on, a = tier 1, b = tier 2, etc.
            self.a1 = SceneNode( 'a1' )
            self.b1 = SceneNode( 'b1' )
            self.b2 = SceneNode( 'b2' )
            self.c1 = SceneNode( 'c1' )
            self.c2 = SceneNode( 'c2' )
            self.c3 = SceneNode( 'c3' )

            # the tree looks as follows
            #                / c1
            #           / b1 - c2
            # root - a1
            #           \ b2 - c3
            self.scene_root.add_child( self.a1 )
            self.a1.add_child( self.b1 )
            self.a1.add_child( self.b2 )
            self.b1.add_child( self.c1 )
            self.b1.add_child( self.c2 )
            self.b2.add_child( self.c3 )

            # if we set the nodes local scale (transform)
            # it will be affected by the parent's scale.
            # by setting the world scale (world_transform)
            # we are ignoring the parent's scale.
            # re-attaching the node would invalidate this.
            self.a1.world_transform.scale = [2.0, 2.0, 2.0]
            self.b1.world_transform.scale = [1.0, 1.0, 1.0]
            self.b2.world_transform.scale = [1.0, 1.0, 1.0]
            self.c1.world_transform.scale = [0.8, 0.8, 0.8]
            self.c2.world_transform.scale = [0.8, 0.8, 0.8]
            self.c3.world_transform.scale = [0.8, 0.8, 0.8]

            # move our scene nodes
            # leave a1 at the centre
            self.b1.transform.object.translate( [10.0, 0.0, 0.0 ] )
            self.b2.transform.object.translate([-10.0, 0.0, 0.0 ] )
            self.c1.transform.object.translate( [ 5.0, 0.0, 0.0 ] )
            self.c2.transform.object.translate( [-5.0, 0.0, 0.0 ] )
            self.c3.transform.object.translate( [ 5.0, 0.0, 0.0 ] )

            # rotate the our b nodes so they tilting forward
            self.b1.transform.object.rotate_x( math.pi / 4.0 )
            self.b2.transform.object.rotate_x( math.pi / 4.0 )
Exemple #5
0
    def setup_scene( self ):
        super( Application, self ).setup_scene()
        
        # enable texturing
        glEnable( GL_TEXTURE_2D )

        # set our gl clear colour
        glClearColor( 0.2, 0.2, 0.2, 1.0 )

        # create a scene node to hold our GOL renderable
        self.gol_node = SceneNode( "GOL_Node" )
        self.scene_node.add_child( self.gol_node )
        
        # get the maximum viewport size
        max_viewport_size = (c_int * 2)()
        glGetIntegerv( GL_MAX_VIEWPORT_DIMS, max_viewport_size )
        
        max_viewport_size = (max_viewport_size[ 0 ], max_viewport_size[ 1 ])
        print "Max viewport size", max_viewport_size
        
        # make the GOL board
        # ensure it is a power of 2 for ou texture
        board_size = (2048, 2048)
        if board_size > max_viewport_size:
            board_size = max_viewport_size
        
        self.gol = GOL_Renderable( board_size )
        # add our renderable to the scene
        self.gol_node.add_child( self.gol )
        # add to our list of renderables
        self.renderables.append( self.gol )
Exemple #6
0
    def setup_scene( self ):
        # create an fps display
        self.fps_display = pyglet.clock.ClockDisplay()

        # store a list of our renderables
        self.renderables = []

        # create a scene
        self.scene_node = SceneNode( 'root' )

        self.mesh_node = SceneNode( 'obj' )
        self.scene_node.add_child( self.mesh_node )

        # create a mesh object and render node
        self.mesh = OBJ_Mesh( 'examples/data/obj/cessna.obj' )
        self.mesh_render_node = RenderCallbackNode(
            'mesh',
            self.initialise_mesh,
            self.render_mesh
            )
        self.mesh_node.add_child( self.mesh_render_node )

        # add to our list of renderables
        self.renderables.append( self.mesh_render_node )
        
        # create a camera and a view matrix
        self.view_matrix = ProjectionViewMatrix(
            self.viewport.aspect_ratio,
            fov = 45.0,
            near_clip = 1.0,
            far_clip = 200.0
            )
        # create a camera
        self.camera = CameraNode(
            'camera',
            self.view_matrix
            )
        self.scene_node.add_child( self.camera )

        # move the camera so we can see the model
        self.camera.transform.object.translate(
            [ 0.0, 20.0, 30.0 ]
            )

        # rotate the camera so it is pointing down
        self.camera.transform.object.rotate_x( -math.pi / 4.0 )
    def test_scale( self ):
        root = SceneNode( '/root' )
        child = SceneNode( '/child' )
        
        root.add_child( child )

        #
        # Initial state
        #
        test_scale( self, root.transform, [1.0, 1.0, 1.0] )
        test_scale( self, root.world_transform, [1.0, 1.0, 1.0] )
        test_scale( self, child.transform, [1.0, 1.0, 1.0] )
        test_scale( self, child.world_transform, [1.0, 1.0, 1.0] )

        #
        # Root Scale = 2.0
        #
        root.transform.scale = [2.0, 2.0, 2.0]
        test_scale( self, root.transform, [2.0, 2.0, 2.0] )
        test_scale( self, root.world_transform, [2.0, 2.0, 2.0] )
        test_scale( self, child.transform, [1.0, 1.0, 1.0] )
        test_scale( self, child.world_transform, [2.0, 2.0, 2.0] )

        #
        # Child World Scale = 2.0
        #
        child.world_transform.scale = [1.0, 1.0, 1.0]
        test_scale( self, root.transform, [2.0, 2.0, 2.0] )
        test_scale( self, root.world_transform, [2.0, 2.0, 2.0] )
        test_scale( self, child.transform, [0.5, 0.5, 0.5] )
        test_scale( self, child.world_transform, [1.0, 1.0, 1.0] )

        #
        # Root Scale = 1.0
        #
        root.transform.scale = [1.0, 1.0, 1.0]
        test_scale( self, root.transform, [1.0, 1.0, 1.0] )
        test_scale( self, root.world_transform, [1.0, 1.0, 1.0] )
        test_scale( self, child.transform, [0.5, 0.5, 0.5] )
        test_scale( self, child.world_transform, [0.5, 0.5, 0.5] )
Exemple #8
0
    def setup_scene(self):
        """Creates the scene to be rendered.
        Creates our camera, scene graph, 
        """
        # don't call 'SimpleApplication's setup_scene
        CoreApplication.setup_scene(self)

        # setup our GL state
        # enable z buffer
        glEnable(GL_DEPTH_TEST)

        # enable back face culling
        glEnable(GL_CULL_FACE)
        glCullFace(GL_BACK)

        # load our texture
        # use the PIL decoder as the pyglet one is broken
        # and loads most images as greyscale
        path = os.path.join(os.path.dirname(__file__), "../../data/md2/sydney.bmp")
        image = Image.open(path)
        self.texture = Texture2D(GL_TEXTURE_2D)
        self.texture.bind()
        self.texture.set_min_mag_filter(min=GL_LINEAR, mag=GL_LINEAR)
        # load the image from PIL
        # MD2 textures are inverted
        pygly.pil_texture.set_pil_image(self.texture, image, flip=False)
        self.texture.unbind()

        # create a grid of cubes
        self.grid_root = SceneNode("grid_root")
        self.scene_node.add_child(self.grid_root)

        # store a list of renderables
        path = os.path.join(os.path.dirname(__file__), "../../data/md2/sydney.md2")

        self.mesh_node = RenderCallbackNode("mesh", None, self.render_node)
        # rotate the mesh to face the camera
        self.mesh_node.transform.object.rotate_y(math.pi)

        self.mesh_node.mesh = MD2_Mesh(path)
        self.mesh_node.mesh.load()

        # attach to our scene graph
        self.grid_root.add_child(self.mesh_node)

        # scale the node
        # self.mesh_node.transform.scale = 0.2

        # store current animation
        self.animation_number = 0
        self.set_animation(self.animation_number)
    def test_translation_with_rotation( self ):
        root = SceneNode( '/root' )
        child = SceneNode( '/child' )
        
        root.add_child( child )

        #
        # Rotate 180 deg (1 * pi) about the Y axis (yaw)
        #
        root.transform.object.rotate_y( math.pi )

        identity = matrix44.identity()
        root_matrix = matrix44.create_from_y_rotation( math.pi )

        #
        # Translate the child node
        #
        child.transform.translation = [1.0, 1.0, 1.0]

        test_translation( self, root.transform, [0.0, 0.0, 0.0] )
        test_translation( self, root.world_transform, [0.0, 0.0, 0.0] )
        test_translation( self, child.transform, [1.0, 1.0, 1.0] )
        # Y does not invert
        test_translation( self, child.world_transform, [-1.0, 1.0,-1.0] )
Exemple #10
0
    def setup_scene( self ):
        """Creates the scene to be rendered.
        Creates our camera, scene graph, 
        """
        # don't call 'SimpleApplication's setup_scene
        CoreApplication.setup_scene( self )

        # setup our GL state
        # enable z buffer
        glEnable( GL_DEPTH_TEST )

        # enable back face culling
        glEnable( GL_CULL_FACE )
        glCullFace( GL_BACK )

        # create a grid of cubes
        self.grid_root = SceneNode( 'grid_root' )
        self.scene_node.add_child( self.grid_root )

        # store a list of renderables
        path = os.path.join(
            os.path.dirname( __file__ ),
            '../data/obj/capsule.obj'
            )

        self.mesh_node = RenderCallbackNode(
            'mesh',
            None,
            self.render_node
            )
        # rotate the mesh to face the camera
        self.mesh_node.transform.object.rotate_y( math.pi )

        self.mesh_node.mesh = OBJ_Mesh( path )
        self.mesh_node.mesh.load()

        # attach to our scene graph
        self.grid_root.add_child( self.mesh_node )

        # scale the node
        self.mesh_node.transform.scale = 1.0

        # create a list of groups to render
        # by default, render all groups
        # this may be in-efficient if data is contained in
        # multiple groups
        self.groups = self.mesh_node.mesh.data.meshes.keys()
        def setup_camera():
            # add another node that our camera will be under
            # we can rotate this node to show how the cameras work
            self.camera2_parent = SceneNode( 'camera2_parent' )
            self.scene_root.add_child( self.camera2_parent )

            # create our camera node
            self.camera2 = CameraNode( 'camera2', pyrr.matrix44.create_identity() )
            self.camera2_parent.add_child( self.camera2 )

            # place the camera at the same position as the previous one
            #self.camera2.transform.translation = self.camera.transform.translation
            #self.camera2.transform.orientation = self.camera.transform.orientation
            #self.camera2.transform.scale = self.camera.transform.scale

            self.camera2.transform.object.translate(
                [ 0.0, 0.0, 35.0 ]
                )
        def create_cubes():
            # create a grid of cubes
            self.grid_root = SceneNode( 'grid_root' )
            self.scene_root.add_child( self.grid_root )
            self.grid_root.transform.scale = [2.0, 2.0, 2.0]

            # create a number of cubes
            # the grid will extend from -5 to +5
            x,z = numpy.mgrid[
                -5:5:11j,
                -5:5:11j
                ]
            x = x.flatten()
            z = z.flatten()

            positions = numpy.vstack(
                (x, numpy.zeros( x.shape ), z )
                )
            positions = positions.T

            # set the distance of the cubes
            # cube is -1 -> 1
            # so distance is 2
            positions *= 2.5

            # store a list of renderables
            self.renderables = []

            for position in positions:
                node = SceneNode( 'node-%s' % position )
                node.transform.inertial.translation = position
                self.grid_root.add_child( node )
                self.renderables.append( node )

            # create a range of colours from 0.1 -> 0.5
            self.cube_colours = numpy.linspace( 0.1, 0.5, len(positions) )
            # make them consistent for RGBA
            self.cube_colours = self.cube_colours.repeat( 4 )
            self.cube_colours.shape = (-1, 4)
            # replace the Blue and Alpha value
            self.cube_colours[:,2] = 0.5
            self.cube_colours[:,3] = 0.5
Exemple #13
0
class MD2_Application(SimpleApplication):
    def setup(self):
        super(MD2_Application, self).setup()

        self.setup_keyboard()

        print "Press any key to move to the next animation"

    def setup_keyboard(self):
        self.window.push_handlers(on_key_release=self.on_key_release)

    def on_key_release(self, *args):
        self.increment_animation()

    def setup_viewports(self):
        super(MD2_Application, self).setup_viewports()

        self.colours[0] = (1.0, 1.0, 1.0, 1.0)

    def setup_camera(self):
        super(MD2_Application, self).setup_camera()

        # move the camera
        self.cameras[0].transform.inertial.translate([0.0, -3.0, 0.0])
        # tilt the camera downward
        self.cameras[0].transform.object.rotate_x(math.pi / 8.0)

    def setup_scene(self):
        """Creates the scene to be rendered.
        Creates our camera, scene graph, 
        """
        # don't call 'SimpleApplication's setup_scene
        CoreApplication.setup_scene(self)

        # setup our GL state
        # enable z buffer
        glEnable(GL_DEPTH_TEST)

        # enable back face culling
        glEnable(GL_CULL_FACE)
        glCullFace(GL_BACK)

        # load our texture
        # use the PIL decoder as the pyglet one is broken
        # and loads most images as greyscale
        path = os.path.join(os.path.dirname(__file__), "../../data/md2/sydney.bmp")
        image = Image.open(path)
        self.texture = Texture2D(GL_TEXTURE_2D)
        self.texture.bind()
        self.texture.set_min_mag_filter(min=GL_LINEAR, mag=GL_LINEAR)
        # load the image from PIL
        # MD2 textures are inverted
        pygly.pil_texture.set_pil_image(self.texture, image, flip=False)
        self.texture.unbind()

        # create a grid of cubes
        self.grid_root = SceneNode("grid_root")
        self.scene_node.add_child(self.grid_root)

        # store a list of renderables
        path = os.path.join(os.path.dirname(__file__), "../../data/md2/sydney.md2")

        self.mesh_node = RenderCallbackNode("mesh", None, self.render_node)
        # rotate the mesh to face the camera
        self.mesh_node.transform.object.rotate_y(math.pi)

        self.mesh_node.mesh = MD2_Mesh(path)
        self.mesh_node.mesh.load()

        # attach to our scene graph
        self.grid_root.add_child(self.mesh_node)

        # scale the node
        # self.mesh_node.transform.scale = 0.2

        # store current animation
        self.animation_number = 0
        self.set_animation(self.animation_number)

    def increment_animation(self):
        self.animation_number += 1
        if self.animation_number >= len(self.mesh_node.mesh.animations):
            self.animation_number = 0

        self.set_animation(self.animation_number)

    def set_animation(self, number):
        self.animation_number = number
        self.animation = pymesh.md2.MD2.animations.keys()[number]

        start, end = self.mesh_node.mesh.animation_start_end_frame(self.animation)
        num_frames = self.mesh_node.mesh.num_frames

        if start >= num_frames or end >= num_frames:
            print 'Animation "%s" not present' % self.animation
            return self.set_animation(0)

        self.mesh_node.mesh.frame_1 = start
        self.mesh_node.mesh.frame_2 = start + 1

        # some animations have only 1 frame
        if self.mesh_node.mesh.frame_2 > end:
            self.mesh_node.mesh.frame_2 = end

        print "Animation:", self.animation

    def step(self, dt):
        """Updates our scene and triggers the on_draw event.
        This is scheduled in our __init__ method and
        called periodically by pyglet's event callbacks.
        We need to manually call 'on_draw' as we patched
        it our of pyglets event loop when we patched it
        out with pygly.monkey_patch.
        Because we called 'on_draw', we also need to
        perform the buffer flip at the end.
        """
        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.grid_root.transform.object.rotate_y(dt * 0.2)

        # update our frame rates
        frame_rate = self.mesh_node.mesh.frame_rate

        # increment our frame
        self.mesh_node.mesh.interpolation += dt * frame_rate

        # calculate the current and next frame
        # and the blending fraction
        fraction, whole = math.modf(self.mesh_node.mesh.interpolation)
        whole = int(whole)

        # check if we're moving to the next keyframe
        if whole > 0:
            # ensure fraction remains < 1.0
            self.mesh_node.mesh.interpolation = fraction

            # increment our frames
            self.mesh_node.mesh.frame_1 += whole
            self.mesh_node.mesh.frame_2 += whole

            # get the animation's start and end frame
            start, end = self.mesh_node.mesh.animation_start_end_frame(self.animation)

            num_frames = self.mesh_node.mesh.num_frames
            if start >= num_frames:
                start = num_frames
                end = num_frames
                print "Animation has insufficient frames"
            elif end >= num_frames:
                end = num_frames
                print "Animation has insufficient frames"

            # ensure we don't go outside the animation
            animation_size = (end - start) + 1
            if self.mesh_node.mesh.frame_1 > end:
                self.mesh_node.mesh.frame_1 -= animation_size

            if self.mesh_node.mesh.frame_2 > end:
                self.mesh_node.mesh.frame_2 -= animation_size

        # this will trigger the draw event and buffer flip
        CoreApplication.step(self, dt)

    def render_scene(self, camera):
        """Renders each renderable in the scene
        using the current projection and model
        view matrix.
        The original GL state will be restored
        upon leaving this function.
        """
        projection = camera.view_matrix.matrix
        model_view = camera.model_view

        # bind our diffuse texture
        glActiveTexture(GL_TEXTURE0)
        self.texture.bind()

        # update the model view
        world_matrix = self.mesh_node.world_transform.matrix
        current_mv = matrix44.multiply(world_matrix, model_view)

        # render a cube
        self.mesh_node.render(projection=projection, model_view=current_mv)

        glActiveTexture(GL_TEXTURE0)
        self.texture.unbind()

    def render_node(self, node, **kwargs):
        node.mesh.render(**kwargs)
Exemple #14
0
class Application( object ):
    
    def __init__( self ):
        super( Application, self ).__init__()
        
        # setup our opengl requirements
        config = pyglet.gl.Config(
            depth_size = 16,
            double_buffer = True
            )

        # create our window
        self.window = pyglet.window.Window(
            fullscreen = False,
            width = 1024,
            height = 768,
            resizable = True,
            vsync = False,
            config = config
            )

        # create a viewport
        self.viewport = RatioViewport(
            self.window,
            [ [0.0, 0.0], [1.0, 1.0] ]
            )

        # create our input devices
        self.keyboard = Keyboard( self.window )
        self.mouse = Mouse( self.window )

        # setup our scene
        self.setup_scene()

        # setup our text
        self.setup_text()

        # listen for on_draw events
        self.window.push_handlers(
            on_draw = self.on_draw
            )
        
        # setup our update loop the app
        # we'll render at 60 fps
        frequency = 60.0
        self.update_delta = 1.0 / frequency

        # over-ride the frequency and render at full speed
        self.update_delta = -1

        # use a pyglet callback for our render loop
        pyglet.clock.schedule_interval(
            self.step,
            self.update_delta
            )

    def setup_scene( self ):
        # create an fps display
        self.fps_display = pyglet.clock.ClockDisplay()

        # create a list of renderables
        self.renderables = []

        # create a scene
        self.scene_node = SceneNode( 'root' )

        self.grid_node = SceneNode( 'grid' )
        self.scene_node.add_child( self.grid_node )

        self.grid_render_node = RenderCallbackNode(
            'mesh',
            grid.initialise_grid,
            grid.render_grid
            )
        self.grid_node.add_child( self.grid_render_node )

        # add to our list of renderables
        self.renderables.append( self.grid_render_node )

        # move the grid backward so we can see it
        # and move it down so we start above it
        self.grid_node.transform.inertial.translate(
            [ 0.0, 0.0, -80.0 ]
            )
        
        # create a camera and a view matrix
        self.view_matrix = ProjectionViewMatrix(
            self.viewport.aspect_ratio,
            fov = 45.0,
            near_clip = 1.0,
            far_clip = 200.0
            )
        # create a camera
        self.camera = CameraNode(
            'camera',
            self.view_matrix
            )
        self.scene_node.add_child( self.camera )

        # move the camera up so it starts above the grid
        self.camera.transform.inertial.translate(
            [ 0.0, 20.0, 0.0 ]
            )
        
        # assign a camera controller
        # we'll use the 6 degrees of freedom
        # camera for this one
        self.camera_controller = SixDOF_Controller(
            self.camera.transform
            )

    def setup_text( self ):
        self.help_label = pyglet.text.HTMLLabel(
"""
<b>6-DOF Camera demo</b>
<ul>
<li>Mouse: look around</li>
<li>W,A,S,D: move around</li>
<li>Space: move up</li>
<li>Shift: move down</li>
</ul>
""",
            multiline = True,
            x = 0,
            y = 50,
            width = 500,
            anchor_x = 'left',
            anchor_y = 'bottom',
            )
        self.help_label.color = (255,255,255,255)
        
    def run( self ):
        pyglet.app.run()
    
    def step( self, dt ):
        # update the Camera
        camera_speed = 40.0
        
        # handle input
        # this looks complex, but all we're doing
        # is checking for WASD / Arrows
        # and then sending forward, backward, etc
        # to the camera controller with an amount that
        # is scaled by the current time delta
        if self.keyboard[ self.keyboard.keys.W ] or self.keyboard[ self.keyboard.keys.UP ]:
            # move forward
            self.camera_controller.translate_forward( camera_speed * dt )
        if self.keyboard[ self.keyboard.keys.S ] or self.keyboard[ self.keyboard.keys.DOWN ]:
            # move backward
            self.camera_controller.translate_backward( camera_speed * dt )
        if self.keyboard[ self.keyboard.keys.D ] or self.keyboard[ self.keyboard.keys.RIGHT ]:
            # move right
            self.camera_controller.translate_right( camera_speed * dt )
        if self.keyboard[ self.keyboard.keys.A ] or self.keyboard[ self.keyboard.keys.LEFT ]:
            # move right
            self.camera_controller.translate_left( camera_speed * dt )
        if self.keyboard[ self.keyboard.keys.SPACE ]:
            # move up
            self.camera_controller.translate_up( camera_speed * dt )
        if self.keyboard[ self.keyboard.keys.LSHIFT ]:
            # move up
            self.camera_controller.translate_down( camera_speed * dt )
        
        # handle camera rotation
        # get the relative movement of the mouse
        # since the last frame
        mouse_relative = self.mouse.relative_position

        # the base movement speed we use for
        # scaling with the mouse movements
        # this value just feels about right
        mouse_speed = 0.006
        
        # scale the mouse movement by the relative value
        # DON'T multiply by the time delta here
        # think about it, it's not what you want!
        frame_pitch = math.pi * mouse_speed * mouse_relative[ 1 ]
        frame_yaw = -math.pi * mouse_speed * mouse_relative[ 0 ]
        
        # check for mouse inverts, for us freaks...
        # WE HAVE RIGHTS TOO!
        invert_y = True
        if invert_y == True:
            frame_pitch = -frame_pitch
        
        # pass the mouse movement to the camera controller
        self.camera_controller.orient( pitch = frame_pitch, yaw = frame_yaw )
        
        # reset our mouse relative position
        # we should do this each time we take a reading
        # or the delta will continue to accumulate
        self.mouse.clear_delta()

        # manually dispatch the on_draw event
        # as we patched it out of the idle loop
        self.window.dispatch_event( 'on_draw' )
        
        # display the frame buffer
        self.window.flip()

    def on_draw( self ):
        # render the scene
        self.render()

        # render our help text
        self.help_label.draw()

        # render the fps
        self.fps_display.draw()

    def render( self ):
        #
        # setup
        #

        # activate the window
        self.window.switch_to()

        # activate our viewport
        self.viewport.switch_to()

        # setup our viewport properties
        self.viewport.push_viewport_attributes()

        # update the view matrix aspect ratio
        self.camera.view_matrix.aspect_ratio = self.viewport.aspect_ratio

        # apply our view matrix and camera translation
        self.camera.view_matrix.push_view_matrix()
        self.camera.push_model_view()

        #
        # render
        #

        # clear our frame buffer and depth buffer
        pygly.gl.set_scissor( self.viewport.rect )
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )

        # render our grid
        for renderable in self.renderables:
            renderable.render()

        #
        # tear down
        #

        # pop our view matrix and camera translation
        self.camera.pop_model_view()
        self.camera.view_matrix.pop_view_matrix()

        # reset our gl state
        self.viewport.pop_viewport_attributes()

        #
        # reset state
        #

        # set our viewport to the entire window
        pygly.gl.set_scissor(
            pygly.window.create_rectangle( self.window )
            )
        pygly.gl.set_viewport(
            pygly.window.create_rectangle( self.window )
            )
Exemple #15
0
    def setup_scene(self):
        """Creates the scene to be rendered.
        Creates our camera, scene graph, 
        """
        # don't call 'SimpleApplication's setup_scene
        CoreApplication.setup_scene(self)

        # setup our GL state
        # enable z buffer
        glEnable(GL_DEPTH_TEST)

        # enable back face culling
        glEnable(GL_CULL_FACE)
        glCullFace(GL_BACK)

        # load our texture
        # use the PIL decoder as the pyglet one is broken
        # and loads most images as greyscale
        path = os.path.join(os.path.dirname(__file__),
                            '../../data/md2/sydney.bmp')
        image = Image.open(path)
        self.texture = Texture2D(GL_TEXTURE_2D)
        self.texture.bind()
        self.texture.set_min_mag_filter(min=GL_LINEAR, mag=GL_LINEAR)
        # load the image from PIL
        # MD2 textures are inverted
        pygly.pil_texture.set_pil_image(self.texture, image, flip=False)
        self.texture.unbind()

        # create a grid of cubes
        self.grid_root = SceneNode('grid_root')
        self.scene_node.add_child(self.grid_root)

        # create a number of cubes
        # the grid will extend from -5 to +5
        x, z = numpy.mgrid[-5:5:11j, -5:5:11j]
        x = x.flatten()
        z = z.flatten()

        positions = numpy.vstack((x, numpy.zeros(x.shape), z))
        positions = positions.T

        # set the distance between the models
        positions *= 4.5

        # store a list of renderables
        self.renderables = []

        path = os.path.join(os.path.dirname(__file__),
                            '../../data/md2/sydney.md2')

        for position in positions:
            node = RenderCallbackNode('node-%s' % position, None,
                                      self.render_node)
            node.mesh = MD2_Mesh(path)
            node.mesh.load()

            # attach to our scene graph
            self.grid_root.add_child(node)
            self.renderables.append(node)

            # move and scale the node
            node.transform.inertial.translation = position
            node.transform.scale = 0.2

        # create a range of animation times
        # 0.0 <= x < num_frames
        self.frames = numpy.linspace(0.0,
                                     float(
                                         self.renderables[0].mesh.num_frames),
                                     len(positions),
                                     endpoint=False)

        # create an array that will store our frame rates
        self.frame_rate = numpy.zeros(len(self.renderables), dtype=numpy.float)

        self.animation = ''
Exemple #16
0
class MD2_Application(SimpleApplication):
    def setup(self):
        super(MD2_Application, self).setup()

        self.setup_keyboard()

        print 'Press any key to move to the next animation'

    def setup_keyboard(self):
        self.window.push_handlers(on_key_release=self.on_key_release)

    def on_key_release(self, *args):
        self.increment_animation()

    def setup_viewports(self):
        super(MD2_Application, self).setup_viewports()

        self.colours[0] = (1.0, 1.0, 1.0, 1.0)

    def setup_camera(self):
        super(MD2_Application, self).setup_camera()

        # move the camera
        self.cameras[0].transform.inertial.translate([0.0, -3.0, 0.0])
        # tilt the camera downward
        self.cameras[0].transform.object.rotate_x(math.pi / 8.0)

    def setup_scene(self):
        """Creates the scene to be rendered.
        Creates our camera, scene graph, 
        """
        # don't call 'SimpleApplication's setup_scene
        CoreApplication.setup_scene(self)

        # setup our GL state
        # enable z buffer
        glEnable(GL_DEPTH_TEST)

        # enable back face culling
        glEnable(GL_CULL_FACE)
        glCullFace(GL_BACK)

        # load our texture
        # use the PIL decoder as the pyglet one is broken
        # and loads most images as greyscale
        path = os.path.join(os.path.dirname(__file__),
                            '../../data/md2/sydney.bmp')
        image = Image.open(path)
        self.texture = Texture2D(GL_TEXTURE_2D)
        self.texture.bind()
        self.texture.set_min_mag_filter(min=GL_LINEAR, mag=GL_LINEAR)
        # load the image from PIL
        # MD2 textures are inverted
        pygly.pil_texture.set_pil_image(self.texture, image, flip=False)
        self.texture.unbind()

        # create a grid of cubes
        self.grid_root = SceneNode('grid_root')
        self.scene_node.add_child(self.grid_root)

        # store a list of renderables
        path = os.path.join(os.path.dirname(__file__),
                            '../../data/md2/sydney.md2')

        self.mesh_node = RenderCallbackNode('mesh', None, self.render_node)
        # rotate the mesh to face the camera
        self.mesh_node.transform.object.rotate_y(math.pi)

        self.mesh_node.mesh = MD2_Mesh(path)
        self.mesh_node.mesh.load()

        # attach to our scene graph
        self.grid_root.add_child(self.mesh_node)

        # scale the node
        #self.mesh_node.transform.scale = 0.2

        # store current animation
        self.animation_number = 0
        self.set_animation(self.animation_number)

    def increment_animation(self):
        self.animation_number += 1
        if self.animation_number >= len(self.mesh_node.mesh.animations):
            self.animation_number = 0

        self.set_animation(self.animation_number)

    def set_animation(self, number):
        self.animation_number = number
        self.animation = pymesh.md2.MD2.animations.keys()[number]

        start, end = self.mesh_node.mesh.animation_start_end_frame(
            self.animation)
        num_frames = self.mesh_node.mesh.num_frames

        if start >= num_frames or end >= num_frames:
            print 'Animation "%s" not present' % self.animation
            return self.set_animation(0)

        self.mesh_node.mesh.frame_1 = start
        self.mesh_node.mesh.frame_2 = start + 1

        # some animations have only 1 frame
        if self.mesh_node.mesh.frame_2 > end:
            self.mesh_node.mesh.frame_2 = end

        print 'Animation:', self.animation

    def step(self, dt):
        """Updates our scene and triggers the on_draw event.
        This is scheduled in our __init__ method and
        called periodically by pyglet's event callbacks.
        We need to manually call 'on_draw' as we patched
        it our of pyglets event loop when we patched it
        out with pygly.monkey_patch.
        Because we called 'on_draw', we also need to
        perform the buffer flip at the end.
        """
        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.grid_root.transform.object.rotate_y(dt * 0.2)

        # update our frame rates
        frame_rate = self.mesh_node.mesh.frame_rate

        # increment our frame
        self.mesh_node.mesh.interpolation += dt * frame_rate

        # calculate the current and next frame
        # and the blending fraction
        fraction, whole = math.modf(self.mesh_node.mesh.interpolation)
        whole = int(whole)

        # check if we're moving to the next keyframe
        if whole > 0:
            # ensure fraction remains < 1.0
            self.mesh_node.mesh.interpolation = fraction

            # increment our frames
            self.mesh_node.mesh.frame_1 += whole
            self.mesh_node.mesh.frame_2 += whole

            # get the animation's start and end frame
            start, end = self.mesh_node.mesh.animation_start_end_frame(
                self.animation)

            num_frames = self.mesh_node.mesh.num_frames
            if start >= num_frames:
                start = num_frames
                end = num_frames
                print 'Animation has insufficient frames'
            elif end >= num_frames:
                end = num_frames
                print 'Animation has insufficient frames'

            # ensure we don't go outside the animation
            animation_size = (end - start) + 1
            if self.mesh_node.mesh.frame_1 > end:
                self.mesh_node.mesh.frame_1 -= animation_size

            if self.mesh_node.mesh.frame_2 > end:
                self.mesh_node.mesh.frame_2 -= animation_size

        # this will trigger the draw event and buffer flip
        CoreApplication.step(self, dt)

    def render_scene(self, camera):
        """Renders each renderable in the scene
        using the current projection and model
        view matrix.
        The original GL state will be restored
        upon leaving this function.
        """
        projection = camera.view_matrix.matrix
        model_view = camera.model_view

        # bind our diffuse texture
        glActiveTexture(GL_TEXTURE0)
        self.texture.bind()

        # update the model view
        world_matrix = self.mesh_node.world_transform.matrix
        current_mv = matrix44.multiply(world_matrix, model_view)

        # render a cube
        self.mesh_node.render(projection=projection, model_view=current_mv)

        glActiveTexture(GL_TEXTURE0)
        self.texture.unbind()

    def render_node(self, node, **kwargs):
        node.mesh.render(**kwargs)
Exemple #17
0
class Application(object):
    def __init__(self):
        super(Application, self).__init__()

        # setup our opengl requirements
        config = pyglet.gl.Config(depth_size=16, double_buffer=True)

        # create our window
        self.window = pyglet.window.Window(fullscreen=False,
                                           width=1024,
                                           height=768,
                                           resizable=True,
                                           vsync=False,
                                           config=config)

        # create a viewport
        self.viewport = RatioViewport(self.window, [[0.0, 0.0], [1.0, 1.0]])

        # create our input devices
        self.keyboard = Keyboard(self.window)
        self.mouse = Mouse(self.window)

        # setup our scene
        self.setup_scene()

        # setup our text
        self.setup_text()

        # listen for on_draw events
        self.window.push_handlers(on_draw=self.on_draw)

        # setup our update loop the app
        # we'll render at 60 fps
        frequency = 60.0
        self.update_delta = 1.0 / frequency

        # over-ride the frequency and render at full speed
        self.update_delta = -1

        # use a pyglet callback for our render loop
        pyglet.clock.schedule_interval(self.step, self.update_delta)

    def setup_scene(self):
        # create an fps display
        self.fps_display = pyglet.clock.ClockDisplay()

        # create a list of renderables
        self.renderables = []

        # create a scene
        self.scene_node = SceneNode('root')

        self.grid_node = SceneNode('grid')
        self.scene_node.add_child(self.grid_node)

        self.grid_render_node = RenderCallbackNode('mesh',
                                                   grid.initialise_grid,
                                                   grid.render_grid)
        self.grid_node.add_child(self.grid_render_node)

        # add to our list of renderables
        self.renderables.append(self.grid_render_node)

        # move the grid backward so we can see it
        # and move it down so we start above it
        self.grid_node.transform.inertial.translate([0.0, 0.0, -80.0])

        # create a camera and a view matrix
        self.view_matrix = ProjectionViewMatrix(self.viewport.aspect_ratio,
                                                fov=45.0,
                                                near_clip=1.0,
                                                far_clip=200.0)
        # create a camera
        self.camera = CameraNode('camera', self.view_matrix)
        self.scene_node.add_child(self.camera)

        # move the camera up so it starts above the grid
        self.camera.transform.inertial.translate([0.0, 20.0, 0.0])

        # assign a camera controller
        # we'll use the 6 degrees of freedom
        # camera for this one
        self.camera_controller = SixDOF_Controller(self.camera.transform)

    def setup_text(self):
        self.help_label = pyglet.text.HTMLLabel(
            """
<b>6-DOF Camera demo</b>
<ul>
<li>Mouse: look around</li>
<li>W,A,S,D: move around</li>
<li>Space: move up</li>
<li>Shift: move down</li>
</ul>
""",
            multiline=True,
            x=0,
            y=50,
            width=500,
            anchor_x='left',
            anchor_y='bottom',
        )
        self.help_label.color = (255, 255, 255, 255)

    def run(self):
        pyglet.app.run()

    def step(self, dt):
        # update the Camera
        camera_speed = 40.0

        # handle input
        # this looks complex, but all we're doing
        # is checking for WASD / Arrows
        # and then sending forward, backward, etc
        # to the camera controller with an amount that
        # is scaled by the current time delta
        if self.keyboard[self.keyboard.keys.W] or self.keyboard[
                self.keyboard.keys.UP]:
            # move forward
            self.camera_controller.translate_forward(camera_speed * dt)
        if self.keyboard[self.keyboard.keys.S] or self.keyboard[
                self.keyboard.keys.DOWN]:
            # move backward
            self.camera_controller.translate_backward(camera_speed * dt)
        if self.keyboard[self.keyboard.keys.D] or self.keyboard[
                self.keyboard.keys.RIGHT]:
            # move right
            self.camera_controller.translate_right(camera_speed * dt)
        if self.keyboard[self.keyboard.keys.A] or self.keyboard[
                self.keyboard.keys.LEFT]:
            # move right
            self.camera_controller.translate_left(camera_speed * dt)
        if self.keyboard[self.keyboard.keys.SPACE]:
            # move up
            self.camera_controller.translate_up(camera_speed * dt)
        if self.keyboard[self.keyboard.keys.LSHIFT]:
            # move up
            self.camera_controller.translate_down(camera_speed * dt)

        # handle camera rotation
        # get the relative movement of the mouse
        # since the last frame
        mouse_relative = self.mouse.relative_position

        # the base movement speed we use for
        # scaling with the mouse movements
        # this value just feels about right
        mouse_speed = 0.006

        # scale the mouse movement by the relative value
        # DON'T multiply by the time delta here
        # think about it, it's not what you want!
        frame_pitch = math.pi * mouse_speed * mouse_relative[1]
        frame_yaw = -math.pi * mouse_speed * mouse_relative[0]

        # check for mouse inverts, for us freaks...
        # WE HAVE RIGHTS TOO!
        invert_y = True
        if invert_y == True:
            frame_pitch = -frame_pitch

        # pass the mouse movement to the camera controller
        self.camera_controller.orient(pitch=frame_pitch, yaw=frame_yaw)

        # reset our mouse relative position
        # we should do this each time we take a reading
        # or the delta will continue to accumulate
        self.mouse.clear_delta()

        # manually dispatch the on_draw event
        # as we patched it out of the idle loop
        self.window.dispatch_event('on_draw')

        # display the frame buffer
        self.window.flip()

    def on_draw(self):
        # render the scene
        self.render()

        # render our help text
        self.help_label.draw()

        # render the fps
        self.fps_display.draw()

    def render(self):
        #
        # setup
        #

        # activate the window
        self.window.switch_to()

        # activate our viewport
        self.viewport.switch_to()

        # setup our viewport properties
        self.viewport.push_viewport_attributes()

        # update the view matrix aspect ratio
        self.camera.view_matrix.aspect_ratio = self.viewport.aspect_ratio

        # apply our view matrix and camera translation
        self.camera.view_matrix.push_view_matrix()
        self.camera.push_model_view()

        #
        # render
        #

        # clear our frame buffer and depth buffer
        pygly.gl.set_scissor(self.viewport.rect)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        # render our grid
        for renderable in self.renderables:
            renderable.render()

        #
        # tear down
        #

        # pop our view matrix and camera translation
        self.camera.pop_model_view()
        self.camera.view_matrix.pop_view_matrix()

        # reset our gl state
        self.viewport.pop_viewport_attributes()

        #
        # reset state
        #

        # set our viewport to the entire window
        pygly.gl.set_scissor(pygly.window.create_rectangle(self.window))
        pygly.gl.set_viewport(pygly.window.create_rectangle(self.window))
    def test_rotation( self ):
        """
        Rotation and Inheritance
        """

        # we'll add a child to a root node
        # we'll move the child
        # rotate the root
        # and check the child is where it should be
        # the child should be moved somewhere that will
        # make it easy to check

        root = SceneNode( '/root' )
        child = SceneNode( '/child' )
        
        root.add_child( child )

        #
        # Rotate 180 deg (1 * pi) about the Y axis (yaw)
        #
        root.transform.object.rotate_y( math.pi )

        identity = matrix44.identity()
        root_matrix = matrix44.create_from_y_rotation( math.pi )

        # root object
        test_axis( self, root.transform.object, root_matrix )
        test_axis( self, root.transform.inertial, identity )
        test_axis( self, root.world_transform.object, root_matrix )
        test_axis( self, root.world_transform.inertial, identity )

        child_matrix = matrix44.identity()
        test_axis( self, child.transform.object, child_matrix )
        test_axis( self, child.transform.inertial, identity )
        test_axis( self, child.world_transform.object, root_matrix )
        test_axis( self, child.world_transform.inertial, identity )


        # check the node matrix matches what we're seeing in
        # the transform axis values
        self.assertTrue(
            numpy.allclose( root.transform.matrix, root_matrix ),
            "Root Local Matrix incorrect"
            )
        self.assertTrue(
            numpy.allclose( root.world_transform.matrix, root_matrix ),
            "Root RootMatrix incorrect"
            )

        self.assertTrue(
            numpy.allclose( child.transform.matrix, identity ),
            "Child Local Matrix incorrect"
            )
        self.assertTrue(
            numpy.allclose( child.world_transform.matrix, root_matrix ),
            "Child RootMatrix incorrect"
            )


        #
        # Rotate 180 deg (1 * pi) about the X axis (pitch)
        #
        # rotate 180 deg / 1pi about the x axis (pitch)
        child.transform.object.rotate_x( math.pi )

        child_matrix = matrix44.multiply(
            matrix44.create_from_x_rotation( math.pi ),
            child_matrix
            )

        child_world = matrix44.multiply( child_matrix, root_matrix )

        # root object
        test_axis( self, root.transform.object, root_matrix )
        test_axis( self, root.transform.inertial, identity )
        test_axis( self, root.world_transform.object, root_matrix )
        test_axis( self, root.world_transform.inertial, identity )

        test_axis( self, child.transform.object, child_matrix )
        test_axis( self, child.transform.inertial, identity )
        test_axis( self, child.world_transform.object, child_world )
        test_axis( self, child.world_transform.inertial, identity )

        # check the node matrix matches what we're seeing in
        # the transform axis values
        self.assertTrue(
            numpy.allclose( root.transform.matrix, root_matrix ),
            "Root Local Matrix incorrect"
            )
        self.assertTrue(
            numpy.allclose( root.world_transform.matrix, root_matrix ),
            "Root RootMatrix incorrect"
            )

        self.assertTrue(
            numpy.allclose( child.transform.matrix, child_matrix ),
            "Child Local Matrix incorrect"
            )
        self.assertTrue(
            numpy.allclose( child.world_transform.matrix, child_world ),
            "Child RootMatrix incorrect"
            )
Exemple #19
0
class MD2_Application( SimpleApplication ):

    def setup_viewports( self ):
        super( MD2_Application, self ).setup_viewports()

        self.colours[ 0 ] = (1.0,1.0,1.0,1.0)

    def setup_scene( self ):
        """Creates the scene to be rendered.
        Creates our camera, scene graph, 
        """
        # don't call 'SimpleApplication's setup_scene
        CoreApplication.setup_scene( self )

        # setup our GL state
        # enable z buffer
        glEnable( GL_DEPTH_TEST )

        # enable back face culling
        glEnable( GL_CULL_FACE )
        glCullFace( GL_BACK )

        # load our texture
        # use the PIL decoder as the pyglet one is broken
        # and loads most images as greyscale
        path = os.path.join(
            os.path.dirname( __file__ ),
            '../../data/md2/sydney.bmp'
            )
        image = Image.open( path )
        self.texture = Texture2D( GL_TEXTURE_2D )
        self.texture.bind()
        self.texture.set_min_mag_filter(
            min = GL_LINEAR,
            mag = GL_LINEAR
            )
        # load the image from PIL
        # MD2 textures are inverted
        pygly.pil_texture.set_pil_image( self.texture, image, flip = False )
        self.texture.unbind()

        # create a grid of cubes
        self.grid_root = SceneNode( 'grid_root' )
        self.scene_node.add_child( self.grid_root )

        # create a number of cubes
        # the grid will extend from -5 to +5
        x,z = numpy.mgrid[
            -5:5:11j,
            -5:5:11j
            ]
        x = x.flatten()
        z = z.flatten()

        positions = numpy.vstack(
            (x, numpy.zeros( x.shape ), z )
            )
        positions = positions.T

        # set the distance between the models
        positions *= 4.5

        # store a list of renderables
        self.renderables = []

        path = os.path.join(
            os.path.dirname( __file__ ),
            '../../data/md2/sydney.md2'
            )

        for position in positions:
            node = RenderCallbackNode(
                'node-%s' % position,
                None,
                self.render_node
                )
            node.mesh = MD2_Mesh( path )
            node.mesh.load()

            # attach to our scene graph
            self.grid_root.add_child( node )
            self.renderables.append( node )

            # move and scale the node
            node.transform.inertial.translation = position
            node.transform.scale = 0.2

        # create a range of animation times
        # 0.0 <= x < num_frames
        self.frames = numpy.linspace(
            0.0,
            float(self.renderables[ 0 ].mesh.num_frames),
            len(positions),
            endpoint = False
            )

        # create an array that will store our frame rates
        self.frame_rate = numpy.zeros( len(self.renderables), dtype = numpy.float )

        self.animation = ''

    def step( self, dt ):
        """Updates our scene and triggers the on_draw event.
        This is scheduled in our __init__ method and
        called periodically by pyglet's event callbacks.
        We need to manually call 'on_draw' as we patched
        it our of pyglets event loop when we patched it
        out with pygly.monkey_patch.
        Because we called 'on_draw', we also need to
        perform the buffer flip at the end.
        """
        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.grid_root.transform.object.rotate_y( dt * 0.2 )

        # update our frame rates
        self.frame_rate[:] = [ mesh_node.mesh.frame_rate for mesh_node in self.renderables ]


        # increment our frame
        #self.frames += dt * fps
        self.frames += dt * self.frame_rate
        numpy.mod(
            self.frames,
            self.renderables[ 0 ].mesh.num_frames,
            self.frames
            )

        # print the animation name of the first mesh
        curr_anim = self.renderables[ 0 ].mesh.animation
        if self.animation != curr_anim:
            self.animation = curr_anim
            print 'Curren animation:', self.animation

        # this will trigger the draw event and buffer flip
        CoreApplication.step( self, dt )

    def render_scene( self, camera ):
        """Renders each renderable in the scene
        using the current projection and model
        view matrix.
        The original GL state will be restored
        upon leaving this function.
        """
        projection = camera.view_matrix.matrix
        model_view = camera.model_view

        # bind our diffuse texture
        glActiveTexture( GL_TEXTURE0 )
        self.texture.bind()

        # iterate through our renderables
        for node, frame in zip(self.renderables, self.frames):
            # update the model view
            world_matrix = node.world_transform.matrix
            current_mv = matrix44.multiply(
                world_matrix,
                model_view
                )

            fraction, frame1 = math.modf( frame )
            frame2 = (frame1 + 1.0) % node.mesh.num_frames

            # update the frame
            node.mesh.frame_1 = int(frame1)
            node.mesh.frame_2 = int(frame2)
            node.mesh.interpolation = fraction

            # render a cube
            node.render(
                projection = projection,
                model_view = current_mv
                )

        glActiveTexture( GL_TEXTURE0 )
        self.texture.unbind()

    def render_node( self, node, **kwargs ):
        node.mesh.render( **kwargs )
class Scene( scene_scene_graph.Scene ):

    def __init__( self, core_profile = True ):
        super( Scene, self ).__init__( core_profile )

    def initialise( self ):
        super( Scene, self ).initialise()

        def set_gl_state():
            # setup our GL state
            # enable scissoring for viewports
            GL.glEnable( GL.GL_SCISSOR_TEST )

        set_gl_state()

        self.viewport2 = None

        def setup_camera():
            # add another node that our camera will be under
            # we can rotate this node to show how the cameras work
            self.camera2_parent = SceneNode( 'camera2_parent' )
            self.scene_root.add_child( self.camera2_parent )

            # create our camera node
            self.camera2 = CameraNode( 'camera2', pyrr.matrix44.create_identity() )
            self.camera2_parent.add_child( self.camera2 )

            # place the camera at the same position as the previous one
            #self.camera2.transform.translation = self.camera.transform.translation
            #self.camera2.transform.orientation = self.camera.transform.orientation
            #self.camera2.transform.scale = self.camera.transform.scale

            self.camera2.transform.object.translate(
                [ 0.0, 0.0, 35.0 ]
                )

        setup_camera()

    def on_window_resized( self, width, height ):
        #super( Scene, self ).on_window_resized( width, height )

        def update_viewports():
            half_width = width / 2.0

            # update the viewport
            self.viewport = pyrr.rectangle.create_from_position(
                x = 0,
                y = 0,
                width = half_width,
                height = height
                )

            self.viewport2 = pyrr.rectangle.create_from_position(
                x = half_width,
                y = 0,
                width = half_width,
                height = height
                )

            print self.viewport, self.viewport2

        def update_cameras():
            # update the projection matrix
            # we need to do this or the rendering will become skewed with each
            # resize of viewport change
            aspect_ratio = pyrr.rectangle.aspect_ratio( self.viewport )
            self.camera.projection_matrix = pyrr.matrix44.create_perspective_projection_matrix(
                fovy = 80.0,
                aspect = aspect_ratio,
                near = 1.0,
                far = 100.0
                )

            # update the projection matrix
            # we need to do this or the rendering will become skewed with each
            # resize of viewport change
            aspect_ratio = pyrr.rectangle.aspect_ratio( self.viewport2 )
            self.camera2.projection_matrix = pyrr.matrix44.create_perspective_projection_matrix(
                fovy = 80.0,
                aspect = aspect_ratio,
                near = 1.0,
                far = 100.0
                )

        update_viewports()
        update_cameras()

    def step( self, dt ):
        super( Scene, self ).step( dt )

        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.camera2_parent.transform.object.rotate_x( dt )

    def render( self ):
        # render viewport 1
        super( Scene, self ).render()

        # change our clear colour to make it clear where the viewport is
        GL.glClearColor( 1.0, 1.0, 1.0, 1.0 )

        # render the viewport
        self.render_viewport( self.viewport2, self.camera2 )
 def setup_scene():
     # create a scene
     # we'll create the scene as a tree
     # to demonstrate the depth-first iteration
     # technique we will use to render it
     self.scene_root = SceneNode( 'root' )
Exemple #22
0
        def setup_scene():
            # create a scene
            # we'll create the scene as a tree
            # to demonstrate the depth-first iteration
            # technique we will use to render it
            self.scene_root = SceneNode('root')

            # the letter indicates the tier the node
            # is on, a = tier 1, b = tier 2, etc.
            self.a1 = SceneNode('a1')
            self.b1 = SceneNode('b1')
            self.b2 = SceneNode('b2')
            self.c1 = SceneNode('c1')
            self.c2 = SceneNode('c2')
            self.c3 = SceneNode('c3')

            # the tree looks as follows
            #                / c1
            #           / b1 - c2
            # root - a1
            #           \ b2 - c3
            self.scene_root.add_child(self.a1)
            self.a1.add_child(self.b1)
            self.a1.add_child(self.b2)
            self.b1.add_child(self.c1)
            self.b1.add_child(self.c2)
            self.b2.add_child(self.c3)

            # if we set the nodes local scale (transform)
            # it will be affected by the parent's scale.
            # by setting the world scale (world_transform)
            # we are ignoring the parent's scale.
            # re-attaching the node would invalidate this.
            self.a1.world_transform.scale = [2.0, 2.0, 2.0]
            self.b1.world_transform.scale = [1.0, 1.0, 1.0]
            self.b2.world_transform.scale = [1.0, 1.0, 1.0]
            self.c1.world_transform.scale = [0.8, 0.8, 0.8]
            self.c2.world_transform.scale = [0.8, 0.8, 0.8]
            self.c3.world_transform.scale = [0.8, 0.8, 0.8]

            # move our scene nodes
            # leave a1 at the centre
            self.b1.transform.object.translate([10.0, 0.0, 0.0])
            self.b2.transform.object.translate([-10.0, 0.0, 0.0])
            self.c1.transform.object.translate([5.0, 0.0, 0.0])
            self.c2.transform.object.translate([-5.0, 0.0, 0.0])
            self.c3.transform.object.translate([5.0, 0.0, 0.0])

            # rotate the our b nodes so they tilting forward
            self.b1.transform.object.rotate_x(math.pi / 4.0)
            self.b2.transform.object.rotate_x(math.pi / 4.0)
class Scene( scene.Scene ):

    def __init__( self, core_profile = True ):
        super( Scene, self ).__init__( core_profile )

    @property
    def name( self ):
        return "Basic"

    def initialise( self ):
        super( Scene, self ).initialise()

        def set_gl_state():
            # setup our GL state
            # disable z buffer
            # because we're rendering transparent cubes
            GL.glDisable( GL.GL_DEPTH_TEST )

            # enable back face culling
            GL.glEnable( GL.GL_CULL_FACE )
            GL.glCullFace( GL.GL_BACK )

            # enable alpha testing
            GL.glEnable( GL.GL_BLEND )
            GL.glBlendFunc( GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA )

        set_gl_state()

        # create a viewport
        # this will be updated before we begin
        self.viewport = None

        # create a cube to render
        self.cube = renderable_colour_cube.create( self.core_profile )

        def setup_scene():
            # create a scene
            # we'll create the scene as a tree
            # to demonstrate the depth-first iteration
            # technique we will use to render it
            self.scene_root = SceneNode( 'root' )

        setup_scene()

        def setup_camera():
            # create our camera node
            self.camera = CameraNode( 'camera', pyrr.matrix44.create_identity() )
            self.scene_root.add_child( self.camera )

            # move the camera so we're not inside
            # the root scene node's debug cube
            self.camera.transform.object.translate(
                [ 0.0, 30.0, 35.0 ]
                )

            # tilt the camera downward
            self.camera.transform.object.rotate_x(-math.pi / 4.0 )

        setup_camera()

        def create_cubes():
            # create a grid of cubes
            self.grid_root = SceneNode( 'grid_root' )
            self.scene_root.add_child( self.grid_root )
            self.grid_root.transform.scale = [2.0, 2.0, 2.0]

            # create a number of cubes
            # the grid will extend from -5 to +5
            x,z = numpy.mgrid[
                -5:5:11j,
                -5:5:11j
                ]
            x = x.flatten()
            z = z.flatten()

            positions = numpy.vstack(
                (x, numpy.zeros( x.shape ), z )
                )
            positions = positions.T

            # set the distance of the cubes
            # cube is -1 -> 1
            # so distance is 2
            positions *= 2.5

            # store a list of renderables
            self.renderables = []

            for position in positions:
                node = SceneNode( 'node-%s' % position )
                node.transform.inertial.translation = position
                self.grid_root.add_child( node )
                self.renderables.append( node )

            # create a range of colours from 0.1 -> 0.5
            self.cube_colours = numpy.linspace( 0.1, 0.5, len(positions) )
            # make them consistent for RGBA
            self.cube_colours = self.cube_colours.repeat( 4 )
            self.cube_colours.shape = (-1, 4)
            # replace the Blue and Alpha value
            self.cube_colours[:,2] = 0.5
            self.cube_colours[:,3] = 0.5

        create_cubes()

    def on_window_resized( self, width, height ):
        # update the viewport
        self.viewport = pyrr.rectangle.create_from_position(
            x = 0,
            y = 0,
            width = width,
            height = height
            )

        # update the projection matrix
        # we need to do this or the rendering will become skewed with each
        # resize of viewport change
        aspect_ratio = pyrr.rectangle.aspect_ratio( self.viewport )
        self.camera.projection_matrix = pyrr.matrix44.create_perspective_projection_matrix(
            fovy = 80.0,
            aspect = aspect_ratio,
            near = 1.0,
            far = 100.0
            )

    def step( self, dt ):
        super( Scene, self ).step( dt )

        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.grid_root.transform.object.rotate_y( dt * 0.2 )

    def render( self ):
        super( Scene, self ).render()

        # sort our scene
        # extract the positions of all our renderables
        positions = [
            node.world_transform.translation for node in self.renderables
            ]

        # sort our renderables based on their position
        # from the camera
        # sort based on the -Z axis (the direction the
        # camera faces)
        sorted = pygly.sort.sort_radius_back_to_front(
            self.camera.world_transform.translation,
            -(self.camera.transform.object.z),
            self.renderables,
            positions
            )

        def render_core():
            # activate our viewport
            pygly.viewport.set_viewport( self.viewport )

            projection = self.camera.projection_matrix
            model_view = self.camera.model_view

            for node, colour in zip(sorted, self.cube_colours):
                # get the node's world matrix
                world_matrix = node.world_transform.matrix

                # apply the camera's model view to the node's matrix
                current_mv = pyrr.matrix44.multiply(
                    world_matrix,
                    model_view
                    )

                # render a cube
                self.cube.draw( projection, current_mv, colour )

        def render_legacy():
            # activate our viewport
            pygly.viewport.set_viewport( self.viewport )

            # load our projection matrix
            with pygly.gl.mode_and_matrix(
                GL.GL_PROJECTION,
                self.camera.projection_matrix
                ):
                with pygly.gl.mode_and_matrix(
                    GL.GL_MODELVIEW,
                    self.camera.model_view
                    ):
                    # iterate through the scene graph
                    for node, colour in zip(sorted, self.cube_colours):
                        world_matrix = node.world_transform.matrix

                        # multiply the existing model view matrix
                        # by the model's world matrix
                        # then render a cube
                        with pygly.gl.multiply_matrix( world_matrix ):
                            self.cube.draw( colour )

        # render the scene
        if self.core_profile:
            render_core()
        else:
            render_legacy()
Exemple #24
0
 def setup_scene():
     # create a scene
     # we'll create the scene as a tree
     # to demonstrate the depth-first iteration
     # technique we will use to render it
     self.scene_root = SceneNode( 'root' )
Exemple #25
0
class Scene( scene.Scene ):

    def __init__( self, core_profile = True ):
        super( Scene, self ).__init__( core_profile )

    @property
    def name( self ):
        return "Basic"

    def initialise( self ):
        super( Scene, self ).initialise()

        def set_gl_state():
            # setup our GL state
            # disable z buffer
            # because we're rendering transparent cubes
            GL.glDisable( GL.GL_DEPTH_TEST )

            # enable back face culling
            GL.glEnable( GL.GL_CULL_FACE )
            GL.glCullFace( GL.GL_BACK )

            # enable alpha testing
            GL.glEnable( GL.GL_BLEND )
            GL.glBlendFunc( GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA )

        set_gl_state()

        # create a viewport
        # this will be updated before we begin
        self.viewport = None

        # create a cube to render
        self.cube = renderable_colour_cube.create( self.core_profile )

        def setup_scene():
            # create a scene
            # we'll create the scene as a tree
            # to demonstrate the depth-first iteration
            # technique we will use to render it
            self.scene_root = SceneNode( 'root' )

        setup_scene()

        def setup_camera():
            # create our camera node
            self.camera = CameraNode( 'camera', pyrr.matrix44.create_identity() )
            self.scene_root.add_child( self.camera )

            # move the camera so we're not inside
            # the root scene node's debug cube
            self.camera.transform.object.translate(
                [ 0.0, 30.0, 35.0 ]
                )

            # tilt the camera downward
            self.camera.transform.object.rotate_x(-math.pi / 4.0 )

        setup_camera()

        def create_cubes():
            # create a grid of cubes
            self.grid_root = SceneNode( 'grid_root' )
            self.scene_root.add_child( self.grid_root )
            self.grid_root.transform.scale = [2.0, 2.0, 2.0]

            # create a number of cubes
            # the grid will extend from -5 to +5
            x,z = numpy.mgrid[
                -5:5:11j,
                -5:5:11j
                ]
            x = x.flatten()
            z = z.flatten()

            positions = numpy.vstack(
                (x, numpy.zeros( x.shape ), z )
                )
            positions = positions.T

            # set the distance of the cubes
            # cube is -1 -> 1
            # so distance is 2
            positions *= 2.5

            # store a list of renderables
            self.renderables = []

            for position in positions:
                node = SceneNode( 'node-%s' % position )
                node.transform.inertial.translation = position
                self.grid_root.add_child( node )
                self.renderables.append( node )

            # create a range of colours from 0.1 -> 0.5
            self.cube_colours = numpy.linspace( 0.1, 0.5, len(positions) )
            # make them consistent for RGBA
            self.cube_colours = self.cube_colours.repeat( 4 )
            self.cube_colours.shape = (-1, 4)
            # replace the Blue and Alpha value
            self.cube_colours[:,2] = 0.5
            self.cube_colours[:,3] = 0.5

        create_cubes()

    def on_window_resized( self, width, height ):
        # update the viewport
        self.viewport = pyrr.rectangle.create_from_position(
            x = 0,
            y = 0,
            width = width,
            height = height
            )

        # update the projection matrix
        # we need to do this or the rendering will become skewed with each
        # resize of viewport change
        aspect_ratio = pyrr.rectangle.aspect_ratio( self.viewport )
        self.camera.projection_matrix = pyrr.matrix44.create_perspective_projection_matrix(
            fovy = 80.0,
            aspect = aspect_ratio,
            near = 1.0,
            far = 100.0
            )

    def step( self, dt ):
        super( Scene, self ).step( dt )

        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.grid_root.transform.object.rotate_y( dt * 0.2 )

    def render( self ):
        super( Scene, self ).render()

        # sort our scene
        # extract the positions of all our renderables
        positions = [
            node.world_transform.translation for node in self.renderables
            ]

        # sort our renderables based on their position
        # from the camera
        # sort based on the -Z axis (the direction the
        # camera faces)
        sorted = pygly.sort.sort_radius_back_to_front(
            self.camera.world_transform.translation,
            -(self.camera.transform.object.z),
            self.renderables,
            positions
            )

        def render_core():
            # activate our viewport
            pygly.viewport.set_viewport( self.viewport )

            projection = self.camera.projection_matrix
            model_view = self.camera.model_view

            for node, colour in zip(sorted, self.cube_colours):
                # get the node's world matrix
                world_matrix = node.world_transform.matrix

                # apply the camera's model view to the node's matrix
                current_mv = pyrr.matrix44.multiply(
                    world_matrix,
                    model_view
                    )

                # render a cube
                self.cube.draw( projection, current_mv, colour )

        def render_legacy():
            # activate our viewport
            pygly.viewport.set_viewport( self.viewport )

            # load our projection matrix
            with pygly.gl.mode_and_matrix(
                GL.GL_PROJECTION,
                self.camera.projection_matrix
                ):
                with pygly.gl.mode_and_matrix(
                    GL.GL_MODELVIEW,
                    self.camera.model_view
                    ):
                    # iterate through the scene graph
                    for node, colour in zip(sorted, self.cube_colours):
                        world_matrix = node.world_transform.matrix

                        # multiply the existing model view matrix
                        # by the model's world matrix
                        # then render a cube
                        with pygly.gl.multiply_matrix( world_matrix ):
                            self.cube.draw( colour )

        # render the scene
        if self.core_profile:
            render_core()
        else:
            render_legacy()
Exemple #26
0
class MD5_Application( SimpleApplication ):

    def setup( self ):
        super( MD5_Application, self ).setup()

        self.setup_keyboard()

        print 'Press any key to move to the next animation'

    def setup_keyboard( self ):
        self.window.push_handlers(
            on_key_release = self.on_key_release
            )

    def on_key_release( self, *args ):
        self.increment_animation()

    def setup_viewports( self ):
        super( MD5_Application, self ).setup_viewports()

        self.colours[ 0 ] = (0.5,0.5,0.5,1.0)

    def setup_cameras( self ):
        super( MD5_Application, self ).setup_cameras()

        # move the camera
        self.cameras[ 0 ].transform.inertial.translate(
            #[ 0.0, 70.0, 100.0 ]
            [ 0.0,-3.0, 10.0 ]
            )
        # tilt the camera downward
        self.cameras[ 0 ].transform.object.rotate_x( math.pi / 8.0 )

    def setup_scene( self ):
        """Creates the scene to be rendered.
        Creates our camera, scene graph, 
        """
        # don't call 'SimpleApplication's setup_scene
        CoreApplication.setup_scene( self )

        # setup our GL state
        # enable z buffer
        glEnable( GL_DEPTH_TEST )

        # enable back face culling
        #glEnable( GL_CULL_FACE )
        glDisable( GL_CULL_FACE )
        #glCullFace( GL_BACK )

        # create a grid of cubes
        self.grid_root = SceneNode( 'grid_root' )
        self.scene_node.add_child( self.grid_root )

        self.mesh_node = RenderCallbackNode(
            'mesh',
            None,
            self.render_node
            )
        # rotate the mesh to face the camera
        self.mesh_node.transform.object.rotate_x( -math.pi * 0.5 )

        # store a list of renderables
        mesh_path = os.path.join(
            os.path.dirname( __file__ ),
            '../data/md5/boblampclean.md5mesh'
            #'../data/md5/md5/cyberdemon/cyberdemon.md5mesh'
            )

        anim_path = os.path.join(
            os.path.dirname( __file__ ),
            '../data/md5/boblampclean.md5anim'
            #'../data/md5/md5/cyberdemon/idle.md5anim'
            )

        # load our md5 data
        self.md5mesh = MD5_Mesh()
        self.md5mesh.load( mesh_path )

        self.md5anim = MD5_Anim()
        self.md5anim.load( anim_path )

        # load the gl mesh
        self.mesh_node.mesh = Mesh( self.md5mesh )

        # load our bindpose
        self.mesh_node.baseframe = BaseFrameSkeleton( self.md5mesh )

        # load some test skeletons
        self.mesh_node.anim = Animation( self.md5anim )

        # set to base frame
        self.mesh_node.mesh.set_skeleton( self.mesh_node.baseframe )

        # load a skeleton renderer
        self.mesh_node.skeleton = SkeletonRenderer()
        #self.mesh_node.skeleton.set_skeleton( self.mesh_node.baseframe )
        self.mesh_node.skeleton.set_skeleton( self.mesh_node.anim.skeleton( 0 ) )

        # create a list of frames
        self.frames = [
            skeleton
            for skeleton in self.mesh_node.anim
            ]
        #self.frames = []
        self.frames.append( self.mesh_node.baseframe )

        self.frame = 0
        self.time_accumulator = 0.0
        self.time_per_frame = 1.0 / self.mesh_node.anim.frame_rate


        # attach to our scene graph
        self.grid_root.add_child( self.mesh_node )

        # scale the node
        self.mesh_node.transform.scale = 0.5

    def step( self, dt ):
        """Updates our scene and triggers the on_draw event.
        This is scheduled in our __init__ method and
        called periodically by pyglet's event callbacks.
        We need to manually call 'on_draw' as we patched
        it our of pyglets event loop when we patched it
        out with pygly.monkey_patch.
        Because we called 'on_draw', we also need to
        perform the buffer flip at the end.
        """
        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.grid_root.transform.object.rotate_y( dt * 0.2 )

        # this will trigger the draw event and buffer flip
        CoreApplication.step( self, dt )

        if self.time_accumulator == 0.0:
            self.mesh_node.mesh.set_skeleton( self.frames[ self.frame ] )
            self.mesh_node.skeleton.set_skeleton( self.frames[ self.frame ] )

        self.time_accumulator += dt
        if self.time_accumulator > self.time_per_frame:
            self.time_accumulator = 0.0

            self.frame += 1
            self.frame %= len( self.frames )


    def render_scene( self, camera ):
        """Renders each renderable in the scene
        using the current projection and model
        view matrix.
        The original GL state will be restored
        upon leaving this function.
        """
        projection = camera.view_matrix.matrix
        model_view = camera.model_view

        # update the model view
        world_matrix = self.mesh_node.world_transform.matrix
        current_mv = matrix44.multiply(
            world_matrix,
            model_view
            )

        # render a cube
        self.mesh_node.render(
            projection = projection,
            model_view = current_mv
            )

    def render_node( self, node, **kwargs ):
        node.mesh.render( **kwargs )
        node.skeleton.render( **kwargs )
class Scene( scene.Scene ):

    def __init__( self, core_profile = True ):
        super( Scene, self ).__init__( core_profile )

    @property
    def name( self ):
        return "Basic"

    def initialise( self ):
        super( Scene, self ).initialise()

        def set_gl_state():
            # setup our GL state
            # enable z buffer
            GL.glEnable( GL.GL_DEPTH_TEST )

            # enable back face culling
            GL.glEnable( GL.GL_CULL_FACE )
            GL.glCullFace( GL.GL_BACK )

        set_gl_state()

        # create a viewport
        # this will be updated before we begin
        self.viewport = None

        # create a cube to render
        self.cube = renderable_cube.create( self.core_profile )

        def setup_scene():
            # create a scene
            # we'll create the scene as a tree
            # to demonstrate the depth-first iteration
            # technique we will use to render it
            self.scene_root = SceneNode( 'root' )

            # the letter indicates the tier the node
            # is on, a = tier 1, b = tier 2, etc.
            self.a1 = SceneNode( 'a1' )
            self.b1 = SceneNode( 'b1' )
            self.b2 = SceneNode( 'b2' )
            self.c1 = SceneNode( 'c1' )
            self.c2 = SceneNode( 'c2' )
            self.c3 = SceneNode( 'c3' )

            # the tree looks as follows
            #                / c1
            #           / b1 - c2
            # root - a1
            #           \ b2 - c3
            self.scene_root.add_child( self.a1 )
            self.a1.add_child( self.b1 )
            self.a1.add_child( self.b2 )
            self.b1.add_child( self.c1 )
            self.b1.add_child( self.c2 )
            self.b2.add_child( self.c3 )

            # if we set the nodes local scale (transform)
            # it will be affected by the parent's scale.
            # by setting the world scale (world_transform)
            # we are ignoring the parent's scale.
            # re-attaching the node would invalidate this.
            self.a1.world_transform.scale = [2.0, 2.0, 2.0]
            self.b1.world_transform.scale = [1.0, 1.0, 1.0]
            self.b2.world_transform.scale = [1.0, 1.0, 1.0]
            self.c1.world_transform.scale = [0.8, 0.8, 0.8]
            self.c2.world_transform.scale = [0.8, 0.8, 0.8]
            self.c3.world_transform.scale = [0.8, 0.8, 0.8]

            # move our scene nodes
            # leave a1 at the centre
            self.b1.transform.object.translate( [10.0, 0.0, 0.0 ] )
            self.b2.transform.object.translate([-10.0, 0.0, 0.0 ] )
            self.c1.transform.object.translate( [ 5.0, 0.0, 0.0 ] )
            self.c2.transform.object.translate( [-5.0, 0.0, 0.0 ] )
            self.c3.transform.object.translate( [ 5.0, 0.0, 0.0 ] )

            # rotate the our b nodes so they tilting forward
            self.b1.transform.object.rotate_x( math.pi / 4.0 )
            self.b2.transform.object.rotate_x( math.pi / 4.0 )

        setup_scene()

        def setup_camera():
            # create our camera node
            self.camera = CameraNode( 'camera', pyrr.matrix44.create_identity() )
            self.scene_root.add_child( self.camera )

            # move the camera so we're not inside
            # the root scene node's debug cube
            self.camera.transform.object.translate(
                [ 0.0, 30.0, 35.0 ]
                )

            # tilt the camera downward
            self.camera.transform.object.rotate_x(-math.pi / 4.0 )

        setup_camera()

    def on_window_resized( self, width, height ):
        # update the viewport
        self.viewport = pyrr.rectangle.create_from_position(
            x = 0,
            y = 0,
            width = width,
            height = height
            )

        # update the projection matrix
        # we need to do this or the rendering will become skewed with each
        # resize of viewport change
        aspect_ratio = pyrr.rectangle.aspect_ratio( self.viewport )
        self.camera.projection_matrix = pyrr.matrix44.create_perspective_projection_matrix(
            fovy = 80.0,
            aspect = aspect_ratio,
            near = 1.0,
            far = 100.0
            )

    def step( self, dt ):
        super( Scene, self ).step( dt )

        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.a1.transform.object.rotate_y( dt )
        self.b1.transform.object.rotate_y( dt )
        self.b2.transform.object.rotate_y( dt )
        self.c1.transform.object.rotate_y( dt )
        self.c2.transform.object.rotate_y( dt )
        self.c3.transform.object.rotate_y( dt )

    def render( self ):
        super( Scene, self ).render()

        # this code is split into 2 functions to support the
        # multiple_viewports scene which inherits from this class
        self.render_viewport( self.viewport, self.camera )

    def render_viewport( self, viewport, camera ):
        def render_core():
            projection = camera.projection_matrix
            model_view = camera.model_view

            for node in self.scene_root.dfs():
                if isinstance( node, CameraNode ):
                    continue

                # get the node's world matrix
                world_matrix = node.world_transform.matrix

                # apply the camera's model view to the node's matrix
                current_mv = pyrr.matrix44.multiply(
                    world_matrix,
                    model_view
                    )

                # render a cube
                self.cube.draw( projection, current_mv )

        def render_legacy():
            # load our projection matrix
            with pygly.gl.mode_and_matrix(
                GL.GL_PROJECTION,
                camera.projection_matrix
                ):
                with pygly.gl.mode_and_matrix(
                    GL.GL_MODELVIEW,
                    camera.model_view
                    ):
                    # iterate through the scene graph
                    for node in self.scene_root.dfs():
                        # don't render cameras
                        if isinstance( node, CameraNode ):
                            continue

                        world_matrix = node.world_transform.matrix

                        # multiply the existing model view matrix
                        # by the model's world matrix
                        # then render a cube
                        with pygly.gl.multiply_matrix( world_matrix ):
                            self.cube.draw()

        # activate our viewport
        pygly.viewport.set_viewport( viewport )

        # set our scissor to the main viewport
        pygly.viewport.set_scissor( viewport )

        # clear the colour and depth buffer
        GL.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT )

        # render the scene
        if self.core_profile:
            render_core()
        else:
            render_legacy()
Exemple #28
0
    def setup_scene( self ):
        """Creates the scene to be rendered.
        Creates our camera, scene graph, 
        """
        # don't call 'SimpleApplication's setup_scene
        CoreApplication.setup_scene( self )

        # setup our GL state
        # enable z buffer
        glEnable( GL_DEPTH_TEST )

        # enable back face culling
        #glEnable( GL_CULL_FACE )
        glDisable( GL_CULL_FACE )
        #glCullFace( GL_BACK )

        # create a grid of cubes
        self.grid_root = SceneNode( 'grid_root' )
        self.scene_node.add_child( self.grid_root )

        self.mesh_node = RenderCallbackNode(
            'mesh',
            None,
            self.render_node
            )
        # rotate the mesh to face the camera
        self.mesh_node.transform.object.rotate_x( -math.pi * 0.5 )

        # store a list of renderables
        mesh_path = os.path.join(
            os.path.dirname( __file__ ),
            '../data/md5/boblampclean.md5mesh'
            #'../data/md5/md5/cyberdemon/cyberdemon.md5mesh'
            )

        anim_path = os.path.join(
            os.path.dirname( __file__ ),
            '../data/md5/boblampclean.md5anim'
            #'../data/md5/md5/cyberdemon/idle.md5anim'
            )

        # load our md5 data
        self.md5mesh = MD5_Mesh()
        self.md5mesh.load( mesh_path )

        self.md5anim = MD5_Anim()
        self.md5anim.load( anim_path )

        # load the gl mesh
        self.mesh_node.mesh = Mesh( self.md5mesh )

        # load our bindpose
        self.mesh_node.baseframe = BaseFrameSkeleton( self.md5mesh )

        # load some test skeletons
        self.mesh_node.anim = Animation( self.md5anim )

        # set to base frame
        self.mesh_node.mesh.set_skeleton( self.mesh_node.baseframe )

        # load a skeleton renderer
        self.mesh_node.skeleton = SkeletonRenderer()
        #self.mesh_node.skeleton.set_skeleton( self.mesh_node.baseframe )
        self.mesh_node.skeleton.set_skeleton( self.mesh_node.anim.skeleton( 0 ) )

        # create a list of frames
        self.frames = [
            skeleton
            for skeleton in self.mesh_node.anim
            ]
        #self.frames = []
        self.frames.append( self.mesh_node.baseframe )

        self.frame = 0
        self.time_accumulator = 0.0
        self.time_per_frame = 1.0 / self.mesh_node.anim.frame_rate


        # attach to our scene graph
        self.grid_root.add_child( self.mesh_node )

        # scale the node
        self.mesh_node.transform.scale = 0.5
    def test_tree( self ):
        root = SceneNode( 'root' )

        child1_1 = SceneNode( 'child1_1' )
        child1_2 = SceneNode( 'child1_2' )

        child2_1 = SceneNode( 'child2_1' )
        child2_2 = SceneNode( 'child2_2' )

        root.add_child( child1_1 )
        root.add_child( child1_2 )

        child1_1.add_child( child2_1 )
        child1_2.add_child( child2_2 )

        self.assertTrue(
            child1_1.parent is root,
            "Parent not set correctly"
            )
        self.assertTrue(
            child1_1 in root.children,
            "Child not in parents child list"
            )
        self.assertTrue(
            child1_2.parent is root,
            "Parent not set correctly"
            )
        self.assertTrue(
            child1_2 in root.children,
            "Child not in parents child list"
            )

        self.assertTrue(
            child2_1.parent is child1_1,
            "Parent not set correctly"
            )
        self.assertTrue(
            child2_1 in child1_1.children,
            "Child not in parents child list"
            )
        self.assertTrue(
            child2_2.parent is child1_2,
            "Parent not set correctly"
            )
        self.assertTrue(
            child2_2 in child1_2.children,
            "Child not in parents child list"
            )

        child1_2.remove_child( child2_2 )
        child1_1.add_child( child2_2 )

        self.assertTrue(
            child2_2.parent is child1_1,
            "Parent not set correctly"
            )
        self.assertTrue(
            child2_2 in child1_1.children,
            "Child not in parents child list"
            )
        self.assertFalse(
            child2_2 in child1_2.children,
            "Child not removed from parents child list"
            )
Exemple #30
0
class BaseApplication(object):
    def __init__(self, caption=None):
        super(BaseApplication, self).__init__()

        self.setup_window(caption)
        self.setup_input()
        self.setup_ui()
        self.setup_scene_root()
        self.setup_camera()
        self.setup_scene()
        self.setup_events()

    def setup_window(self, caption):
        # setup our opengl requirements
        config = pyglet.gl.Config(depth_size=16, double_buffer=True, major_version=2, minor_version=1)

        # create our window
        self.window = pyglet.window.Window(
            fullscreen=False, width=1024, height=768, caption=caption, resizable=True, config=config
        )

        # listen for on_draw events
        self.window.push_handlers(on_draw=self.on_draw)

        # create a viewport
        self.viewport = RatioViewport(self.window, [[0.0, 0.0], [1.0, 1.0]])

    def setup_input(self):
        # create our keyboard device
        self.keyboard = Keyboard(self.window)

        # register for keypresses
        self.keyboard.digital.push_handlers(on_digital_input=self.on_key_event)

        # create our mouse device
        self.mouse = Mouse(self.window)

    def setup_events(self):
        # setup our update loop the app
        # we'll render at 60 fps
        frequency = 60.0
        self.update_delta = 1.0 / frequency

        # use a pyglet callback for our render loop
        pyglet.clock.schedule_interval(self.step, self.update_delta)

    def setup_ui(self):
        # create an fps display
        self.fps_display = pyglet.clock.ClockDisplay()

    def setup_scene_root(self):
        # create a list of renderables
        self.renderables = []

        # create a scene
        self.scene_node = SceneNode("root")

    def setup_camera(self):
        # create a camera and a view matrix
        self.view_matrix = ProjectionViewMatrix(self.viewport.aspect_ratio, fov=45.0, near_clip=1.0, far_clip=200.0)
        # create a camera
        self.camera = CameraNode("camera", self.view_matrix)
        self.scene_node.add_child(self.camera)

    def setup_scene(self):
        # CREATE SCENE HERE
        pass

    def run(self):
        pyglet.app.run()

    def step(self, dt):
        # update our mouse
        self.update_mouse(dt)

        # update the scene here
        self.update_scene(dt)

        # manually dispatch the on_draw event
        # as we patched it out of the idle loop
        self.window.dispatch_event("on_draw")

        # display the frame buffer
        self.window.flip()

    def update_mouse(self, dt):
        # USE MOUSE VALUES HERE
        pass

        # reset the relative position of the mouse
        self.mouse.clear_delta()

    def on_key_event(self, digital, event, key):
        # HANDLE KEYBOARD INPUT HERE
        pass

    def update_scene(self, dt):
        # UPDATE SCENE HERE
        pass

    def on_draw(self):
        # render the scene
        self.render()

        # render the fps
        self.fps_display.draw()

    def render(self):
        #
        # setup
        #

        # set our window
        self.window.switch_to()

        # activate our viewport
        self.viewport.switch_to()

        # scissor to our viewport
        self.viewport.scissor_to_viewport()

        # setup our viewport properties
        glPushAttrib(GL_ALL_ATTRIB_BITS)

        # update the view matrix aspect ratio
        self.camera.view_matrix.aspect_ratio = self.viewport.aspect_ratio

        # apply our view matrix and camera translation
        self.camera.view_matrix.push_view_matrix()
        self.camera.push_model_view()

        #
        # render
        #

        # clear our frame buffer and depth buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        self.render_3d()

        #
        # tear down
        #

        # pop our view matrix and camera translation
        self.camera.pop_model_view()
        self.camera.view_matrix.pop_view_matrix()

        # pop our viewport attributes
        glPopAttrib()

        #
        # reset state
        #

        # set our viewport to the entire window
        pygly.gl.set_scissor(pygly.window.create_rectangle(self.window))
        pygly.gl.set_viewport(pygly.window.create_rectangle(self.window))

        #
        # render 2d
        #

        self.render_2d()

    def render_2d(self):
        # render the fps
        self.fps_display.draw()
Exemple #31
0
    def setup_scene( self ):
        """Creates the scene to be rendered.
        Creates our camera, scene graph, 
        """
        # don't call 'SimpleApplication's setup_scene
        CoreApplication.setup_scene( self )

        # setup our GL state
        # enable z buffer
        glEnable( GL_DEPTH_TEST )

        # enable back face culling
        glEnable( GL_CULL_FACE )
        glCullFace( GL_BACK )

        # load our texture
        # use the PIL decoder as the pyglet one is broken
        # and loads most images as greyscale
        path = os.path.join(
            os.path.dirname( __file__ ),
            '../../data/md2/sydney.bmp'
            )
        image = Image.open( path )
        self.texture = Texture2D( GL_TEXTURE_2D )
        self.texture.bind()
        self.texture.set_min_mag_filter(
            min = GL_LINEAR,
            mag = GL_LINEAR
            )
        # load the image from PIL
        # MD2 textures are inverted
        pygly.pil_texture.set_pil_image( self.texture, image, flip = False )
        self.texture.unbind()

        # create a grid of cubes
        self.grid_root = SceneNode( 'grid_root' )
        self.scene_node.add_child( self.grid_root )

        # create a number of cubes
        # the grid will extend from -5 to +5
        x,z = numpy.mgrid[
            -5:5:11j,
            -5:5:11j
            ]
        x = x.flatten()
        z = z.flatten()

        positions = numpy.vstack(
            (x, numpy.zeros( x.shape ), z )
            )
        positions = positions.T

        # set the distance between the models
        positions *= 4.5

        # store a list of renderables
        self.renderables = []

        path = os.path.join(
            os.path.dirname( __file__ ),
            '../../data/md2/sydney.md2'
            )

        for position in positions:
            node = RenderCallbackNode(
                'node-%s' % position,
                None,
                self.render_node
                )
            node.mesh = MD2_Mesh( path )
            node.mesh.load()

            # attach to our scene graph
            self.grid_root.add_child( node )
            self.renderables.append( node )

            # move and scale the node
            node.transform.inertial.translation = position
            node.transform.scale = 0.2

        # create a range of animation times
        # 0.0 <= x < num_frames
        self.frames = numpy.linspace(
            0.0,
            float(self.renderables[ 0 ].mesh.num_frames),
            len(positions),
            endpoint = False
            )

        # create an array that will store our frame rates
        self.frame_rate = numpy.zeros( len(self.renderables), dtype = numpy.float )

        self.animation = ''
Exemple #32
0
class OBJ_Application(SimpleApplication):
    def setup_viewports(self):
        super(OBJ_Application, self).setup_viewports()

        self.colours[0] = (0.1, 0.1, 0.1, 1.0)

    def setup_camera(self):
        super(OBJ_Application, self).setup_camera()

        # move the camera
        self.cameras[0].transform.inertial.translate([0.0, -3.0, -5.0])
        # tilt the camera downward
        self.cameras[0].transform.object.rotate_x(math.pi / 8.0)

    def setup_scene(self):
        """Creates the scene to be rendered.
        Creates our camera, scene graph, 
        """
        # don't call 'SimpleApplication's setup_scene
        CoreApplication.setup_scene(self)

        # setup our GL state
        # enable z buffer
        glEnable(GL_DEPTH_TEST)

        # enable back face culling
        glEnable(GL_CULL_FACE)
        glCullFace(GL_BACK)

        # create a grid of cubes
        self.grid_root = SceneNode('grid_root')
        self.scene_node.add_child(self.grid_root)

        # store a list of renderables
        path = os.path.join(os.path.dirname(__file__),
                            '../data/obj/capsule.obj')

        self.mesh_node = RenderCallbackNode('mesh', None, self.render_node)
        # rotate the mesh to face the camera
        self.mesh_node.transform.object.rotate_y(math.pi)

        self.mesh_node.mesh = OBJ_Mesh(path)
        self.mesh_node.mesh.load()

        # attach to our scene graph
        self.grid_root.add_child(self.mesh_node)

        # scale the node
        self.mesh_node.transform.scale = 1.0

        # create a list of groups to render
        # by default, render all groups
        # this may be in-efficient if data is contained in
        # multiple groups
        self.groups = self.mesh_node.mesh.data.meshes.keys()

    def step(self, dt):
        """Updates our scene and triggers the on_draw event.
        This is scheduled in our __init__ method and
        called periodically by pyglet's event callbacks.
        We need to manually call 'on_draw' as we patched
        it our of pyglets event loop when we patched it
        out with pygly.monkey_patch.
        Because we called 'on_draw', we also need to
        perform the buffer flip at the end.
        """
        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.grid_root.transform.object.rotate_y(dt * 0.2)

        # this will trigger the draw event and buffer flip
        CoreApplication.step(self, dt)

    def render_scene(self, camera):
        """Renders each renderable in the scene
        using the current projection and model
        view matrix.
        The original GL state will be restored
        upon leaving this function.
        """
        projection = camera.view_matrix.matrix
        model_view = camera.model_view

        # update the model view
        world_matrix = self.mesh_node.world_transform.matrix
        current_mv = matrix44.multiply(world_matrix, model_view)

        # render a cube
        self.mesh_node.render(projection=projection,
                              model_view=current_mv,
                              groups=self.groups)

    def render_node(self, node, **kwargs):
        node.mesh.render(**kwargs)
Exemple #33
0
    def setup_scene_root(self):
        # create a list of renderables
        self.renderables = []

        # create a scene
        self.scene_node = SceneNode("root")
Exemple #34
0
class Application( object ):
    
    def __init__( self ):
        super( Application, self ).__init__()
        
        # setup our opengl requirements
        config = pyglet.gl.Config(
            depth_size = 16,
            double_buffer = True
            )

        # create our window
        self.window = pyglet.window.Window(
            fullscreen = False,
            width = 1024,
            height = 768,
            resizable = True,
            vsync = False,
            config = config
            )

        # create a viewport
        self.viewport = RatioViewport(
            self.window,
            [ [0.0, 0.0], [1.0, 1.0] ]
            )
        
        # setup our scene
        self.setup_scene()

        # listen for on_draw events
        self.window.push_handlers(
            on_draw = self.on_draw
            )
        
        # setup our update loop the app
        # we'll render at 60 fps
        frequency = 60.0
        self.update_delta = 1.0 / frequency

        # over-ride the frequency and render at full speed
        self.update_delta = -1

        # use a pyglet callback for our render loop
        pyglet.clock.schedule_interval(
            self.step,
            self.update_delta
            )

    def setup_scene( self ):
        # create an fps display
        self.fps_display = pyglet.clock.ClockDisplay()

        # store a list of our renderables
        self.renderables = []

        # create a scene
        self.scene_node = SceneNode( 'root' )

        self.mesh_node = SceneNode( 'obj' )
        self.scene_node.add_child( self.mesh_node )

        # create a mesh object and render node
        self.mesh = OBJ_Mesh( 'examples/data/obj/cessna.obj' )
        self.mesh_render_node = RenderCallbackNode(
            'mesh',
            self.initialise_mesh,
            self.render_mesh
            )
        self.mesh_node.add_child( self.mesh_render_node )

        # add to our list of renderables
        self.renderables.append( self.mesh_render_node )
        
        # create a camera and a view matrix
        self.view_matrix = ProjectionViewMatrix(
            self.viewport.aspect_ratio,
            fov = 45.0,
            near_clip = 1.0,
            far_clip = 200.0
            )
        # create a camera
        self.camera = CameraNode(
            'camera',
            self.view_matrix
            )
        self.scene_node.add_child( self.camera )

        # move the camera so we can see the model
        self.camera.transform.object.translate(
            [ 0.0, 20.0, 30.0 ]
            )

        # rotate the camera so it is pointing down
        self.camera.transform.object.rotate_x( -math.pi / 4.0 )
        
    def run( self ):
        pyglet.app.run()

    def step( self, dt ):
        # rotate the mesh about it's own vertical axis
        self.mesh_node.transform.object.rotate_y( dt )

        # manually dispatch the on_draw event
        # as we patched it out of the idle loop
        self.window.dispatch_event( 'on_draw' )
        
        # display the frame buffer
        self.window.flip()

    def on_draw( self ):
        # render the scene
        self.render()

        # render the fps
        self.fps_display.draw()

    def initialise_mesh( self ):
        # load the obj mesh from the file
        self.mesh.load()

    def render_mesh( self ):
        # render the mesh
        self.mesh.render()

    def set_gl_state( self ):
        # enable z buffer
        glEnable( GL_DEPTH_TEST )

        # enable smooth shading
        glShadeModel( GL_SMOOTH )

        # rescale only normals for lighting
        glEnable( GL_RESCALE_NORMAL )

        # enable scissoring for viewports
        glEnable( GL_SCISSOR_TEST )

        # enable back face culling
        glEnable( GL_CULL_FACE )
        glCullFace( GL_BACK )

        # setup lighting for our viewport
        glEnable( GL_LIGHTING )

        # set an ambient light level
        glAmbient = glLightModelfv(
            GL_LIGHT_MODEL_AMBIENT,
            (GLfloat * 4)( *[ 0.8, 0.8, 0.8, 1.0 ] )
            )

        # create a light
        glEnable( GL_LIGHT0 )
        glLightfv(
            GL_LIGHT0,
            GL_POSITION,
            (GLfloat * 4)( *[0.0, 20.0, 30.0, 1.0] )
            )
    
    def render( self ):
        #
        # setup
        #

        # set our window
        self.window.switch_to()

        # activate our viewport
        self.viewport.switch_to()

        # scissor to our viewport
        self.viewport.scissor_to_viewport()

        # setup our viewport properties
        glPushAttrib( GL_ALL_ATTRIB_BITS )
        self.set_gl_state()

        # update the view matrix aspect ratio
        self.camera.view_matrix.aspect_ratio = self.viewport.aspect_ratio

        # apply our view matrix and camera translation
        self.camera.view_matrix.push_view_matrix()
        self.camera.push_model_view()

        #
        # render
        #

        # clear our frame buffer and depth buffer
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )

        for renderable in self.renderables:
            renderable.render()

        #
        # tear down
        #

        # pop our view matrix and camera translation
        self.camera.pop_model_view()
        self.camera.view_matrix.pop_view_matrix()

        # pop our viewport attributes
        glPopAttrib()

        #
        # reset state
        #

        # set our viewport to the entire window
        pygly.gl.set_scissor(
            pygly.window.create_rectangle( self.window )
            )
        pygly.gl.set_viewport(
            pygly.window.create_rectangle( self.window )
            )
Exemple #35
0
class Application( BaseApplication ):
    
    def __init__( self ):
        self.print_opengl_versions()
        
        super( Application, self ).__init__( "PyGLy - Conway's Game of Life" )

    def print_opengl_versions( self ):
        # get OpenGL version
        print "OpenGL version", gl_info.get_version()        
        
        # get GLSL version
        plain = string_at(glGetString(GL_SHADING_LANGUAGE_VERSION)).split(' ')[0]
        major, minor = map(int, plain.split('.'))
        version = major * 100 + minor
        print "GLSL Version", version
        
    def setup_camera( self ):
        super( Application, self ).setup_camera()

        # move the camera so we can see the scene
        self.camera.transform.inertial.translate(
            [ 0.0, 0.0, 5.0 ]
            )

    def setup_ui( self ):
        super( Application, self ).setup_ui()

        self.help_label = pyglet.text.HTMLLabel(
"""
<b>Game of Life</b>
""",
        multiline = True,
        x = 10,
        y = 50,
        width = 500,
        anchor_x = 'left',
        anchor_y = 'bottom',
        )
        self.help_label.color = (255,255,255,255)

    def setup_scene( self ):
        super( Application, self ).setup_scene()
        
        # enable texturing
        glEnable( GL_TEXTURE_2D )

        # set our gl clear colour
        glClearColor( 0.2, 0.2, 0.2, 1.0 )

        # create a scene node to hold our GOL renderable
        self.gol_node = SceneNode( "GOL_Node" )
        self.scene_node.add_child( self.gol_node )
        
        # get the maximum viewport size
        max_viewport_size = (c_int * 2)()
        glGetIntegerv( GL_MAX_VIEWPORT_DIMS, max_viewport_size )
        
        max_viewport_size = (max_viewport_size[ 0 ], max_viewport_size[ 1 ])
        print "Max viewport size", max_viewport_size
        
        # make the GOL board
        # ensure it is a power of 2 for ou texture
        board_size = (2048, 2048)
        if board_size > max_viewport_size:
            board_size = max_viewport_size
        
        self.gol = GOL_Renderable( board_size )
        # add our renderable to the scene
        self.gol_node.add_child( self.gol )
        # add to our list of renderables
        self.renderables.append( self.gol )

    def update_mouse( self, dt ):
        # USE MOUSE VALUES HERE
        pass

        # reset the relative position of the mouse
        super( Application, self ).update_mouse( dt )

    def on_key_event( self, digital, event, key ):
        # HANDLE KEYBOARD INPUT HERE
        pass

    def update_scene( self, dt ):
        # rotate the GOL board
        self.gol_node.transform.object.rotate_y( dt * 0.3 )
        
        # add the delta to the accumulated time
        self.gol.dt += dt

    def render_3d( self ):
        # enable z buffer
        glEnable( GL_DEPTH_TEST )
        
        # disable lighting
        glDisable( GL_LIGHTING )
        
        # enable smooth shading
        glShadeModel( GL_SMOOTH )

        # rescale only normals for lighting
        glEnable( GL_RESCALE_NORMAL )

        # enable scissoring for viewports
        glEnable( GL_SCISSOR_TEST )

        # enable back face culling
        #glEnable( GL_CULL_FACE )
        #glCullFace( GL_BACK )
        glDisable( GL_CULL_FACE )

        # render each object
        for renderable in self.renderables:
            renderable.render()

    def render_2d( self ):
        super( Application, self ).render_2d()

        self.help_label.draw()
Exemple #36
0
class Scene(scene.Scene):
    def __init__(self, core_profile=True):
        super(Scene, self).__init__(core_profile)

    @property
    def name(self):
        return "Basic"

    def initialise(self):
        super(Scene, self).initialise()

        def set_gl_state():
            # setup our GL state
            # enable z buffer
            GL.glEnable(GL.GL_DEPTH_TEST)

            # enable back face culling
            GL.glEnable(GL.GL_CULL_FACE)
            GL.glCullFace(GL.GL_BACK)

        set_gl_state()

        # create a viewport
        # this will be updated before we begin
        self.viewport = None

        # create a cube to render
        self.cube = renderable_cube.create(self.core_profile)

        def setup_scene():
            # create a scene
            # we'll create the scene as a tree
            # to demonstrate the depth-first iteration
            # technique we will use to render it
            self.scene_root = SceneNode('root')

            # the letter indicates the tier the node
            # is on, a = tier 1, b = tier 2, etc.
            self.a1 = SceneNode('a1')
            self.b1 = SceneNode('b1')
            self.b2 = SceneNode('b2')
            self.c1 = SceneNode('c1')
            self.c2 = SceneNode('c2')
            self.c3 = SceneNode('c3')

            # the tree looks as follows
            #                / c1
            #           / b1 - c2
            # root - a1
            #           \ b2 - c3
            self.scene_root.add_child(self.a1)
            self.a1.add_child(self.b1)
            self.a1.add_child(self.b2)
            self.b1.add_child(self.c1)
            self.b1.add_child(self.c2)
            self.b2.add_child(self.c3)

            # if we set the nodes local scale (transform)
            # it will be affected by the parent's scale.
            # by setting the world scale (world_transform)
            # we are ignoring the parent's scale.
            # re-attaching the node would invalidate this.
            self.a1.world_transform.scale = [2.0, 2.0, 2.0]
            self.b1.world_transform.scale = [1.0, 1.0, 1.0]
            self.b2.world_transform.scale = [1.0, 1.0, 1.0]
            self.c1.world_transform.scale = [0.8, 0.8, 0.8]
            self.c2.world_transform.scale = [0.8, 0.8, 0.8]
            self.c3.world_transform.scale = [0.8, 0.8, 0.8]

            # move our scene nodes
            # leave a1 at the centre
            self.b1.transform.object.translate([10.0, 0.0, 0.0])
            self.b2.transform.object.translate([-10.0, 0.0, 0.0])
            self.c1.transform.object.translate([5.0, 0.0, 0.0])
            self.c2.transform.object.translate([-5.0, 0.0, 0.0])
            self.c3.transform.object.translate([5.0, 0.0, 0.0])

            # rotate the our b nodes so they tilting forward
            self.b1.transform.object.rotate_x(math.pi / 4.0)
            self.b2.transform.object.rotate_x(math.pi / 4.0)

        setup_scene()

        def setup_camera():
            # create our camera node
            self.camera = CameraNode('camera', pyrr.matrix44.create_identity())
            self.scene_root.add_child(self.camera)

            # move the camera so we're not inside
            # the root scene node's debug cube
            self.camera.transform.object.translate([0.0, 30.0, 35.0])

            # tilt the camera downward
            self.camera.transform.object.rotate_x(-math.pi / 4.0)

        setup_camera()

    def on_window_resized(self, width, height):
        # update the viewport
        self.viewport = pyrr.rectangle.create_from_position(x=0,
                                                            y=0,
                                                            width=width,
                                                            height=height)

        # update the projection matrix
        # we need to do this or the rendering will become skewed with each
        # resize of viewport change
        aspect_ratio = pyrr.rectangle.aspect_ratio(self.viewport)
        self.camera.projection_matrix = pyrr.matrix44.create_perspective_projection_matrix(
            fovy=80.0, aspect=aspect_ratio, near=1.0, far=100.0)

    def step(self, dt):
        super(Scene, self).step(dt)

        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.a1.transform.object.rotate_y(dt)
        self.b1.transform.object.rotate_y(dt)
        self.b2.transform.object.rotate_y(dt)
        self.c1.transform.object.rotate_y(dt)
        self.c2.transform.object.rotate_y(dt)
        self.c3.transform.object.rotate_y(dt)

    def render(self):
        super(Scene, self).render()

        # this code is split into 2 functions to support the
        # multiple_viewports scene which inherits from this class
        self.render_viewport(self.viewport, self.camera)

    def render_viewport(self, viewport, camera):
        def render_core():
            projection = camera.projection_matrix
            model_view = camera.model_view

            for node in self.scene_root.dfs():
                if isinstance(node, CameraNode):
                    continue

                # get the node's world matrix
                world_matrix = node.world_transform.matrix

                # apply the camera's model view to the node's matrix
                current_mv = pyrr.matrix44.multiply(world_matrix, model_view)

                # render a cube
                self.cube.draw(projection, current_mv)

        def render_legacy():
            # load our projection matrix
            with pygly.gl.mode_and_matrix(GL.GL_PROJECTION,
                                          camera.projection_matrix):
                with pygly.gl.mode_and_matrix(GL.GL_MODELVIEW,
                                              camera.model_view):
                    # iterate through the scene graph
                    for node in self.scene_root.dfs():
                        # don't render cameras
                        if isinstance(node, CameraNode):
                            continue

                        world_matrix = node.world_transform.matrix

                        # multiply the existing model view matrix
                        # by the model's world matrix
                        # then render a cube
                        with pygly.gl.multiply_matrix(world_matrix):
                            self.cube.draw()

        # activate our viewport
        pygly.viewport.set_viewport(viewport)

        # set our scissor to the main viewport
        pygly.viewport.set_scissor(viewport)

        # clear the colour and depth buffer
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

        # render the scene
        if self.core_profile:
            render_core()
        else:
            render_legacy()
Exemple #37
0
class MD2_Application(SimpleApplication):
    def setup_viewports(self):
        super(MD2_Application, self).setup_viewports()

        self.colours[0] = (1.0, 1.0, 1.0, 1.0)

    def setup_scene(self):
        """Creates the scene to be rendered.
        Creates our camera, scene graph, 
        """
        # don't call 'SimpleApplication's setup_scene
        CoreApplication.setup_scene(self)

        # setup our GL state
        # enable z buffer
        glEnable(GL_DEPTH_TEST)

        # enable back face culling
        glEnable(GL_CULL_FACE)
        glCullFace(GL_BACK)

        # load our texture
        # use the PIL decoder as the pyglet one is broken
        # and loads most images as greyscale
        path = os.path.join(os.path.dirname(__file__),
                            '../../data/md2/sydney.bmp')
        image = Image.open(path)
        self.texture = Texture2D(GL_TEXTURE_2D)
        self.texture.bind()
        self.texture.set_min_mag_filter(min=GL_LINEAR, mag=GL_LINEAR)
        # load the image from PIL
        # MD2 textures are inverted
        pygly.pil_texture.set_pil_image(self.texture, image, flip=False)
        self.texture.unbind()

        # create a grid of cubes
        self.grid_root = SceneNode('grid_root')
        self.scene_node.add_child(self.grid_root)

        # create a number of cubes
        # the grid will extend from -5 to +5
        x, z = numpy.mgrid[-5:5:11j, -5:5:11j]
        x = x.flatten()
        z = z.flatten()

        positions = numpy.vstack((x, numpy.zeros(x.shape), z))
        positions = positions.T

        # set the distance between the models
        positions *= 4.5

        # store a list of renderables
        self.renderables = []

        path = os.path.join(os.path.dirname(__file__),
                            '../../data/md2/sydney.md2')

        for position in positions:
            node = RenderCallbackNode('node-%s' % position, None,
                                      self.render_node)
            node.mesh = MD2_Mesh(path)
            node.mesh.load()

            # attach to our scene graph
            self.grid_root.add_child(node)
            self.renderables.append(node)

            # move and scale the node
            node.transform.inertial.translation = position
            node.transform.scale = 0.2

        # create a range of animation times
        # 0.0 <= x < num_frames
        self.frames = numpy.linspace(0.0,
                                     float(
                                         self.renderables[0].mesh.num_frames),
                                     len(positions),
                                     endpoint=False)

        # create an array that will store our frame rates
        self.frame_rate = numpy.zeros(len(self.renderables), dtype=numpy.float)

        self.animation = ''

    def step(self, dt):
        """Updates our scene and triggers the on_draw event.
        This is scheduled in our __init__ method and
        called periodically by pyglet's event callbacks.
        We need to manually call 'on_draw' as we patched
        it our of pyglets event loop when we patched it
        out with pygly.monkey_patch.
        Because we called 'on_draw', we also need to
        perform the buffer flip at the end.
        """
        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.grid_root.transform.object.rotate_y(dt * 0.2)

        # update our frame rates
        self.frame_rate[:] = [
            mesh_node.mesh.frame_rate for mesh_node in self.renderables
        ]

        # increment our frame
        #self.frames += dt * fps
        self.frames += dt * self.frame_rate
        numpy.mod(self.frames, self.renderables[0].mesh.num_frames,
                  self.frames)

        # print the animation name of the first mesh
        curr_anim = self.renderables[0].mesh.animation
        if self.animation != curr_anim:
            self.animation = curr_anim
            print 'Curren animation:', self.animation

        # this will trigger the draw event and buffer flip
        CoreApplication.step(self, dt)

    def render_scene(self, camera):
        """Renders each renderable in the scene
        using the current projection and model
        view matrix.
        The original GL state will be restored
        upon leaving this function.
        """
        projection = camera.view_matrix.matrix
        model_view = camera.model_view

        # bind our diffuse texture
        glActiveTexture(GL_TEXTURE0)
        self.texture.bind()

        # iterate through our renderables
        for node, frame in zip(self.renderables, self.frames):
            # update the model view
            world_matrix = node.world_transform.matrix
            current_mv = matrix44.multiply(world_matrix, model_view)

            fraction, frame1 = math.modf(frame)
            frame2 = (frame1 + 1.0) % node.mesh.num_frames

            # update the frame
            node.mesh.frame_1 = int(frame1)
            node.mesh.frame_2 = int(frame2)
            node.mesh.interpolation = fraction

            # render a cube
            node.render(projection=projection, model_view=current_mv)

        glActiveTexture(GL_TEXTURE0)
        self.texture.unbind()

    def render_node(self, node, **kwargs):
        node.mesh.render(**kwargs)
Exemple #38
0
class Scene(scene_scene_graph.Scene):
    def __init__(self, core_profile=True):
        super(Scene, self).__init__(core_profile)

    def initialise(self):
        super(Scene, self).initialise()

        def set_gl_state():
            # setup our GL state
            # enable scissoring for viewports
            GL.glEnable(GL.GL_SCISSOR_TEST)

        set_gl_state()

        self.viewport2 = None

        def setup_camera():
            # add another node that our camera will be under
            # we can rotate this node to show how the cameras work
            self.camera2_parent = SceneNode('camera2_parent')
            self.scene_root.add_child(self.camera2_parent)

            # create our camera node
            self.camera2 = CameraNode('camera2',
                                      pyrr.matrix44.create_identity())
            self.camera2_parent.add_child(self.camera2)

            # place the camera at the same position as the previous one
            #self.camera2.transform.translation = self.camera.transform.translation
            #self.camera2.transform.orientation = self.camera.transform.orientation
            #self.camera2.transform.scale = self.camera.transform.scale

            self.camera2.transform.object.translate([0.0, 0.0, 35.0])

        setup_camera()

    def on_window_resized(self, width, height):
        #super( Scene, self ).on_window_resized( width, height )

        def update_viewports():
            half_width = width / 2.0

            # update the viewport
            self.viewport = pyrr.rectangle.create_from_position(
                x=0, y=0, width=half_width, height=height)

            self.viewport2 = pyrr.rectangle.create_from_position(
                x=half_width, y=0, width=half_width, height=height)

            print(self.viewport, self.viewport2)

        def update_cameras():
            # update the projection matrix
            # we need to do this or the rendering will become skewed with each
            # resize of viewport change
            aspect_ratio = pyrr.rectangle.aspect_ratio(self.viewport)
            self.camera.projection_matrix = pyrr.matrix44.create_perspective_projection_matrix(
                fovy=80.0, aspect=aspect_ratio, near=1.0, far=100.0)

            # update the projection matrix
            # we need to do this or the rendering will become skewed with each
            # resize of viewport change
            aspect_ratio = pyrr.rectangle.aspect_ratio(self.viewport2)
            self.camera2.projection_matrix = pyrr.matrix44.create_perspective_projection_matrix(
                fovy=80.0, aspect=aspect_ratio, near=1.0, far=100.0)

        update_viewports()
        update_cameras()

    def step(self, dt):
        super(Scene, self).step(dt)

        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.camera2_parent.transform.object.rotate_x(dt)

    def render(self):
        # render viewport 1
        super(Scene, self).render()

        # change our clear colour to make it clear where the viewport is
        GL.glClearColor(1.0, 1.0, 1.0, 1.0)

        # render the viewport
        self.render_viewport(self.viewport2, self.camera2)
Exemple #39
0
class OBJ_Application( SimpleApplication ):

    def setup_viewports( self ):
        super( OBJ_Application, self ).setup_viewports()

        self.colours[ 0 ] = (0.1,0.1,0.1,1.0)

    def setup_camera( self ):
        super( OBJ_Application, self ).setup_camera()

        # move the camera
        self.cameras[ 0 ].transform.inertial.translate(
            [ 0.0,-3.0,-5.0 ]
            )
        # tilt the camera downward
        self.cameras[ 0 ].transform.object.rotate_x( math.pi / 8.0 )

    def setup_scene( self ):
        """Creates the scene to be rendered.
        Creates our camera, scene graph, 
        """
        # don't call 'SimpleApplication's setup_scene
        CoreApplication.setup_scene( self )

        # setup our GL state
        # enable z buffer
        glEnable( GL_DEPTH_TEST )

        # enable back face culling
        glEnable( GL_CULL_FACE )
        glCullFace( GL_BACK )

        # create a grid of cubes
        self.grid_root = SceneNode( 'grid_root' )
        self.scene_node.add_child( self.grid_root )

        # store a list of renderables
        path = os.path.join(
            os.path.dirname( __file__ ),
            '../data/obj/capsule.obj'
            )

        self.mesh_node = RenderCallbackNode(
            'mesh',
            None,
            self.render_node
            )
        # rotate the mesh to face the camera
        self.mesh_node.transform.object.rotate_y( math.pi )

        self.mesh_node.mesh = OBJ_Mesh( path )
        self.mesh_node.mesh.load()

        # attach to our scene graph
        self.grid_root.add_child( self.mesh_node )

        # scale the node
        self.mesh_node.transform.scale = 1.0

        # create a list of groups to render
        # by default, render all groups
        # this may be in-efficient if data is contained in
        # multiple groups
        self.groups = self.mesh_node.mesh.data.meshes.keys()

    def step( self, dt ):
        """Updates our scene and triggers the on_draw event.
        This is scheduled in our __init__ method and
        called periodically by pyglet's event callbacks.
        We need to manually call 'on_draw' as we patched
        it our of pyglets event loop when we patched it
        out with pygly.monkey_patch.
        Because we called 'on_draw', we also need to
        perform the buffer flip at the end.
        """
        # setup the scene
        # rotate the scene nodes about their vertical axis
        self.grid_root.transform.object.rotate_y( dt * 0.2 )

        # this will trigger the draw event and buffer flip
        CoreApplication.step( self, dt )

    def render_scene( self, camera ):
        """Renders each renderable in the scene
        using the current projection and model
        view matrix.
        The original GL state will be restored
        upon leaving this function.
        """
        projection = camera.view_matrix.matrix
        model_view = camera.model_view

        # update the model view
        world_matrix = self.mesh_node.world_transform.matrix
        current_mv = matrix44.multiply(
            world_matrix,
            model_view
            )

        # render a cube
        self.mesh_node.render(
            projection = projection,
            model_view = current_mv,
            groups = self.groups
            )

    def render_node( self, node, **kwargs ):
        node.mesh.render( **kwargs )