示例#1
0
class Line(DisplayListStimulus):
    """  A line.
    

    Parameters
    ==========
    anti_aliasing -- (Boolean)
                     Default: True
    color         -- color (AnyOf(Sequence3 of Real or Sequence4 of Real))
                     Default: (1.0, 1.0, 1.0)
    on            -- draw? (Boolean)
                     Default: True
    position      -- position in eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real))
                     Default: (320.0, 240.0)
    end           -- position in eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real))
                     Default: (420.0, 240.0)
    """

    parameters_and_defaults = VisionEgg.ParameterDefinition({
        'on': (True, ve_types.Boolean, 'draw?'),
        'color': ((1.0, 1.0, 1.0),
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real)), 'color'),
        'anti_aliasing': (True, ve_types.Boolean),
        'position': (
            (320.0, 240.0),  # in eye coordinates
            ve_types.AnyOf(ve_types.Sequence2(ve_types.Real),
                           ve_types.Sequence3(ve_types.Real),
                           ve_types.Sequence4(ve_types.Real)),
            'position in eye coordinates'),
        'end': (
            (420.0, 240.0),  # in eye coordinates
            ve_types.AnyOf(ve_types.Sequence2(ve_types.Real),
                           ve_types.Sequence3(ve_types.Real),
                           ve_types.Sequence4(ve_types.Real)),
            'end point in eye coordinates'),
        'width': (1., ve_types.Real, 'line width'),
    })
    __slots__ = VisionEgg.Core.Stimulus.__slots__ + ('_gave_alpha_warning', )

    def __init__(self, **kw):
        DisplayListStimulus.__init__(self, **kw)
        self._gave_alpha_warning = 0

    def _draw(self):
        p = self.parameters
        gl.glDisable(gl.GL_DEPTH_TEST)
        gl.glDisable(gl.GL_TEXTURE_2D)
        gl.glDisable(gl.GL_BLEND)
        gl.glColor(p.color)
        if p.anti_aliasing:
            gl.glEnable(gl.GL_LINE_SMOOTH)
        gl.glLineWidth(p.width)
        gl.glBegin(gl.GL_LINES)
        gl.glVertex(p.position)
        gl.glVertex(p.end)
        gl.glEnd()
        gl.glDisable(gl.GL_LINE_SMOOTH)
示例#2
0
    class GlutTextBase(VisionEgg.Core.Stimulus):
        """DEPRECATED. Base class: don't instantiate this class directly.

        Base class that defines the common interface between the
        other glut-based text stimuli.

        Parameters
        ==========
        color     -- (AnyOf(Sequence3 of Real or Sequence4 of Real))
                     Default: (1.0, 1.0, 1.0)
        lowerleft -- (Sequence2 of Real)
                     Default: (320, 240)
        on        -- (Boolean)
                     Default: True
        text      -- (String)
                     Default: the string to display
        """

        parameters_and_defaults = {
            'on': (True, ve_types.Boolean),
            'color': ((1.0, 1.0, 1.0),
                      ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                     ve_types.Sequence4(ve_types.Real))),
            'lowerleft': ((320, 240), ve_types.Sequence2(ve_types.Real)),
            'text': ('the string to display', ve_types.String)
        }

        def __init__(self, **kw):
            if not hasattr(VisionEgg.config, "_GAVE_GLUT_TEXT_DEPRECATION"):
                logger = logging.getLogger('VisionEgg.Text')
                logger.warning("Using GlutTextBase class.  This will be "
                               "removed in a future release. Use "
                               "VisionEgg.Text.Text instead.")
                VisionEgg.config._GAVE_GLUT_TEXT_DEPRECATION = 1
                VisionEgg.Core.Stimulus.__init__(self, **kw)
示例#3
0
class GlutTextBase(VisionEgg.Core.Stimulus):
    """DEPRECATED. Base class: don't instantiate this class directly.

    Base class that defines the common interface between the
    other glut-based text stimuli.

    Parameters
    ==========
    color     -- (AnyOf(Sequence3 of Real or Sequence4 of Real))
                 Default: (1.0, 1.0, 1.0)
    lowerleft -- (Sequence2 of Real)
                 Default: (320, 240)
    on        -- (Boolean)
                 Default: True
    text      -- (String)
                 Default: the string to display
    """

    parameters_and_defaults = {
        'on': (True, ve_types.Boolean),
        'color': ((1.0, 1.0, 1.0),
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real))),
        'lowerleft': ((320, 240), ve_types.Sequence2(ve_types.Real)),
        'text': ('the string to display', ve_types.String)
    }

    def __init__(self, **kw):
        VisionEgg.Core.Stimulus.__init__(self, **kw)
示例#4
0
    class Foo(ClassWithParameters):
        parameters_and_defaults = {
            'position': ((320, 240), vtype.Sequence2(vtype.Real)),
            'numCols': (15, vtype.UnsignedInteger),
            'numRows': (15, vtype.UnsignedInteger),
            'dotSize': (10, vtype.UnsignedInteger),
            'scale': (50, vtype.Real),
            'angle': (0, vtype.Real),
            'gamma': (85, vtype.Real),
            'aspectRatio': (1, vtype.Real),
            'apertureSize': (300, vtype.Real),
            'perturb': (False, vtype.Boolean),
            'lighting': (False, vtype.Boolean),
            'lightPos': ((100, 100, -100), vtype.Sequence3(vtype.Real)),
            'foreground': ((0, 0, 0, 1), vtype.Sequence4(vtype.Real)),
            'background': ((0.3, 0.3, 0.3, 1), vtype.Sequence4(vtype.Real))
        }

        def __init__(self, **kw):
            ClassWithParameters.__init__(self, **kw)

        def __str__(self):
            return 'Foo'
