| /FAQ /Tutorial |
Overview
This page describes a few of the many of the demo scripts included with the Vision Egg. Click on the images to see a 320x240 12 frame per second QuickTime movie of the output of the Vision Egg. Note that this is very small and slow compared to what you would see running the same demo on your computer, especially in fullscreen mode. These demos and many more are a DownloadAndInstall away.
grating.py
The grating demo is a simple Vision Egg application script to show basic operation. First, the screen is initialized, which opens the OpenGL window. Second, a grating object is created with specified parameters of size, position, spatial frequency, temporal frequency, and orientation. Next, a viewport object is created, which is an intermediary between stimuli and screens. Finally, a presentation object is created, which controls the main loop and realtime behavior of any Vision Egg script.
1 #!/usr/bin/env python
2 """Sinusoidal grating calculated in realtime."""
3
4 ############################
5 # Import various modules #
6 ############################
7
8 import VisionEgg
9 VisionEgg.start_default_logging(); VisionEgg.watch_exceptions()
10
11 from VisionEgg.Core import *
12 from VisionEgg.FlowControl import Presentation
13 from VisionEgg.Gratings import *
14
15 #####################################
16 # Initialize OpenGL window/screen #
17 #####################################
18
19 screen = get_default_screen()
20
21 ######################################
22 # Create sinusoidal grating object #
23 ######################################
24
25 stimulus = SinGrating2D(position = ( screen.size[0]/2.0, screen.size[1]/2.0 ),
26 anchor = 'center',
27 size = ( 300.0 , 300.0 ),
28 spatial_freq = 10.0 / screen.size[0], # units of cycles/pixel
29 temporal_freq_hz = 1.0,
30 orientation = 45.0 )
31
32 ###############################################################
33 # Create viewport - intermediary between stimuli and screen #
34 ###############################################################
35
36 viewport = Viewport( screen=screen, stimuli=[stimulus] )
37
38 ########################################
39 # Create presentation object and go! #
40 ########################################
41
42 p = Presentation(go_duration=(5.0,'seconds'),viewports=[viewport])
43 p.go()
target.py
The target demo creates a small target which moves across the screen. The target is spatially anti-aliased by default, meaning that the edges can have colors intermediate between the target and the background to reduce jaggies. This demo also introduces the concept of controllers which allow realtime control of a Vision Egg stimulus through any number of means, including a data acquisition device, a network connection, or software control.
1 #!/usr/bin/env python
2 """A moving target."""
3
4 ############################
5 # Import various modules #
6 ############################
7
8 import VisionEgg
9 VisionEgg.start_default_logging(); VisionEgg.watch_exceptions()
10
11 from VisionEgg.Core import *
12 from VisionEgg.FlowControl import Presentation, Controller, FunctionController
13 from VisionEgg.MoreStimuli import *
14 from math import *
15
16 #################################
17 # Initialize the various bits #
18 #################################
19
20 # Initialize OpenGL graphics screen.
21 screen = get_default_screen()
22
23 # Set the background color to white (RGBA).
24 screen.parameters.bgcolor = (1.0,1.0,1.0,1.0)
25
26 # Create an instance of the Target2D class with appropriate parameters.
27 target = Target2D(size = (25.0,10.0),
28 color = (0.0,0.0,0.0,1.0), # Set the target color (RGBA) black
29 orientation = -45.0)
30
31 # Create a Viewport instance
32 viewport = Viewport(screen=screen, stimuli=[target])
33
34 # Create an instance of the Presentation class. This contains the
35 # the Vision Egg's runtime control abilities.
36 p = Presentation(go_duration=(10.0,'seconds'),viewports=[viewport])
37
38 #######################
39 # Define controller #
40 #######################
41
42 # calculate a few variables we need
43 mid_x = screen.size[0]/2.0
44 mid_y = screen.size[1]/2.0
45 max_vel = min(screen.size[0],screen.size[1]) * 0.4
46
47 # define position as a function of time
48 def get_target_position(t):
49 global mid_x, mid_y, max_vel
50 return ( max_vel*sin(0.1*2.0*pi*t) + mid_x , # x
51 max_vel*sin(0.1*2.0*pi*t) + mid_y ) # y
52
53 # Create an instance of the Controller class
54 target_position_controller = FunctionController(during_go_func=get_target_position)
55
56 #############################################################
57 # Connect the controllers with the variables they control #
58 #############################################################
59
60 p.add_controller(target,'position', target_position_controller )
61
62 #######################
63 # Run the stimulus! #
64 #######################
65
66 p.go()
targetBackground.py
The targetBackground demo illustrates how easy it is to combine multiple stimuli. A spatially anti-aliased small target is drawn as before, but this occurs over a spinning drum.
This demo also introduces more power of OpenGL -- coordinate transforms that occur in realtime via projections. In the Vision Egg, a projection is a parameter of the viewport. In the default case (such as for the small target), the viewport uses pixel coordinates to create an orthographic projection. This allows specification of stimulus position and size in units of pixels. However, a projection also allows other 3D to 2D projections, such as that used to draw the spinning drum. This drum, which is defined in 3D, is drawn using a perspective projection. Because the drum uses a different projection than the small target, it needs its another viewport to link it to the screen.
1 #!/usr/bin/env python
2 """Moving target over a spinning drum."""
3
4 ############################
5 # Import various modules #
6 ############################
7
8 from VisionEgg import *
9 start_default_logging(); watch_exceptions()
10
11 from VisionEgg.Core import *
12 from VisionEgg.FlowControl import Presentation, Controller, FunctionController
13 from VisionEgg.MoreStimuli import *
14 from VisionEgg.Textures import *
15 import os
16 from math import *
17
18 # Initialize OpenGL graphics screen.
19 screen = get_default_screen()
20
21 #######################
22 # Create the target #
23 #######################
24
25 # Create an instance of the Target2D class with appropriate parameters
26 target = Target2D(size = (25.0,10.0),
27 color = (1.0,1.0,1.0,1.0), # Set the target color (RGBA) black
28 orientation = -45.0)
29
30 # Create a viewport for the target
31 target_viewport = Viewport(screen=screen, stimuli=[target])
32
33 #####################
34 # Create the drum #
35 #####################
36
37 # Get a texture
38 filename = os.path.join(config.VISIONEGG_SYSTEM_DIR,"data","panorama.jpg")
39 texture = Texture(filename)
40
41 # Create an instance of SpinningDrum class
42 drum = SpinningDrum(texture=texture,shrink_texture_ok=1)
43
44 # Create a perspective projection for the spinning drum
45 perspective = SimplePerspectiveProjection(fov_x=90.0)
46
47 # Create a viewport with this projection
48 drum_viewport = Viewport(screen=screen,
49 projection=perspective,
50 stimuli=[drum])
51
52 ##################################################
53 # Create an instance of the Presentation class #
54 ##################################################
55
56 # Add target_viewport last so its stimulus is drawn last. This way the
57 # target is always drawn after (on top of) the drum and is therefore
58 # visible.
59 p = Presentation(go_duration=(10.0,'seconds'),viewports=[drum_viewport,target_viewport])
60
61 ########################
62 # Define controllers #
63 ########################
64
65 # calculate a few variables we need
66 mid_x = screen.size[0]/2.0
67 mid_y = screen.size[1]/2.0
68 max_vel = min(screen.size[0],screen.size[1]) * 0.4
69
70 # define target position as a function of time
71 def get_target_position(t):
72 global mid_x, mid_y, max_vel
73 return ( max_vel*sin(0.1*2.0*pi*t) + mid_x , # x
74 max_vel*sin(0.1*2.0*pi*t) + mid_y ) # y
75
76 def get_drum_angle(t):
77 return 50.0*math.cos(0.2*2*math.pi*t)
78
79 # Create instances of the Controller class
80 target_position_controller = FunctionController(during_go_func=get_target_position)
81 drum_angle_controller = FunctionController(during_go_func=get_drum_angle)
82
83 #############################################################
84 # Connect the controllers with the variables they control #
85 #############################################################
86
87 p.add_controller(target,'position', target_position_controller )
88 p.add_controller(drum,'angular_position', drum_angle_controller )
89
90 #######################
91 # Run the stimulus! #
92 #######################
93
94 p.go()
put_pixels.py
The put_pixels demo puts arbitrary array data to the screen. For the sake of simplicity this example uses only solid, uniformly colored arrays. The screen is updated with a new array on every frame, which will reveal tearing artifacts if you do not have buffer swaps synchronized to VSync.
This demo also illustrates an alternative to using the FlowControl module by using pygame's event handling.
1 #!/usr/bin/env python
2 import VisionEgg
3 VisionEgg.start_default_logging(); VisionEgg.watch_exceptions()
4
5 from VisionEgg.Core import *
6 import pygame
7 from pygame.locals import *
8
9 screen = get_default_screen()
10 screen.set( bgcolor = (0.0,0.0,0.0) ) # black (RGB)
11
12 white_data = (Numeric.ones((100,200,3))*255).astype(Numeric.UnsignedInt8)
13 red_data = white_data.copy()
14 red_data[:,:,1:] = 0 # zero non-red channels
15
16 blue_data = white_data.copy()
17 blue_data[:,:,:-1] = 0 # zero non-blue channels
18
19 frame_timer = FrameTimer() # start frame counter/timer
20 count = 0
21 quit_now = 0
22
23 # This style of main loop is an alternative to using the
24 # VisionEgg.FlowControl module.
25 while not quit_now:
26 for event in pygame.event.get():
27 if event.type in (QUIT,KEYDOWN,MOUSEBUTTONDOWN):
28 quit_now = 1
29 screen.clear()
30 count = (count+1) % 3
31 if count == 0:
32 pixels = white_data
33 elif count == 1:
34 pixels = red_data
35 elif count == 2:
36 pixels = blue_data
37 screen.put_pixels(pixels=pixels,
38 position=(screen.size[0]/2.0,screen.size[1]/2.0),
39 anchor="center")
40 swap_buffers() # display what we've drawn
41 frame_timer.tick() # register frame draw with timer
42 frame_timer.log_histogram()



