|
1 | 1 | function [cfg, thisEvent] = apertureTexture(action, cfg, thisEvent) |
2 | | - |
3 | | - transparent = [0 0 0 0]; |
| 2 | + % [cfg, thisEvent] = apertureTexture(action, cfg, thisEvent) |
| 3 | + % |
| 4 | + % |
4 | 5 |
|
5 | 6 | switch action |
6 | 7 |
|
7 | 8 | case 'init' |
8 | 9 |
|
9 | | - switch cfg.aperture.type |
10 | | - |
11 | | - case 'circle' |
12 | | - % we take the screen height as maximum aperture width if not |
13 | | - % specified. |
14 | | - if ~isfield(cfg.aperture, 'width') || isempty(cfg.aperture.width) |
15 | | - cfg.aperture.width = cfg.screen.winRect(4) / cfg.screen.ppd; |
16 | | - end |
17 | | - cfg.aperture = degToPix('width', cfg.aperture, cfg); |
18 | | - |
19 | | - case 'ring' |
20 | | - |
21 | | - % Set parameters for rings |
22 | | - if strcmp(cfg.aperture.type, 'ring') |
23 | | - % scale of outer ring (exceeding screen until |
24 | | - % inner ring reaches window boarder) |
25 | | - cfg.ring.maxEcc = ... |
26 | | - cfg.screen.FOV / 2 + ... |
27 | | - cfg.aperture.width + ... |
28 | | - log(cfg.screen.FOV / 2 + 1) ; |
29 | | - % ring.CsFuncFact is used to expand with log increasing speed so |
30 | | - % that ring is at ring.maxEcc at end of cycle |
31 | | - cfg.ring.csFuncFact = ... |
32 | | - 1 / ... |
33 | | - ((cfg.ring.maxEcc + exp(1)) * ... |
34 | | - log(cfg.ring.maxEcc + exp(1)) - ... |
35 | | - (cfg.ring.maxEcc + exp(1))) ; |
36 | | - end |
37 | | - end |
| 10 | + cfg = apertureInit(cfg); |
38 | 11 |
|
39 | 12 | cfg.aperture.texture = Screen('MakeTexture', cfg.screen.win, ... |
40 | 13 | cfg.color.background(1) * ones(cfg.screen.winRect([4 3]))); |
41 | 14 |
|
42 | 15 | case 'make' |
43 | 16 |
|
| 17 | + transparent = [0, 0, 0, 0]; |
| 18 | + |
44 | 19 | xCenter = cfg.screen.center(1); |
45 | 20 | yCenter = cfg.screen.center(2); |
46 | 21 |
|
|
62 | 37 | end |
63 | 38 |
|
64 | 39 | Screen('FillOval', cfg.aperture.texture, transparent, ... |
65 | | - CenterRectOnPoint([0 0 repmat(diameter, 1, 2)], ... |
| 40 | + CenterRectOnPoint([0, 0, repmat(diameter, 1, 2)], ... |
66 | 41 | xCenter, yCenter)); |
67 | 42 |
|
68 | 43 | case 'ring' |
|
74 | 49 |
|
75 | 50 | Screen('FillOval', cfg.aperture.texture, transparent, ... |
76 | 51 | CenterRectOnPoint( ... |
77 | | - [0 0 repmat(cfg.ring.outerRimPix, 1, 2)], ... |
| 52 | + [0, 0, repmat(cfg.ring.outerRimPix, 1, 2)], ... |
78 | 53 | xCenter, yCenter)); |
79 | 54 |
|
80 | 55 | Screen('FillOval', cfg.aperture.texture, [cfg.color.background 255], ... |
81 | 56 | CenterRectOnPoint( ... |
82 | | - [0 0 repmat(cfg.ring.innerRimPix, 1, 2)], ... |
| 57 | + [0, 0, repmat(cfg.ring.innerRimPix, 1, 2)], ... |
83 | 58 | xCenter, yCenter)); |
84 | 59 |
|
85 | 60 | case 'wedge' |
|
104 | 79 |
|
105 | 80 | Screen('FillArc', cfg.aperture.texture, transparent, ... |
106 | 81 | CenterRect( ... |
107 | | - [0 0 repmat(cfg.stimRect(4), 1, 2)], ... |
| 82 | + [0, 0, repmat(cfg.stimRect(4), 1, 2)], ... |
108 | 83 | cfg.screen.winRect), ... |
109 | 84 | thisEvent.angle, ... % start angle |
110 | 85 | cfg.aperture.width); % arc angle |
111 | 86 |
|
| 87 | + case 'bar' |
| 88 | + |
| 89 | + % aperture is the color of the background |
| 90 | + Screen('FillRect', cfg.aperture.texture, cfg.color.background); |
| 91 | + |
| 92 | + % We let the stimulus through |
| 93 | + Screen('FillOval', cfg.aperture.texture, transparent, ... |
| 94 | + CenterRect([0, 0, repmat(cfg.stimRect(3), 1, 2)], cfg.screen.winRect)); |
| 95 | + |
| 96 | + % Then we add the position of the bar aperture |
| 97 | + Screen('FillRect', cfg.aperture.texture, cfg.color.background, ... |
| 98 | + [0, ... |
| 99 | + 0, ... |
| 100 | + thisEvent.barPosPix - cfg.aperture.barWidthPix / 2, ... |
| 101 | + cfg.screen.winRect(4)]); |
| 102 | + |
| 103 | + Screen('FillRect', cfg.aperture.texture, cfg.color.background, ... |
| 104 | + [thisEvent.barPosPix + cfg.aperture.barWidthPix / 2, ... |
| 105 | + 0, ... |
| 106 | + cfg.screen.winRect(3), ... |
| 107 | + cfg.screen.winRect(4)]); |
| 108 | + |
112 | 109 | otherwise |
113 | 110 |
|
114 | 111 | error('unknown aperture type: %s.', cfg.aperture.type); |
|
117 | 114 |
|
118 | 115 | case 'draw' |
119 | 116 |
|
120 | | - Screen('DrawTexture', cfg.screen.win, cfg.aperture.texture); |
| 117 | + if strcmp(cfg.aperture.type, 'bar') |
| 118 | + |
| 119 | + % Draw aperture and we rotate to match the required condition |
| 120 | + Screen('DrawTexture', cfg.screen.win, cfg.aperture.texture, ... |
| 121 | + cfg.screen.winRect, ... |
| 122 | + cfg.screen.winRect, ... |
| 123 | + thisEvent.condition - 90); |
| 124 | + else |
| 125 | + |
| 126 | + Screen('DrawTexture', cfg.screen.win, cfg.aperture.texture); |
| 127 | + |
| 128 | + end |
| 129 | + |
| 130 | + end |
| 131 | + |
| 132 | +end |
| 133 | + |
| 134 | +function cfg = apertureInit(cfg) |
| 135 | + |
| 136 | + switch cfg.aperture.type |
| 137 | + |
| 138 | + case 'circle' |
| 139 | + % we take the screen height as maximum aperture width if not |
| 140 | + % specified. |
| 141 | + if ~isfield(cfg.aperture, 'width') || isempty(cfg.aperture.width) |
| 142 | + cfg.aperture.width = cfg.screen.winRect(4) / cfg.screen.ppd; |
| 143 | + end |
| 144 | + cfg.aperture = degToPix('width', cfg.aperture, cfg); |
| 145 | + |
| 146 | + case 'ring' |
| 147 | + |
| 148 | + % Set parameters for rings |
| 149 | + if strcmp(cfg.aperture.type, 'ring') |
| 150 | + % scale of outer ring (exceeding screen until |
| 151 | + % inner ring reaches window boarder) |
| 152 | + cfg.ring.maxEcc = ... |
| 153 | + cfg.screen.FOV / 2 + ... |
| 154 | + cfg.aperture.width + ... |
| 155 | + log(cfg.screen.FOV / 2 + 1) ; |
| 156 | + % ring.CsFuncFact is used to expand with log increasing speed so |
| 157 | + % that ring is at ring.maxEcc at end of cycle |
| 158 | + cfg.ring.csFuncFact = ... |
| 159 | + 1 / ... |
| 160 | + ((cfg.ring.maxEcc + exp(1)) * ... |
| 161 | + log(cfg.ring.maxEcc + exp(1)) - ... |
| 162 | + (cfg.ring.maxEcc + exp(1))) ; |
| 163 | + end |
| 164 | + |
| 165 | + case 'bar' |
| 166 | + |
| 167 | + % Set parameters drifting bars |
| 168 | + cfg.aperture.barWidthPix = cfg.stimRect(3) / cfg.volsPerCycle; |
| 169 | + cfg.aperture.barPosPix = ... |
| 170 | + [0:cfg.aperture.barWidthPix:cfg.stimRect(3) - cfg.aperture.barWidthPix] + ... |
| 171 | + (cfg.screen.winRect(3) / 2 - cfg.stimRect(3) / 2) + ... |
| 172 | + cfg.aperture.barWidthPix / 2; %#ok<NBRAK> |
121 | 173 |
|
122 | | - % Screen('DrawTexture', cfg.screen.win, apertureTexture, ... |
123 | | - % cfg.screen.winRect, cfg.screen.winRect, current.apertureAngle - 90); |
| 174 | + % Width of bar in degrees of VA (needed for saving) |
| 175 | + cfg.aperture.width = cfg.aperture.barWidthPix / cfg.screen.ppd; |
| 176 | + cfg.aperture.barPos = ... |
| 177 | + (cfg.aperture.barPosPix - cfg.screen.center(1)) / ... |
| 178 | + cfg.screen.ppd; |
124 | 179 |
|
125 | 180 | end |
126 | 181 |
|
|
0 commit comments