示例#5
0
class SinGrating3D(LuminanceGratingCommon):
    """Sine wave grating stimulus texture mapped onto quad in 3D

    This is a general-purpose, realtime sine-wave luminace grating
    generator. This 3D version doesn't support an orientation
    parameter.  This could be implemented, but for now should be done
    by orienting the quad in 3D.

    Parameters
    ==========
    bit_depth                   -- precision with which grating is calculated and sent to OpenGL (UnsignedInteger)
                                   Inherited from LuminanceGratingCommon
                                   Default: 8
    color1                      -- (AnyOf(Sequence3 of Real or Sequence4 of Real))
                                   Default: (1.0, 1.0, 1.0)
    color2                      -- optional color with which to perform interpolation with color1 in RGB space (AnyOf(Sequence3 of Real or Sequence4 of Real))
                                   Default: (determined at runtime)
    contrast                    -- (Real)
                                   Default: 1.0
    depth                       -- (Real)
                                   Default: (determined at runtime)
    depth_test                  -- perform depth test? (Boolean)
                                   Default: True
    ignore_time                 -- (Boolean)
                                   Default: False
    lowerleft                   -- vertex position (units: eye coordinates) (AnyOf(Sequence3 of Real or Sequence4 of Real))
                                   Default: (0.0, 0.0, -1.0)
    lowerright                  -- vertex position (units: eye coordinates) (AnyOf(Sequence3 of Real or Sequence4 of Real))
                                   Default: (1.0, 0.0, -1.0)
    mask                        -- optional masking function (Instance of <class 'VisionEgg.Textures.Mask2D'>)
                                   Default: (determined at runtime)
    max_alpha                   -- (Real)
                                   Default: 1.0
    num_samples                 -- (UnsignedInteger)
                                   Default: 512
    on                          -- draw stimulus? (Boolean)
                                   Default: True
    pedestal                    -- (Real)
                                   Default: 0.5
    phase_at_t0                 -- (Real)
                                   Default: 0.0
    polygon_offset_enabled      -- perform polygon offset? (Boolean)
                                   Default: False
    polygon_offset_factor       -- polygon factor (Real)
                                   Default: 1.0
    polygon_offset_units        -- polygon units (Real)
                                   Default: 1.0
    recalculate_phase_tolerance -- (Real)
                                   Default: (determined at runtime)
    size                        -- defines coordinate size of grating (in eye coordinates) (Sequence2 of Real)
                                   Default: (1.0, 1.0)
    spatial_freq                -- frequency defined relative to coordinates defined in size parameter (units; cycles/eye_coord_unit) (Real)
                                   Default: 4.0
    t0_time_sec_absolute        -- (Real)
                                   Default: (determined at runtime)
    temporal_freq_hz            -- (Real)
                                   Default: 5.0
    upperleft                   -- vertex position (units: eye coordinates) (AnyOf(Sequence3 of Real or Sequence4 of Real))
                                   Default: (0.0, 1.0, -1.0)
    upperright                  -- vertex position (units: eye coordinates) (AnyOf(Sequence3 of Real or Sequence4 of Real))
                                   Default: (1.0, 1.0, -1.0)
    """

    parameters_and_defaults = VisionEgg.ParameterDefinition({
        'on':(True,
              ve_types.Boolean,
              "draw stimulus?"),
        'mask':(None, # allows window onto otherwise (tilted) rectangular grating
                ve_types.Instance(VisionEgg.Textures.Mask2D),
                "optional masking function"),
        'contrast':(1.0,
                    ve_types.Real),
        'pedestal':(0.5,
                    ve_types.Real),
        'depth':(None, # if not None, turns on depth testing and allows for occlusion
                 ve_types.Real),
        'size':((1.0,1.0), # in eye coordinates
                ve_types.Sequence2(ve_types.Real),
                "defines coordinate size of grating (in eye coordinates)"),
        'spatial_freq':(4.0, # cycles/eye coord units
                        ve_types.Real,
                        "frequency defined relative to coordinates defined in size parameter (units; cycles/eye_coord_unit)"),
        'temporal_freq_hz':(5.0, # hz
                            ve_types.Real),
        't0_time_sec_absolute':(None, # Will be assigned during first call to draw()
                                ve_types.Real),
        'ignore_time':(False, # ignore temporal frequency variable - allow control purely with phase_at_t0
                       ve_types.Boolean),
        'phase_at_t0':(0.0, # degrees [0.0-360.0]
                       ve_types.Real),
        'num_samples':(512, # number of spatial samples, should be a power of 2
                       ve_types.UnsignedInteger),
        'max_alpha':(1.0, # controls "opacity": 1.0 = completely opaque, 0.0 = completely transparent
                     ve_types.Real),
        'color1':((1.0, 1.0, 1.0), # alpha is ignored (if given) -- use max_alpha parameter
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real))),
        'color2':(None, # perform interpolation with color1 in RGB space.
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real)),
                  "optional color with which to perform interpolation with color1 in RGB space"),
        'recalculate_phase_tolerance':(None, # only recalculate texture when phase is changed by more than this amount, None for always recalculate. (Saves time.)
                                       ve_types.Real),
        'depth_test':(True,
                      ve_types.Boolean,
                      "perform depth test?"),
        'lowerleft':((0.0,0.0,-1.0), # in eye coordinates
                     ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                    ve_types.Sequence4(ve_types.Real)),
                     "vertex position (units: eye coordinates)"),
        'lowerright':((1.0,0.0,-1.0), # in eye coordinates
                      ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                     ve_types.Sequence4(ve_types.Real)),
                      "vertex position (units: eye coordinates)"),
        'upperleft':((0.0,1.0,-1.0), # in eye coordinates
                     ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                    ve_types.Sequence4(ve_types.Real)),
                     "vertex position (units: eye coordinates)"),
        'upperright':((1.0,1.0,-1.0), # in eye coordinates
                      ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                     ve_types.Sequence4(ve_types.Real)),
                      "vertex position (units: eye coordinates)"),
        'polygon_offset_enabled':(False,
                                  ve_types.Boolean,
                                  "perform polygon offset?"),
        'polygon_offset_factor':(1.0,
                                 ve_types.Real,
                                 "polygon factor"),
        'polygon_offset_units':(1.0,
                                ve_types.Real,
                                "polygon units"),
        })

    __slots__ = (
        '_texture_object_id',
        '_last_phase',
        )

    def __init__(self,**kw):
        LuminanceGratingCommon.__init__(self,**kw)

        p = self.parameters # shorthand

        self._texture_object_id = gl.glGenTextures(1)
        if p.mask:
            gl.glActiveTextureARB(gl.GL_TEXTURE0_ARB)
        gl.glBindTexture(gl.GL_TEXTURE_1D,self._texture_object_id)

        # Do error-checking on texture to make sure it will load
        max_dim = gl.glGetIntegerv(gl.GL_MAX_TEXTURE_SIZE)
        if p.num_samples > max_dim:
            raise NumSamplesTooLargeError("Grating num_samples too large for video system.\nOpenGL reports maximum size of %d"%(max_dim,))

        self.calculate_bit_depth_dependencies()

        w = p.size[0]
        inc = w/float(p.num_samples)
        phase = 0.0 # this data won't get used - don't care about phase
        self._last_phase = phase
        floating_point_sin = numpy.sin(2.0*math.pi*p.spatial_freq*numpy.arange(0.0,w,inc,dtype=numpy.float)+(phase/180.0*math.pi))*0.5*p.contrast+p.pedestal
        floating_point_sin = numpy.clip(floating_point_sin,0.0,1.0) # allow square wave generation if contrast > 1
        texel_data = (floating_point_sin*self.max_int_val).astype(self.numpy_dtype).tostring()

        # Because the MAX_TEXTURE_SIZE method is insensitive to the current
        # state of the video system, another check must be done using
        # "proxy textures".
        gl.glTexImage1D(gl.GL_PROXY_TEXTURE_1D,            # target
                        0,                                 # level
                        self.gl_internal_format,           # video RAM internal format
                        p.num_samples,                     # width
                        0,                                 # border
                        self.format,                       # format of texel data
                        self.gl_type,                      # type of texel data
                        texel_data)                        # texel data (irrelevant for proxy)
        if gl.glGetTexLevelParameteriv(gl.GL_PROXY_TEXTURE_1D, # Need PyOpenGL >= 2.0
                                       0,
                                       gl.GL_TEXTURE_WIDTH) == 0:
            raise NumSamplesTooLargeError("Grating num_samples is too wide for your video system!")

        # If we got here, it worked and we can load the texture for real.
        gl.glTexImage1D(gl.GL_TEXTURE_1D,                  # target
                        0,                                 # level
                        self.gl_internal_format,           # video RAM internal format
                        p.num_samples,                     # width
                        0,                                 # border
                        self.format,                       # format of texel data
                        self.gl_type,                      # type of texel data
                        texel_data)                        # texel data

        # Set texture object defaults
        gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_WRAP_S,gl.GL_CLAMP_TO_EDGE)
        gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_WRAP_T,gl.GL_CLAMP_TO_EDGE)
        gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_MAG_FILTER,gl.GL_LINEAR)
        gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_MIN_FILTER,gl.GL_LINEAR)

        if p.color2 is not None:
            if VisionEgg.Core.gl_renderer == 'ATi Rage 128 Pro OpenGL Engine' and VisionEgg.Core.gl_version == '1.1 ATI-1.2.22':
                logger = logging.getLogger('VisionEgg.Gratings')
                logger.warning("Your video card and driver have known "
                               "bugs which prevent them from rendering "
                               "color gratings properly.")

    def __del__(self):
        gl.glDeleteTextures( [self._texture_object_id] )

    def draw(self):
        p = self.parameters # shorthand
        if p.on:
            if p.mask:
                gl.glActiveTextureARB(gl.GL_TEXTURE0_ARB)
            if p.depth_test:
                gl.glEnable(gl.GL_DEPTH_TEST)
            else:
                gl.glDisable(gl.GL_DEPTH_TEST)
            if p.polygon_offset_enabled:
                gl.glEnable(gl.GL_POLYGON_OFFSET_EXT)
                gl.glPolygonOffset(p.polygon_offset_factor, p.polygon_offset_units)
            gl.glBindTexture(gl.GL_TEXTURE_1D,self._texture_object_id)
            gl.glEnable(gl.GL_TEXTURE_1D)
            gl.glDisable(gl.GL_TEXTURE_2D)
            if p.bit_depth != self.cached_bit_depth:
                self.calculate_bit_depth_dependencies()

            # allow max_alpha value to control blending
            gl.glEnable( gl.GL_BLEND )
            gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA )

            if p.color2:
                gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_BLEND)
                gl.glTexEnvfv(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_COLOR, p.color2)
                ## alpha is ignored because the texture base internal format is luminance
            else:
                gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE)

            if p.t0_time_sec_absolute is None and not p.ignore_time:
                p.t0_time_sec_absolute = VisionEgg.time_func()

            w = p.size[0]
            inc = w/float(p.num_samples)
            if p.ignore_time:
                phase = p.phase_at_t0
            else:
                t_var = VisionEgg.time_func() - p.t0_time_sec_absolute
                phase = t_var*p.temporal_freq_hz*-360.0 + p.phase_at_t0
            if p.recalculate_phase_tolerance is None or abs(self._last_phase - phase) > p.recalculate_phase_tolerance:
                self._last_phase = phase # we're re-drawing the phase at this angle
                floating_point_sin = numpy.sin(2.0*math.pi*p.spatial_freq*numpy.arange(0.0,w,inc,dtype=numpy.float)+(phase/180.0*math.pi))*0.5*p.contrast+p.pedestal
                floating_point_sin = numpy.clip(floating_point_sin,0.0,1.0) # allow square wave generation if contrast > 1
                texel_data = (floating_point_sin*self.max_int_val).astype(self.numpy_dtype).tostring()

                gl.glTexSubImage1D(gl.GL_TEXTURE_1D, # target
                                   0,                # level
                                   0,                # x offset
                                   p.num_samples,    # width
                                   self.format,      # format of new texel data
                                   self.gl_type,     # type of new texel data
                                   texel_data)       # new texel data

            # in the case of only color1,
            # the texel data multiplies color1 to produce a color

            # with color2,
            # the texel data linearly interpolates between color1 and color2

            gl.glColor4f(p.color1[0],p.color1[1],p.color1[2],p.max_alpha)

            if p.mask:
                p.mask.draw_masked_quad_3d(0.0,1.0,0.0,1.0, # for texture coordinates
                                           p.lowerleft,p.lowerright,p.upperright,p.upperleft)
            else:
                # draw unmasked quad
                gl.glBegin(gl.GL_QUADS)

                gl.glTexCoord2f(0.0,0.0)
                gl.glVertex(*p.lowerleft)

                gl.glTexCoord2f(1.0,0.0)
                gl.glVertex(*p.lowerright)

                gl.glTexCoord2f(1.0,1.0)
                gl.glVertex(*p.upperright)

                gl.glTexCoord2f(0.0,1.0)
                gl.glVertex(*p.upperleft)
                gl.glEnd() # GL_QUADS

            gl.glDisable(gl.GL_TEXTURE_1D)
            if p.polygon_offset_enabled:
                gl.glDisable(gl.GL_POLYGON_OFFSET_EXT)
示例#6
0
class SinGrating2D(LuminanceGratingCommon):
    """Sine wave grating stimulus

    This is a general-purpose, realtime sine-wave luminace grating
    generator. To acheive an arbitrary orientation, this class rotates
    a textured quad.  To draw a grating with sides that always remain
    horizontal and vertical, draw a large grating in a small viewport.
    (The viewport will clip anything beyond its edges.)

    Parameters
    ==========
    anchor                      -- specifies how position parameter is interpreted (String)
                                   Default: center
    bit_depth                   -- precision with which grating is calculated and sent to OpenGL (UnsignedInteger)
                                   Inherited from LuminanceGratingCommon
                                   Default: 8
    color1                      -- (AnyOf(Sequence3 of Real or Sequence4 of Real))
                                   Default: (1.0, 1.0, 1.0)
    color2                      -- optional color with which to perform interpolation with color1 in RGB space (AnyOf(Sequence3 of Real or Sequence4 of Real))
                                   Default: (determined at runtime)
    contrast                    -- (Real)
                                   Default: 1.0
    depth                       -- (Real)
                                   Default: (determined at runtime)
    ignore_time                 -- (Boolean)
                                   Default: False
    mask                        -- optional masking function (Instance of <class 'VisionEgg.Textures.Mask2D'>)
                                   Default: (determined at runtime)
    max_alpha                   -- (Real)
                                   Default: 1.0
    num_samples                 -- (UnsignedInteger)
                                   Default: 512
    on                          -- draw stimulus? (Boolean)
                                   Default: True
    orientation                 -- (Real)
                                   Default: 0.0
    pedestal                    -- (Real)
                                   Default: 0.5
    phase_at_t0                 -- (Real)
                                   Default: 0.0
    position                    -- (units: eye coordinates) (Sequence2 of Real)
                                   Default: (320.0, 240.0)
    recalculate_phase_tolerance -- (Real)
                                   Default: (determined at runtime)
    size                        -- defines coordinate size of grating (in eye coordinates) (Sequence2 of Real)
                                   Default: (640.0, 480.0)
    spatial_freq                -- frequency defined relative to coordinates defined in size parameter (units: cycles/eye_coord_unit) (Real)
                                   Default: 0.0078125
    t0_time_sec_absolute        -- (Real)
                                   Default: (determined at runtime)
    temporal_freq_hz            -- (Real)
                                   Default: 5.0
    """

    parameters_and_defaults = VisionEgg.ParameterDefinition({
        'on':(True,
              ve_types.Boolean,
              "draw stimulus?"),
        'mask':(None, # allows window onto otherwise (tilted) rectangular grating
                ve_types.Instance(VisionEgg.Textures.Mask2D),
                "optional masking function"),
        'contrast':(1.0,
                    ve_types.Real),
        'pedestal':(0.5,
                    ve_types.Real),
        'position':((320.0,240.0), # in eye coordinates
                    ve_types.Sequence2(ve_types.Real),
                    "(units: eye coordinates)"),
        'anchor':('center',
                  ve_types.String,
                  "specifies how position parameter is interpreted"),
        'depth':(None, # if not None, turns on depth testing and allows for occlusion
                 ve_types.Real),
        'size':((640.0,480.0),
                ve_types.Sequence2(ve_types.Real),
                "defines coordinate size of grating (in eye coordinates)",
                ),
        'spatial_freq':(1.0/128.0, # cycles/eye coord units
                        ve_types.Real,
                        "frequency defined relative to coordinates defined in size parameter (units: cycles/eye_coord_unit)",
                        ),
        'temporal_freq_hz':(5.0, # hz
                            ve_types.Real),
        't0_time_sec_absolute':(None, # Will be assigned during first call to draw()
                                ve_types.Real),
        'ignore_time':(False, # ignore temporal frequency variable - allow control purely with phase_at_t0
                       ve_types.Boolean),
        'phase_at_t0':(0.0, # degrees [0.0-360.0]
                       ve_types.Real),
        'orientation':(0.0, # 0=right, 90=up
                       ve_types.Real),
        'num_samples':(512, # number of spatial samples, should be a power of 2
                       ve_types.UnsignedInteger),
        'max_alpha':(1.0, # controls "opacity": 1.0 = completely opaque, 0.0 = completely transparent
                     ve_types.Real),
        'color1':((1.0, 1.0, 1.0), # alpha is ignored (if given) -- use max_alpha parameter
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real))),
        'color2':(None, # perform interpolation with color1 in RGB space.
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real)),
                  "optional color with which to perform interpolation with color1 in RGB space"),
        'recalculate_phase_tolerance':(None, # only recalculate texture when phase is changed by more than this amount, None for always recalculate. (Saves time.)
                                       ve_types.Real),
        })

    __slots__ = (
        '_texture_object_id',
        '_last_phase',
        )

    def __init__(self,**kw):
        LuminanceGratingCommon.__init__(self,**kw)

        p = self.parameters # shorthand

        self._texture_object_id = gl.glGenTextures(1)
        if p.mask:
            gl.glActiveTextureARB(gl.GL_TEXTURE0_ARB)
        gl.glBindTexture(gl.GL_TEXTURE_1D,self._texture_object_id)

        # Do error-checking on texture to make sure it will load
        max_dim = gl.glGetIntegerv(gl.GL_MAX_TEXTURE_SIZE)
        if p.num_samples > max_dim:
            raise NumSamplesTooLargeError("Grating num_samples too large for video system.\nOpenGL reports maximum size of %d"%(max_dim,))

        self.calculate_bit_depth_dependencies()

        w = p.size[0]
        inc = w/float(p.num_samples)
        phase = 0.0 # this data won't get used - don't care about phase
        self._last_phase = phase
        floating_point_sin = numpy.sin(2.0*math.pi*p.spatial_freq*numpy.arange(0.0,w,inc,dtype=numpy.float)+(phase/180.0*math.pi))*0.5*p.contrast+p.pedestal
        floating_point_sin = numpy.clip(floating_point_sin,0.0,1.0) # allow square wave generation if contrast > 1
        texel_data = (floating_point_sin*self.max_int_val).astype(self.numpy_dtype).tostring()

        # Because the MAX_TEXTURE_SIZE method is insensitive to the current
        # state of the video system, another check must be done using
        # "proxy textures".
        gl.glTexImage1D(gl.GL_PROXY_TEXTURE_1D,            # target
                        0,                                 # level
                        self.gl_internal_format,           # video RAM internal format
                        p.num_samples,                     # width
                        0,                                 # border
                        self.format,                       # format of texel data
                        self.gl_type,                      # type of texel data
                        texel_data)                        # texel data (irrelevant for proxy)
        if gl.glGetTexLevelParameteriv(gl.GL_PROXY_TEXTURE_1D, # Need PyOpenGL >= 2.0
                                       0,
                                       gl.GL_TEXTURE_WIDTH) == 0:
            raise NumSamplesTooLargeError("Grating num_samples is too wide for your video system!")

        # If we got here, it worked and we can load the texture for real.
        gl.glTexImage1D(gl.GL_TEXTURE_1D,                  # target
                        0,                                 # level
                        self.gl_internal_format,           # video RAM internal format
                        p.num_samples,                     # width
                        0,                                 # border
                        self.format,                       # format of texel data
                        self.gl_type,                      # type of texel data
                        texel_data)                        # texel data

        # Set texture object defaults
        gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_WRAP_S,gl.GL_CLAMP_TO_EDGE)
        gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_WRAP_T,gl.GL_CLAMP_TO_EDGE)
        gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_MAG_FILTER,gl.GL_LINEAR)
        gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_MIN_FILTER,gl.GL_LINEAR)

        if p.color2 is not None:
            if VisionEgg.Core.gl_renderer == 'ATi Rage 128 Pro OpenGL Engine' and VisionEgg.Core.gl_version == '1.1 ATI-1.2.22':
                logger = logging.getLogger('VisionEgg.Gratings')
                logger.warning("Your video card and driver have known "
                               "bugs which prevent them from rendering "
                               "color gratings properly.")

    def __del__(self):
        gl.glDeleteTextures( [self._texture_object_id] )

    def draw(self):
        p = self.parameters # shorthand
        if p.on:
            # calculate center
            center = VisionEgg._get_center(p.position,p.anchor,p.size)
            if p.mask:
                gl.glActiveTextureARB(gl.GL_TEXTURE0_ARB)
            gl.glBindTexture(gl.GL_TEXTURE_1D,self._texture_object_id)

            gl.glEnable(gl.GL_TEXTURE_1D)
            gl.glDisable(gl.GL_TEXTURE_2D)
            if p.bit_depth != self.cached_bit_depth:
                self.calculate_bit_depth_dependencies()

            # Clear the modeview matrix
            gl.glMatrixMode(gl.GL_MODELVIEW)
            gl.glPushMatrix()

            # Rotate about the center of the texture
            gl.glTranslate(center[0],
                           center[1],
                           0)
            gl.glRotate(p.orientation,0,0,1)

            if p.depth is None:
                gl.glDisable(gl.GL_DEPTH_TEST)
                depth = 0.0
            else:
                gl.glEnable(gl.GL_DEPTH_TEST)
                depth = p.depth

            # allow max_alpha value to control blending
            gl.glEnable( gl.GL_BLEND )
            gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA )

            if p.color2:
                gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_BLEND)
                gl.glTexEnvfv(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_COLOR, p.color2)
                ## alpha is ignored because the texture base internal format is luminance
            else:
                gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE)

            if p.t0_time_sec_absolute is None and not p.ignore_time:
                p.t0_time_sec_absolute = VisionEgg.time_func()

            w = p.size[0]
            inc = w/float(p.num_samples)
            if p.ignore_time:
                phase = p.phase_at_t0
            else:
                t_var = VisionEgg.time_func() - p.t0_time_sec_absolute
                phase = t_var*p.temporal_freq_hz*-360.0 + p.phase_at_t0
            if p.recalculate_phase_tolerance is None or abs(self._last_phase - phase) > p.recalculate_phase_tolerance:
                self._last_phase = phase # we're re-drawing the phase at this angle
                floating_point_sin = numpy.sin(2.0*math.pi*p.spatial_freq*numpy.arange(0.0,w,inc,dtype=numpy.float)+(phase/180.0*math.pi))*0.5*p.contrast+p.pedestal
                floating_point_sin = numpy.clip(floating_point_sin,0.0,1.0) # allow square wave generation if contrast > 1
                texel_data = (floating_point_sin*self.max_int_val).astype(self.numpy_dtype)
                # PyOpenGL 2.0.1.09 has a bug, so use our own wrapper
                _vegl.veglTexSubImage1D(gl.GL_TEXTURE_1D, # target
                                        0,                # level
                                        0,                # x offset
                                        p.num_samples,    # width
                                        self.format,      # format of new texel data
                                        self.gl_type,     # type of new texel data
                                        texel_data)       # new texel data
                if 0:
                    compare_array = numpy.empty(texel_data.shape,dtype=texel_data.dtype)
                    pixels = _vegl.veglGetTexImage(gl.GL_TEXTURE_1D, # target
                                                   0, # level
                                                   self.format, # format
                                                   self.gl_type, # type
                                                   compare_array)
                    assert numpy.allclose( compare_array, texel_data )

            h_w = p.size[0]/2.0
            h_h = p.size[1]/2.0

            l = -h_w
            r = h_w
            b = -h_h
            t = h_h

            # in the case of only color1,
            # the texel data multiplies color1 to produce a color

            # with color2,
            # the texel data linearly interpolates between color1 and color2

            gl.glColor4f(p.color1[0],p.color1[1],p.color1[2],p.max_alpha)

            if p.mask:
                p.mask.draw_masked_quad(0.0,1.0,0.0,1.0, # l,r,b,t for texture coordinates
                                        l,r,b,t, # l,r,b,t in eye coordinates
                                        depth ) # also in eye coordinates
            else:
                # draw unmasked quad
                gl.glBegin(gl.GL_QUADS)

                gl.glTexCoord2f(0.0,0.0)
                gl.glVertex3f(l,b,depth)

                gl.glTexCoord2f(1.0,0.0)
                gl.glVertex3f(r,b,depth)

                gl.glTexCoord2f(1.0,1.0)
                gl.glVertex3f(r,t,depth)

                gl.glTexCoord2f(0.0,1.0)
                gl.glVertex3f(l,t,depth)
                gl.glEnd() # GL_QUADS

            gl.glDisable(gl.GL_TEXTURE_1D)
            gl.glPopMatrix()
示例#7
0
class DotArea2D(VisionEgg.Core.Stimulus):
    """Random dots of constant velocity

    Every dot has the same velocity. Some fraction of the dots all
    move in the one direction, while the rest move in random
    directions. Dots wrap around edges. Each dot has a lifespan.

    This is just one example of the endless variations on drawing random dots.

    Parameters
    ==========
    anchor                  -- (String)
                               Default: center
    anti_aliasing           -- (Boolean)
                               Default: True
    color                   -- (AnyOf(Sequence3 of Real or Sequence4 of Real))
                               Default: (1.0, 1.0, 1.0)
    depth                   -- (Real)
                               Default: (determined at runtime)
    dot_lifespan_sec        -- (Real)
                               Default: 5.0
    dot_size                -- (Real)
                               Default: 4.0
    on                      -- (Boolean)
                               Default: True
    position                -- (Sequence2 of Real)
                               Default: (320.0, 240.0)
    signal_direction_deg    -- (Real)
                               Default: 90.0
    signal_fraction         -- (Real)
                               Default: 0.5
    size                    -- (Sequence2 of Real)
                               Default: (300.0, 300.0)
    velocity_pixels_per_sec -- (Real)
                               Default: 10.0

    Constant Parameters
    ===================
    num_dots -- (UnsignedInteger)
                Default: 100
    """

    parameters_and_defaults = {
        'on': (True, ve_types.Boolean),
        'position': (
            (320.0, 240.0),  # in eye coordinates
            ve_types.Sequence2(ve_types.Real)),
        'anchor': ('center', ve_types.String),
        'size': (
            (300.0, 300.0),  # in eye coordinates
            ve_types.Sequence2(ve_types.Real)),
        'signal_fraction': (0.5, ve_types.Real),
        'signal_direction_deg': (90.0, ve_types.Real),
        'velocity_pixels_per_sec': (10.0, ve_types.Real),
        'dot_lifespan_sec': (5.0, ve_types.Real),
        'color': ((1.0, 1.0, 1.0),
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real))),
        'dot_size': (
            4.0,  # pixels
            ve_types.Real),
        'anti_aliasing': (True, ve_types.Boolean),
        'depth': (
            None,  # set for depth testing
            ve_types.Real),
        'center': (
            None,  # DEPRECATED -- don't use
            ve_types.Sequence2(ve_types.Real),
            "",
            VisionEgg.ParameterDefinition.DEPRECATED),
    }

    constant_parameters_and_defaults = {
        'num_dots': (100, ve_types.UnsignedInteger),
    }

    __slots__ = (
        'x_positions',
        'y_positions',
        'random_directions_radians',
        'last_time_sec',
        'start_times_sec',
        '_gave_alpha_warning',
    )

    def __init__(self, **kw):
        VisionEgg.Core.Stimulus.__init__(self, **kw)
        # store positions normalized between 0 and 1 so that re-sizing is ok
        num_dots = self.constant_parameters.num_dots  # shorthand
        self.x_positions = RandomArray.uniform(0.0, 1.0, (num_dots, ))
        self.y_positions = RandomArray.uniform(0.0, 1.0, (num_dots, ))
        self.random_directions_radians = RandomArray.uniform(
            0.0, 2 * math.pi, (num_dots, ))
        self.last_time_sec = VisionEgg.time_func()
        self.start_times_sec = None  # setup variable, assign later
        self._gave_alpha_warning = 0

    def draw(self):
        # XXX This method is not speed-optimized. I just wrote it to
        # get the job done. (Nonetheless, it seems faster than the C
        # version commented out above.)

        p = self.parameters  # shorthand
        if p.center is not None:
            if not hasattr(VisionEgg.config, "_GAVE_CENTER_DEPRECATION"):
                logger = logging.getLogger('VisionEgg.Dots')
                logger.warning("Specifying DotArea2D by deprecated "
                               "'center' parameter deprecated.  Use "
                               "'position' parameter instead.  (Allows "
                               "use of 'anchor' parameter to set to "
                               "other values.)")
                VisionEgg.config._GAVE_CENTER_DEPRECATION = 1
            p.anchor = 'center'
            p.position = p.center[0], p.center[
                1]  # copy values (don't copy ref to tuple)
        if p.on:
            # calculate center
            center = VisionEgg._get_center(p.position, p.anchor, p.size)

            if p.anti_aliasing:
                if len(p.color) == 4 and not self._gave_alpha_warning:
                    if p.color[3] != 1.0:
                        logger = logging.getLogger('VisionEgg.Dots')
                        logger.warning("The parameter anti_aliasing is "
                                       "set to true in the DotArea2D "
                                       "stimulus class, but the color "
                                       "parameter specifies an alpha "
                                       "value other than 1.0.  To "
                                       "acheive the best anti-aliasing, "
                                       "ensure that the alpha value for "
                                       "the color parameter is 1.0.")
                        self._gave_alpha_warning = 1
                gl.glEnable(gl.GL_POINT_SMOOTH)
                # allow max_alpha value to control blending
                gl.glEnable(gl.GL_BLEND)
                gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
            else:
                gl.glDisable(gl.GL_BLEND)

            now_sec = VisionEgg.time_func()
            if self.start_times_sec is not None:
                # compute extinct dots and generate new positions
                replace_indices = Numeric.nonzero(
                    Numeric.greater(now_sec - self.start_times_sec,
                                    p.dot_lifespan_sec))
                Numeric.put(self.start_times_sec, replace_indices, now_sec)

                new_x_positions = RandomArray.uniform(0.0, 1.0,
                                                      (len(replace_indices), ))
                Numeric.put(self.x_positions, replace_indices, new_x_positions)

                new_y_positions = RandomArray.uniform(0.0, 1.0,
                                                      (len(replace_indices), ))
                Numeric.put(self.y_positions, replace_indices, new_y_positions)

                new_random_directions_radians = RandomArray.uniform(
                    0.0, 2 * math.pi, (len(replace_indices), ))
                Numeric.put(self.random_directions_radians, replace_indices,
                            new_random_directions_radians)
            else:
                # initialize dot extinction values to random (uniform) distribution
                self.start_times_sec = RandomArray.uniform(
                    now_sec - p.dot_lifespan_sec, now_sec,
                    (self.constant_parameters.num_dots, ))

            signal_num_dots = int(
                round(p.signal_fraction * self.constant_parameters.num_dots))
            time_delta_sec = now_sec - self.last_time_sec
            self.last_time_sec = now_sec  # reset for next loop
            x_increment_normalized = math.cos(
                p.signal_direction_deg / 180.0 * math.pi
            ) * p.velocity_pixels_per_sec / p.size[0] * time_delta_sec
            y_increment_normalized = -math.sin(
                p.signal_direction_deg / 180.0 * math.pi
            ) * p.velocity_pixels_per_sec / p.size[1] * time_delta_sec
            self.x_positions[:signal_num_dots] += x_increment_normalized
            self.y_positions[:signal_num_dots] += y_increment_normalized

            num_random_dots = self.constant_parameters.num_dots - signal_num_dots
            random_x_increment_normalized = Numeric.cos(
                self.random_directions_radians[signal_num_dots:]
            ) * p.velocity_pixels_per_sec / p.size[0] * time_delta_sec
            random_y_increment_normalized = -Numeric.sin(
                self.random_directions_radians[signal_num_dots:]
            ) * p.velocity_pixels_per_sec / p.size[1] * time_delta_sec
            self.x_positions[signal_num_dots:] += random_x_increment_normalized
            self.y_positions[signal_num_dots:] += random_y_increment_normalized

            self.x_positions = Numeric.fmod(self.x_positions, 1.0)  # wrap
            self.y_positions = Numeric.fmod(self.y_positions, 1.0)

            self.x_positions = Numeric.fmod(self.x_positions + 1,
                                            1.0)  # wrap again for values < 1
            self.y_positions = Numeric.fmod(self.y_positions + 1, 1.0)

            xs = (self.x_positions - 0.5) * p.size[0] + center[0]
            ys = (self.y_positions - 0.5) * p.size[1] + center[1]

            if len(p.color) == 3:
                gl.glColor3f(*p.color)
            elif len(p.color) == 4:
                gl.glColor4f(*p.color)
            gl.glPointSize(p.dot_size)

            # Clear the modeview matrix
            gl.glMatrixMode(gl.GL_MODELVIEW)
            gl.glPushMatrix()

            gl.glDisable(gl.GL_TEXTURE_2D)

            if p.depth is None:
                depth = 0.0
            else:
                gl.glEnable(gl.GL_DEPTH_TEST)
                depth = p.depth
            zs = (depth, ) * len(xs)  # make N tuple with repeat value of depth
            draw_dots(xs, ys, zs)
            if p.anti_aliasing:
                gl.glDisable(gl.GL_POINT_SMOOTH)  # turn off
            gl.glPopMatrix()
示例#8
0
class FilledCircle(VisionEgg.Core.Stimulus):
    """  A circular stimulus, typically used as a fixation point.

    (Note, this implementation almost certainly could be made faster
    using display lists.)

    Parameters
    ==========
    anchor        -- how position parameter is used (String)
                     Default: center
    anti_aliasing -- (Boolean)
                     Default: True
    color         -- color (AnyOf(Sequence3 of Real or Sequence4 of Real))
                     Default: (1.0, 1.0, 1.0)
    num_triangles -- number of triangles used to draw circle (Integer)
                     Default: 51
    on            -- draw? (Boolean)
                     Default: True
    position      -- position in eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real))
                     Default: (320.0, 240.0)
    radius        -- radius in eye coordinates (Real)
                     Default: 2.0
    """

    parameters_and_defaults = VisionEgg.ParameterDefinition({
        'on': (True, ve_types.Boolean, 'draw?'),
        'color': ((1.0, 1.0, 1.0),
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real)), 'color'),
        'anti_aliasing': (True, ve_types.Boolean),
        'position': (
            (320.0, 240.0),  # in eye coordinates
            ve_types.AnyOf(ve_types.Sequence2(ve_types.Real),
                           ve_types.Sequence3(ve_types.Real),
                           ve_types.Sequence4(ve_types.Real)),
            'position in eye coordinates'),
        'anchor':
        ('center', ve_types.String, 'how position parameter is used'),
        'radius': (2.0, ve_types.Real, 'radius in eye coordinates'),
        'num_triangles':
        (51, ve_types.Integer, 'number of triangles used to draw circle'),
    })
    __slots__ = VisionEgg.Core.Stimulus.__slots__ + ('_gave_alpha_warning', )

    def __init__(self, **kw):
        VisionEgg.Core.Stimulus.__init__(self, **kw)
        self._gave_alpha_warning = 0

    def draw(self):
        p = self.parameters  # shorthand
        if p.on:
            # calculate center
            center = VisionEgg._get_center(p.position, p.anchor,
                                           (p.radius, p.radius))
            gl.glDisable(gl.GL_DEPTH_TEST)
            gl.glDisable(gl.GL_TEXTURE_2D)
            gl.glDisable(gl.GL_BLEND)

            if len(p.color) == 3:
                gl.glColor3f(*p.color)
            elif len(p.color) == 4:
                gl.glColor4f(*p.color)

        # Build filled circle from points
#           gl.glBegin(gl.GL_POINTS)
#           radius = int(math.ceil(p.radius))
#           for i in range(-radius, radius):
#               for j in range(-radius, radius):
#                   if(i * i + j * j < radius * radius):
#                       gl.glVertex3f(p.position[0] + i, p.position[1] + j, 0.0)
#           gl.glEnd() # GL_POINTS

# Build filled circle from triangles (this is typically faster
# then the commented code above with the points)
            gl.glBegin(gl.GL_TRIANGLE_FAN)
            gl.glVertex3f(p.position[0], p.position[1], 0.0)
            angles = Numeric.arange(p.num_triangles) / float(
                p.num_triangles) * 2.0 * math.pi
            verts = Numeric.zeros((p.num_triangles, 2), Numeric.Float)
            verts[:, 0] = p.position[0] + p.radius * Numeric.cos(angles)
            verts[:, 1] = p.position[1] + p.radius * Numeric.sin(angles)
            for i in range(verts.shape[0]):
                gl.glVertex2fv(verts[i])
            gl.glVertex2fv(verts[0])

            gl.glEnd()  # GL_TRIANGLE_FAN
            if p.anti_aliasing:
                if not self._gave_alpha_warning:
                    if len(p.color) > 3 and p.color[3] != 1.0:
                        logger = logging.getLogger('VisionEgg.Arrow')
                        logger.warning("The parameter anti_aliasing is "
                                       "set to true in the Arrow "
                                       "stimulus class, but the color "
                                       "parameter specifies an alpha "
                                       "value other than 1.0.  To "
                                       "acheive anti-aliasing, ensure "
                                       "that the alpha value for the "
                                       "color parameter is 1.0.")
                        self._gave_alpha_warning = 1

                        # We've already drawn a filled polygon (aliased), now redraw
                        # the outline of the polygon (with anti-aliasing). (Using
                        # GL_POLYGON_SMOOTH results in artifactual lines where
                        # triangles were joined to create quad, at least on some OpenGL
                        # implementations.)

                # Calculate coverage value for each pixel of outline
                # and store as alpha
                gl.glEnable(gl.GL_LINE_SMOOTH)
                # Now specify how to use the alpha value
                gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
                gl.glEnable(gl.GL_BLEND)

                # Draw a second polygon in line mode, so the edges are anti-aliased
                gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)
                gl.glBegin(gl.GL_TRIANGLE_FAN)
                gl.glVertex3f(p.position[0], p.position[1], 0.0)
                angles = Numeric.arange(p.num_triangles) / float(
                    p.num_triangles) * 2.0 * math.pi
                verts = Numeric.zeros((p.num_triangles, 2), Numeric.Float)
                verts[:, 0] = p.position[0] + p.radius * Numeric.cos(angles)
                verts[:, 1] = p.position[1] + p.radius * Numeric.sin(angles)
                for i in range(verts.shape[0]):
                    gl.glVertex2fv(verts[i])
                gl.glVertex2fv(verts[0])
                gl.glEnd()  # GL_TRIANGLE_FAN

                # Set the polygon mode back to fill mode
                gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
                gl.glDisable(gl.GL_LINE_SMOOTH)
示例#9
0
class Target2D(VisionEgg.Core.Stimulus):
    """Rectanglular stimulus.

    Parameters
    ==========
    anchor        -- specifies how position parameter is interpreted (String)
                     Default: center
    anti_aliasing -- (Boolean)
                     Default: True
    center        -- DEPRECATED: don't use (Sequence2 of Real)
                     Default: (determined at runtime)
    color         -- (AnyOf(Sequence3 of Real or Sequence4 of Real))
                     Default: (1.0, 1.0, 1.0)
    on            -- draw stimulus? (Boolean) (Boolean)
                     Default: True
    orientation   -- (Real)
                     Default: 0.0
    position      -- units: eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real))
                     Default: (320.0, 240.0)
    size          -- units: eye coordinates (Sequence2 of Real)
                     Default: (64.0, 16.0)
    """

    parameters_and_defaults = {
        'on': (True, ve_types.Boolean, "draw stimulus? (Boolean)"),
        'color': ((1.0, 1.0, 1.0),
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real))),
        'anti_aliasing': (True, ve_types.Boolean),
        'orientation': (0.0, ve_types.Real),
        'position': ((320.0, 240.0),
                     ve_types.AnyOf(ve_types.Sequence2(ve_types.Real),
                                    ve_types.Sequence3(ve_types.Real),
                                    ve_types.Sequence4(ve_types.Real)),
                     "units: eye coordinates"),
        'anchor': ('center', ve_types.String,
                   "specifies how position parameter is interpreted"),
        'size': ((64.0, 16.0), ve_types.Sequence2(ve_types.Real),
                 "units: eye coordinates"),
        'center':
        (None, ve_types.Sequence2(ve_types.Real), "DEPRECATED: don't use"),
    }

    __slots__ = ('_gave_alpha_warning', )

    def __init__(self, **kw):
        VisionEgg.Core.Stimulus.__init__(self, **kw)
        self._gave_alpha_warning = 0

    def draw(self):
        p = self.parameters  # shorthand
        if p.center is not None:
            if not hasattr(VisionEgg.config, "_GAVE_CENTER_DEPRECATION"):
                logger = logging.getLogger('VisionEgg.MoreStimuli')
                logger.warning("Specifying Target2D by deprecated "
                               "'center' parameter deprecated.  Use "
                               "'position' parameter instead.  (Allows "
                               "use of 'anchor' parameter to set to "
                               "other values.)")
                VisionEgg.config._GAVE_CENTER_DEPRECATION = 1
            p.anchor = 'center'
            p.position = p.center[0], p.center[
                1]  # copy values (don't copy ref to tuple)
        if p.on:
            # calculate center
            center = VisionEgg._get_center(p.position, p.anchor, p.size)
            gl.glMatrixMode(gl.GL_MODELVIEW)
            gl.glPushMatrix()
            gl.glTranslate(center[0], center[1], 0.0)
            gl.glRotate(p.orientation, 0.0, 0.0, 1.0)

            if len(p.color) == 3:
                gl.glColor3f(*p.color)
            elif len(p.color) == 4:
                gl.glColor4f(*p.color)
            gl.glDisable(gl.GL_DEPTH_TEST)
            gl.glDisable(gl.GL_TEXTURE_2D)
            gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
            gl.glEnable(gl.GL_BLEND)

            w = p.size[0] / 2.0
            h = p.size[1] / 2.0

            gl.glBegin(gl.GL_QUADS)
            gl.glVertex3f(-w, -h, 0.0)
            gl.glVertex3f(w, -h, 0.0)
            gl.glVertex3f(w, h, 0.0)
            gl.glVertex3f(-w, h, 0.0)
            gl.glEnd()  # GL_QUADS

            if p.anti_aliasing:
                if not self._gave_alpha_warning:
                    if len(p.color) > 3 and p.color[3] != 1.0:
                        logger = logging.getLogger('VisionEgg.MoreStimuli')
                        logger.warning("The parameter anti_aliasing is "
                                       "set to true in the Target2D "
                                       "stimulus class, but the color "
                                       "parameter specifies an alpha "
                                       "value other than 1.0.  To "
                                       "acheive anti-aliasing, ensure "
                                       "that the alpha value for the "
                                       "color parameter is 1.0.")
                        self._gave_alpha_warning = 1

                # We've already drawn a filled polygon (aliased), now
                # redraw the outline of the polygon (with
                # anti-aliasing).  (Using GL_POLYGON_SMOOTH results in
                # artifactual lines where triangles were joined to
                # create quad, at least on some OpenGL
                # implementations.)

                # Calculate coverage value for each pixel of outline
                # and store as alpha
                gl.glEnable(gl.GL_LINE_SMOOTH)
                # Now specify how to use the alpha value
                gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
                gl.glEnable(gl.GL_BLEND)

                # Draw a second polygon in line mode, so the edges are anti-aliased
                gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)
                gl.glBegin(gl.GL_QUADS)
                gl.glVertex3f(-w, -h, 0.0)
                gl.glVertex3f(w, -h, 0.0)
                gl.glVertex3f(w, h, 0.0)
                gl.glVertex3f(-w, h, 0.0)
                gl.glEnd()  # GL_QUADS

                # Set the polygon mode back to fill mode
                gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
                gl.glDisable(gl.GL_LINE_SMOOTH)
            gl.glPopMatrix()
示例#10
0
class Arrow(VisionEgg.Core.Stimulus):
    """Arrow stimulus.

    Parameters
    ==========
    anchor        -- (String)
                     Default: center
    anti_aliasing -- (Boolean)
                     Default: True
    color         -- (AnyOf(Sequence3 of Real or Sequence4 of Real))
                     Default: (1.0, 1.0, 1.0)
    on            -- (Boolean)
                     Default: True
    orientation   -- (Real)
                     Default: 0.0
    position      -- units: eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real))
                     Default: (320.0, 240.0)
    size          -- (Sequence2 of Real)
                     Default: (64.0, 16.0)
    """

    parameters_and_defaults = {
        'on': (True, ve_types.Boolean),
        'color': ((1.0, 1.0, 1.0),
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real))),
        'anti_aliasing': (True, ve_types.Boolean),
        'orientation': (
            0.0,  # 0.0 degrees = right, 90.0 degrees = up
            ve_types.Real),
        'position': (
            (320.0, 240.0),  # In eye coordinates
            ve_types.AnyOf(ve_types.Sequence2(ve_types.Real),
                           ve_types.Sequence3(ve_types.Real),
                           ve_types.Sequence4(ve_types.Real)),
            "units: eye coordinates"),
        'anchor': ('center', ve_types.String),
        'size': (
            (64.0, 16.0),  # In eye coordinates
            ve_types.Sequence2(ve_types.Real)),
    }

    __slots__ = VisionEgg.Core.Stimulus.__slots__ + ('_gave_alpha_warning', )

    def __init__(self, **kw):
        VisionEgg.Core.Stimulus.__init__(self, **kw)
        self._gave_alpha_warning = 0

    def draw(self):
        p = self.parameters  # Shorthand
        if p.on:
            # Calculate center
            center = VisionEgg._get_center(p.position, p.anchor, p.size)
            gl.glMatrixMode(gl.GL_MODELVIEW)
            gl.glPushMatrix()
            gl.glTranslate(center[0], center[1], 0.0)
            gl.glRotate(-p.orientation, 0.0, 0.0, 1.0)

            if len(p.color) == 3:
                gl.glColor3f(*p.color)
            elif len(p.color) == 4:
                gl.glColor4f(*p.color)
            gl.glDisable(gl.GL_DEPTH_TEST)
            gl.glDisable(gl.GL_TEXTURE_2D)
            gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
            gl.glEnable(gl.GL_BLEND)

            w = p.size[0] / 2.0
            h = p.size[1] / 2.0

            gl.glBegin(gl.GL_QUADS)  # Draw Rectangle
            gl.glVertex3f(0.25 * w, h, 0.0)
            gl.glVertex3f(-w, h, 0.0)
            gl.glVertex3f(-w, -h, 0.0)
            gl.glVertex3f(0.25 * w, -h, 0.0)
            gl.glEnd()  # GL_QUADS

            gl.glBegin(gl.GL_TRIANGLES)  # Draw Triangle
            gl.glVertex3f(1.00 * w, 0.0 * h, 0.0)  # Top
            gl.glVertex3f(0.25 * w, -3.0 * h, 0.0)
            gl.glVertex3f(0.25 * w, 3.0 * h, 0.0)
            gl.glEnd()  # GL_QUADS

            if p.anti_aliasing:
                if not self._gave_alpha_warning:
                    if len(p.color) > 3 and p.color[3] != 1.0:
                        logger = logging.getLogger('VisionEgg.Arrow')
                        logger.warning("The parameter anti_aliasing is "
                                       "set to true in the Arrow "
                                       "stimulus class, but the color "
                                       "parameter specifies an alpha "
                                       "value other than 1.0.  To "
                                       "acheive anti-aliasing, ensure "
                                       "that the alpha value for the "
                                       "color parameter is 1.0.")
                        self._gave_alpha_warning = 1

                # We've already drawn a filled polygon (aliased), now redraw
                # the outline of the polygon (with anti-aliasing). (Using
                # GL_POLYGON_SMOOTH results in artifactual lines where
                # triangles were joined to create quad, at least on some OpenGL
                # implementations.)

                # Calculate coverage value for each pixel of outline
                # and store as alpha
                gl.glEnable(gl.GL_LINE_SMOOTH)
                # Now specify how to use the alpha value
                gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
                gl.glEnable(gl.GL_BLEND)

                # Draw a second polygon in line mode, so the edges are anti-aliased
                gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)
                gl.glBegin(gl.GL_QUADS)

                gl.glVertex3f(0.25 * w, h, 0.0)  # Draw Rectangle
                gl.glVertex3f(-w, h, 0.0)
                gl.glVertex3f(-w, -h, 0.0)
                gl.glVertex3f(0.25 * w, -h, 0.0)
                gl.glVertex3f(1.00 * w, 0.0 * h, 0.0)  # Draw Triangle
                gl.glVertex3f(0.25 * w, -3.0 * h, 0.0)
                gl.glVertex3f(0.25 * w, 3.0 * h, 0.0)
                gl.glEnd()  # GL_QUADS

                # Set the polygon mode back to fill mode
                gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
                gl.glDisable(gl.GL_LINE_SMOOTH)
            gl.glPopMatrix()
示例#11
0
class Rectangle3D(VisionEgg.Core.Stimulus):
    """Solid color rectangle positioned explicitly by four vertices.

    Parameters
    ==========
    color   -- (AnyOf(Sequence3 of Real or Sequence4 of Real))
               Default: (1.0, 1.0, 1.0, 1.0)
    on      -- (Boolean)
               Default: True
    vertex1 -- units: eye coordinates (AnyOf(Sequence3 of Real or Sequence4 of Real))
               Default: (-10.0, 0.0, -10.0)
    vertex2 -- units: eye coordinates (AnyOf(Sequence3 of Real or Sequence4 of Real))
               Default: (-10.0, 0.0, 10.0)
    vertex3 -- units: eye coordinates (AnyOf(Sequence3 of Real or Sequence4 of Real))
               Default: (10.0, 0.0, 10.0)
    vertex4 -- units: eye coordinates (AnyOf(Sequence3 of Real or Sequence4 of Real))
               Default: (10.0, 0.0, -10.0)
    """

    parameters_and_defaults = {
        'on': (True, ve_types.Boolean),
        'blending_enabled': (False, ve_types.Boolean),

        # different default than TextureStimulus3D due to not break backwards compatibility
        'depth_test': (False, ve_types.Boolean),
        'color': ((1.0, 1.0, 1.0, 1.0),
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real))),
        'vertex1': ((-10.0, 0.0, -10.0),
                    ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                   ve_types.Sequence4(ve_types.Real)),
                    "units: eye coordinates"),
        'vertex2': ((-10.0, 0.0, 10.0),
                    ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                   ve_types.Sequence4(ve_types.Real)),
                    "units: eye coordinates"),
        'vertex3': ((10.0, 0.0, 10.0),
                    ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                   ve_types.Sequence4(ve_types.Real)),
                    "units: eye coordinates"),
        'vertex4': ((10.0, 0.0, -10.0),
                    ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                   ve_types.Sequence4(ve_types.Real)),
                    "units: eye coordinates"),
    }

    def __init__(self, **kw):
        VisionEgg.Core.Stimulus.__init__(self, **kw)

    def draw(self):
        p = self.parameters  # shorthand
        if p.on:
            if len(p.color) == 3:
                gl.glColor3f(*p.color)
            elif len(p.color) == 4:
                gl.glColor4f(*p.color)

            gl.glDisable(gl.GL_TEXTURE_2D)
            if p.depth_test:
                gl.glEnable(gl.GL_DEPTH_TEST)
            else:
                gl.glDisable(gl.GL_DEPTH_TEST)
            if p.blending_enabled:
                gl.glEnable(gl.GL_BLEND)
            else:
                gl.glDisable(gl.GL_BLEND)

            gl.glBegin(gl.GL_QUADS)
            gl.glVertex(*p.vertex1)
            gl.glVertex(*p.vertex2)
            gl.glVertex(*p.vertex3)
            gl.glVertex(*p.vertex4)
            gl.glEnd()  # GL_QUADS
示例#12
0
class CircleSector(DisplayListStimulus):
    """  A sector of a circular stimulus, optionally filled.
    

    Parameters
    ==========
    anchor        -- how position parameter is used (String)
                     Default: center
    anti_aliasing -- (Boolean)
                     Default: True
    color         -- color (AnyOf(Sequence3 of Real or Sequence4 of Real))
                     Default: (1.0, 1.0, 1.0)
    num_triangles -- number of triangles used to draw circle (Integer)
                     Default: 51
    on            -- draw? (Boolean)
                     Default: True
    position      -- position in eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real))
                     Default: (320.0, 240.0)
    radius        -- radius in eye coordinates (Real)
                     Default: 2.0
    """

    parameters_and_defaults = VisionEgg.ParameterDefinition({
        'on': (True, ve_types.Boolean, 'draw?'),
        'color': ((1.0, 1.0, 1.0),
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real)), 'color'),
        'color_edge': ((1.0, 1.0, 1.0),
                       ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                      ve_types.Sequence4(ve_types.Real)),
                       'color for the circle edge'),
        'anti_aliasing': (True, ve_types.Boolean),
        'position': (
            (320.0, 240.0),  # in eye coordinates
            ve_types.AnyOf(ve_types.Sequence2(ve_types.Real),
                           ve_types.Sequence3(ve_types.Real),
                           ve_types.Sequence4(ve_types.Real)),
            'position in eye coordinates'),
        'anchor':
        ('center', ve_types.String, 'how position parameter is used'),
        'radius': (2.0, ve_types.Real, 'radius in eye coordinates'),
        'num_triangles':
        (51, ve_types.Integer, 'number of triangles used to draw circle'),
        'start': (0., ve_types.Real, 'start angle'),
        'end': (360., ve_types.Real, 'end angle'),
        'disk': (True, ve_types.Boolean, 'draw the interior?'),
        'circle': (True, ve_types.Boolean, 'draw the edge?'),
        'circle_width': (1., ve_types.Real, 'line width of the circle edge'),
    })
    __slots__ = VisionEgg.Core.Stimulus.__slots__ + ('_gave_alpha_warning', )

    def __init__(self, **kw):
        DisplayListStimulus.__init__(self, **kw)
        self._gave_alpha_warning = 0

    def _draw(self):
        p = self.parameters
        center = VisionEgg._get_center(p.position, p.anchor,
                                       (p.radius, p.radius))
        gl.glDisable(gl.GL_DEPTH_TEST)
        gl.glDisable(gl.GL_TEXTURE_2D)
        gl.glDisable(gl.GL_BLEND)
        gl.glColor(p.color)
        start, end = p.start, p.end
        if end < start:
            start -= 360.
        start, end = map(numpy.deg2rad, (start, end))
        frac = (end - start) / (2 * numpy.pi)
        num_triangles = float(p.num_triangles) * frac
        angles = numpy.linspace(start, end, num_triangles)
        verts = numpy.zeros((num_triangles, 2))
        verts[:, 0] = center[0] + p.radius * numpy.cos(angles)
        verts[:, 1] = center[1] + p.radius * numpy.sin(angles)
        if p.disk:
            gl.glBegin(gl.GL_TRIANGLE_FAN)
            gl.glVertex(center)
            self._draw_vertices(*verts)
            gl.glEnd()
            if p.anti_aliasing:
                gl.glEnable(gl.GL_LINE_SMOOTH)
                gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
                gl.glEnable(gl.GL_BLEND)
                # Draw a second polygon in line mode, so the edges are anti-aliased
                gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)
                gl.glBegin(gl.GL_TRIANGLE_FAN)
                gl.glVertex(center)
                self._draw_vertices(*verts)
                gl.glEnd()
                gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
                gl.glDisable(gl.GL_LINE_SMOOTH)
        if p.circle:
            if p.anti_aliasing:
                gl.glEnable(gl.GL_LINE_SMOOTH)
            gl.glColor(p.color_edge)
            gl.glLineWidth(p.circle_width)
            gl.glBegin(gl.GL_LINES)
            for i in range(verts.shape[0] - 1):
                self._draw_vertices(verts[i], verts[i + 1])
            gl.glEnd()
            gl.glDisable(gl.GL_LINE_SMOOTH)
示例#13
0
class Triangle(DisplayListStimulus):
    """  An equilateral triangle.
    

    Parameters
    ==========
    anti_aliasing -- (Boolean)
                     Default: True
    color         -- color (AnyOf(Sequence3 of Real or Sequence4 of Real))
                     Default: (1.0, 1.0, 1.0)
    on            -- draw? (Boolean)
                     Default: True
    position      -- position in eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real))
                     Default: (320.0, 240.0)
    side          -- side length
    """

    parameters_and_defaults = VisionEgg.ParameterDefinition({
        'anchor':
        ('center', ve_types.String, 'how position parameter is used'),
        'on': (True, ve_types.Boolean, 'draw?'),
        'color': ((1.0, 1.0, 1.0),
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real)), 'color'),
        'color_edge': ((1.0, 1.0, 1.0),
                       ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                      ve_types.Sequence4(ve_types.Real)),
                       'color for the edge'),
        'anti_aliasing': (True, ve_types.Boolean),
        'position': (
            (320.0, 240.0),  # in eye coordinates
            ve_types.AnyOf(ve_types.Sequence2(ve_types.Real),
                           ve_types.Sequence3(ve_types.Real),
                           ve_types.Sequence4(ve_types.Real)),
            'position in eye coordinates'),
        'side': (10., ve_types.Real, 'side length'),
        'width': (1., ve_types.Real, 'line width'),
    })
    __slots__ = VisionEgg.Core.Stimulus.__slots__ + ('_gave_alpha_warning', )

    def __init__(self, **kw):
        DisplayListStimulus.__init__(self, **kw)
        self._gave_alpha_warning = 0

    def _draw(self):
        p = self.parameters
        side = p.side
        height = side * numpy.sqrt(3) / 2.
        center = VisionEgg._get_center(p.position, p.anchor, (side, height))
        position = numpy.array(center)
        hh = height / 2
        ll = position - (hh, hh)
        lr = position - (-hh, hh)
        u = position + (0., hh)
        gl.glDisable(gl.GL_DEPTH_TEST)
        gl.glDisable(gl.GL_TEXTURE_2D)
        gl.glDisable(gl.GL_BLEND)
        gl.glColor(p.color)
        gl.glBegin(gl.GL_TRIANGLES)
        self._draw_vertices(ll, lr, u)
        gl.glEnd()
        gl.glColor(p.color_edge)
        if p.anti_aliasing:
            gl.glEnable(gl.GL_LINE_SMOOTH)
        gl.glLineWidth(p.width)
        gl.glBegin(gl.GL_LINE_STRIP)
        self._draw_vertices(ll, lr, u, ll)
        gl.glEnd()
        gl.glDisable(gl.GL_LINE_SMOOTH)
示例#14
0
class CheckBoard(Stimulus):
    """A checkboard stimulus, typically used as a aux stimulus for whitenoise.

    Parameters
    ==========
    anchor   -- how position parameter is used (String)
                Default: center
    color    -- color (256 jet colormap )
                Default: 0(gray)
    on       -- draw? (Boolean)
                Default: True
    position -- position in eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real))
                Default: (320.0, 240.0)
    size     -- size in eye coordinates (Sequence2 of Real)
                Default: (4.0, 4.0)
    """

    parameters_and_defaults = VisionEgg.ParameterDefinition({
        'on': (True, ve_types.Boolean, 'draw?'),
        'bgcolor':
        ((0.5, 0.5, 0.5),
         ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                        ve_types.Sequence4(ve_types.Real)), 'backgroud color'),
        'linecolor':
        ((0.5, 0.0, 0.0),
         ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                        ve_types.Sequence4(ve_types.Real)), 'grid line color'),
        'cellcolor':
        ('gbr', ve_types.String, 'color map for the range [0.0,1.0]'),
        'colorindex': (None, ve_types.Sequence(ve_types.Integer),
                       'color index in jet colormap'),
        'drawline': (False, ve_types.Boolean, 'draw line?'),
        'orientation': (0.0, ve_types.Real),
        'position': (
            (320.0, 240.0),  # in eye coordinates
            ve_types.AnyOf(ve_types.Sequence2(ve_types.Real),
                           ve_types.Sequence3(ve_types.Real),
                           ve_types.Sequence4(ve_types.Real)),
            'position in eye coordinates'),
        'anchor':
        ('center', ve_types.String, 'how position parameter is used'),
        'size': (
            (100.0, 100.0),  # horiz and vertical size
            ve_types.Sequence2(ve_types.Real),
            'size in eye coordinates'),
        'grid': (
            (8, 8),  # grid dimension of the checkboard
            ve_types.Sequence2(ve_types.Integer),
            'grid dimension'),
        'center': (
            None,  # DEPRECATED -- don't use
            ve_types.Sequence2(ve_types.Real),
            'position in eye coordinates',
            VisionEgg.ParameterDefinition.DEPRECATED),
    })

    def __init__(self, **kw):
        Stimulus.__init__(self, **kw)
        self.parameters.colorindex = np.zeros(self.parameters.grid)
        self.parameters.colorindex.fill(0.5)

    def draw(self):
        p = self.parameters  # shorthand
        if p.center is not None:
            p.anchor = 'center'
            p.position = p.center[0], p.center[
                1]  # copy values (don't copy ref to tuple)
        if p.on:
            # calculate center
            center = VisionEgg._get_center(p.position, p.anchor, p.size)
            gl.glMatrixMode(gl.GL_MODELVIEW)
            gl.glPushMatrix()
            gl.glTranslate(center[0], center[1], 0.0)
            gl.glRotate(p.orientation, 0.0, 0.0, 1.0)

            if len(p.bgcolor) == 3:
                gl.glColor3f(*p.bgcolor)
            elif len(p.bgcolor) == 4:
                gl.glColor4f(*p.bgcolor)
            gl.glDisable(gl.GL_DEPTH_TEST)
            gl.glDisable(gl.GL_TEXTURE_2D)
            gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
            gl.glEnable(gl.GL_BLEND)

            w = p.size[0] / 2.0  #grid half-size
            h = p.size[1] / 2.0
            m = p.size[0] / p.grid[0]  #cell size
            n = p.size[1] / p.grid[1]
            i = range(p.grid[0])  #grid index
            j = range(p.grid[1])
            #draw colorful cell
            #           vertices_list = [((-w+column*m, h-(row+1)*n, 0.0),(-w+column*m, h-row*n, 0.0),\
            #                         (-w+(column+1)*m, h-row*n, 0.0),(-w+(column+1)*m, h-row*n, 0.0))\
            #                         for column in j for row in i]
            vertices_list = [((-w+column*m, h-(row+1)*n, 0.0),(-w+column*m, h-row*n, 0.0),\
                              (-w+(column+1)*m, h-row*n, 0.0),(-w+(column+1)*m, h-(row+1)*n, 0.0))\
                         for column in j for row in i]
            colors_list = [
                colormap(p.colorindex[row, column], color=p.cellcolor) * 4
                for column in j for row in i
            ]
            #flattening the vertices and colors
            vertices_flat = [
                num for tuple in vertices_list for vertex in tuple
                for num in vertex
            ]
            colors_flat = [num for tuple in colors_list for num in tuple]
            vertices = np.array(vertices_flat)
            colors = np.array(colors_flat)
            vertices.shape = (-1, 3)
            colors.shape = (-1, 3)
            gl.glVertexPointerd(vertices)
            gl.glColorPointerd(colors)
            gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
            gl.glEnableClientState(gl.GL_COLOR_ARRAY)
            gl.glDisable(gl.GL_LIGHTING)
            gl.glDrawArrays(gl.GL_QUADS, 0, p.grid[0] * p.grid[1] * 4)

            #draw grid lines
            if p.drawline:
                if len(p.linecolor) == 3:
                    gl.glColor3f(*p.linecolor)
                elif len(p.linecolor) == 4:
                    gl.glColor4f(*p.linecolor)

                row_list = [((-w, h - i * n), (w, h - i * n))
                            for i in range(p.grid[1] + 1)]
                col_list = [((-w + i * m, h), (-w + i * m, -h))
                            for i in range(p.grid[0] + 1)]
                ver_row_flat = [
                    num for tuple in row_list for vertex in tuple
                    for num in vertex
                ]
                ver_col_flat = [
                    num for tuple in col_list for vertex in tuple
                    for num in vertex
                ]
                vertices_row = np.array(ver_row_flat)
                vertices_col = np.array(ver_col_flat)
                vertices_row.shape = (-1, 2)
                vertices_col.shape = (-1, 2)

                gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
                gl.glDisableClientState(gl.GL_COLOR_ARRAY)
                gl.glVertexPointerd(vertices_row)
                gl.glDrawArrays(gl.GL_LINES, 0, (p.grid[1] + 1) * 2)
                gl.glVertexPointerd(vertices_col)
                gl.glDrawArrays(gl.GL_LINES, 0, (p.grid[0] + 1) * 2)

#                gl.glBegin(gl.GL_LINES);
#                for i in range(p.grid[1] + 1):
#                    gl.glVertex2f(-w, h - i * n)
#                    gl.glVertex2f(w, h - i * n)
#                for i in range(p.grid[0] + 1):
#                    gl.glVertex2f(-w + i * m, h)
#                    gl.glVertex2f(-w + i * m, -h)
#                gl.glEnd();
            gl.glPopMatrix()

    #save checkboard to file
    def save(self):
        import time, os
        (year, month, day, hour24, min, sec) = time.localtime(time.time())[:6]
        trial_time_str = "%04d%02d%02d_%02d%02d%02d" % (year, month, day,
                                                        hour24, min, sec)
        dummy_filename = os.path.abspath(os.curdir)+ os.path.sep + 'screenshoot' + \
                   os.path.sep + 'checkboard' + trial_time_str + '.jpg'
示例#15
0
class Dots3D(VisionEgg.Core.Stimulus):
    """Random dots of constant velocity (3D)

    Every dot has the same 3D velocity. Each dot has a lifespan. Some
    dots can be black, while the rest are white.

    This is just one example of the endless variations on drawing random dots.

    Parameters
    ==========
    dot_lifespan_sec        -- (Real)
                               Default: 5.0
    dot_size                -- (Real)
                               Default: 4.0
    on                      -- (Boolean)
                               Default: True
    signal_vec              -- (Sequence3 of Real)
                               Default: (0, 0, 0)
    start_position_mean     -- (Sequence3 of Real)
                               Default: (0, 0, 0)
    start_position_variance -- (Real)
                               Default: 1

    Constant Parameters
    ===================
    num_dark -- (UnsignedInteger)
                Default: 100
    num_dots -- (UnsignedInteger)
                Default: 200
    """

    parameters_and_defaults = {
        'on' : ( True,
                 ve_types.Boolean ),
        'start_position_mean' : ( ( 0,0,0 ), # in world coordinates
                            ve_types.Sequence3(ve_types.Real) ),
        'start_position_variance' :   (  1, ve_types.Real ), # sigma**2
        'signal_vec' : ( ( 0,0,0 ), # in world coordinates
                         ve_types.Sequence3(ve_types.Real) ),
        'dot_size' : (4.0, # pixels
                      ve_types.Real),
        'dot_lifespan_sec' : ( 5.0,
                               ve_types.Real ),
        }

    constant_parameters_and_defaults = {
        'num_dots' : ( 200,
                       ve_types.UnsignedInteger ),
        'num_dark' : ( 100, # the number of total that are black
                       ve_types.UnsignedInteger ),
        }

    __slots__ = (
        'centers',
        'colors',
        'last_time_sec',
        'start_times_sec',
        )

    def __init__(self, **kw):
        VisionEgg.Core.Stimulus.__init__(self,**kw)
        # store positions normalized around 0 so that re-sizing is ok
        num_dots = self.constant_parameters.num_dots # shorthand
        self.centers = np.random.standard_normal((3,num_dots))
        self.colors = np.ones((num_dots,4))
        self.colors[:self.constant_parameters.num_dark,:3] = 0
        self.last_time_sec = VisionEgg.time_func()
        self.start_times_sec = None # setup variable, assign later

    def draw(self):
        # XXX This method is not speed-optimized. I just wrote it to
        # get the job done. (Nonetheless, it seems faster than the C
        # version commented out above.)

        p = self.parameters # shorthand

        now_sec = VisionEgg.time_func()
        if self.start_times_sec is not None:
            # compute extinct dots and generate new positions
            replace_indices = Numeric.nonzero( Numeric.greater( now_sec - self.start_times_sec, p.dot_lifespan_sec) )
            Numeric.put( self.start_times_sec, replace_indices, now_sec )

            new_centers = np.random.standard_normal((3,len(replace_indices)))
            for i in range(3):
                Numeric.put( self.centers[i,:], replace_indices, new_centers[i,:] )
        else:
            # initialize dot extinction values to random (uniform) distribution
            self.start_times_sec = RandomArray.uniform( now_sec - p.dot_lifespan_sec, now_sec,
                                                        (self.constant_parameters.num_dots,))

        time_delta_sec = now_sec - self.last_time_sec
        self.last_time_sec = now_sec # reset for next loop
        self.centers = self.centers + np.array(p.signal_vec)[:,np.newaxis]*time_delta_sec

        xyz = self.centers*p.start_position_variance + np.array(p.start_position_mean)[:,np.newaxis]
        xs = xyz[0,:]
        ys = xyz[1,:]
        zs = xyz[2,:]

        if p.on:
            gl.glEnable( gl.GL_POINT_SMOOTH )
            # allow max_alpha value to control blending
            gl.glEnable( gl.GL_BLEND )
            gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA )

            gl.glPointSize(p.dot_size)

            # Clear the modeview matrix
            gl.glMatrixMode(gl.GL_MODELVIEW)
            gl.glPushMatrix()

            gl.glDisable(gl.GL_TEXTURE_2D)

            draw_dots(xs,ys,zs,self.colors)
            gl.glDisable( gl.GL_POINT_SMOOTH ) # turn off
            gl.glPopMatrix()
示例#16
0
class WrappedText(VisionEgg.Core.Stimulus):
    """Multi-line text stimulus. No fancy formatting, but line breaks ('\\n')
  are preserved, and text is wrapped to fit within the stimulus
  boundaries."""

    parameters_and_defaults = {
        'on': (True, ve_types.Boolean),
        'position': ((0.0, 0.0),
                     ve_types.AnyOf(ve_types.Sequence2(ve_types.Real),
                                    ve_types.Sequence3(ve_types.Real),
                                    ve_types.Sequence4(ve_types.Real))),
        'size': (None, ve_types.Sequence2(ve_types.Real),
                 """Defaults to the size of the screen."""),
        'text': ('hello', ve_types.AnyOf(ve_types.String, ve_types.Unicode)),
        'color': ((1.0, 1.0, 1.0),
                  ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
                                 ve_types.Sequence4(ve_types.Real)))
    }

    constant_parameters_and_defaults = {
        'font_name': (None, ve_types.AnyOf(ve_types.String, ve_types.Unicode),
                      "Name of font to use. If None, use the default font"),
        'font_size': (30, ve_types.UnsignedInteger)
    }

    def __init__(self, **kw):
        """Initialize the object, perform the initial line-splitting"""
        VisionEgg.Core.Stimulus.__init__(self, **kw)

        if self.parameters.size is None:
            self.parameters.size = (VisionEgg.config.VISIONEGG_SCREEN_W,
                                    VisionEgg.config.VISIONEGG_SCREEN_H)

        self._splitText()

    def _splitText(self):
        """Split a single string into multiple lines of text, storing each as a
    VisionEgg.Text.Text instance"""
        p = self.parameters
        cp = self.constant_parameters

        self._text = p.text

        textAreaWidth = None
        maxLineLength = len(self._text)
        minLineLength = 1
        lineLength = maxLineLength
        while ((textAreaWidth > p.size[0]) or
               ((maxLineLength - minLineLength) > 1)) and (maxLineLength > 1):
            nextPosition = p.position
            self._textLines = []

            try:
                textLineList = []
                for text in self._text.split("\n"):
                    if text == "":
                        textLineList.append("")
                    else:
                        textLineList.extend(textwrap.wrap(text, lineLength))

                textAreaWidth = None
                for textLine in textLineList:
                    if textLine != "":
                        line = VisionEgg.Text.Text(text=textLine,
                                                   position=nextPosition,
                                                   anchor="upperleft",
                                                   ignore_size_parameter=True,
                                                   color=p.color,
                                                   font_name=cp.font_name,
                                                   font_size=cp.font_size)
                        textAreaWidth = max(textAreaWidth,
                                            line.parameters.size[0])
                        self._textLines.append(line)

                    nextPosition = (nextPosition[0],
                                    nextPosition[1] - line.parameters.size[1])

                    # Stop adding lines if the text area's height has been reached
                    if (p.position[1] - nextPosition[1]) > p.size[1]:
                        break

            except VisionEgg.Textures.TextureTooLargeError:
                textAreaWidth = p.size[0] + 1

            if textAreaWidth > p.size[0]:
                maxLineLength = lineLength
            else:
                minLineLength = lineLength
            lineLength = (maxLineLength + minLineLength) / 2

    def draw(self):
        """Draw the lines of text on the screen"""
        p = self.parameters

        if p.on:
            if p.text != self._text:
                self._splitText()

            for line in self._textLines:
                line.parameters.color = p.color
                line.draw()