Skip to content

Commit 0d60ba6

Browse files
committed
update apertureTexture
1 parent 8c805d6 commit 0d60ba6

File tree

1 file changed

+126
-67
lines changed

1 file changed

+126
-67
lines changed

src/aperture/apertureTexture.m

Lines changed: 126 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,69 @@
11
function [cfg, thisEvent] = apertureTexture(action, cfg, thisEvent)
2-
3-
transparent = [0 0 0 0];
2+
% [cfg, thisEvent] = apertureTexture(action, cfg, thisEvent)
3+
%
4+
%
45

56
switch action
6-
7+
78
case 'init'
8-
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
38-
9+
10+
cfg = apertureInit(cfg);
11+
3912
cfg.aperture.texture = Screen('MakeTexture', cfg.screen.win, ...
4013
cfg.color.background(1) * ones(cfg.screen.winRect([4 3])));
41-
14+
4215
case 'make'
43-
16+
17+
transparent = [0, 0, 0, 0];
18+
4419
xCenter = cfg.screen.center(1);
4520
yCenter = cfg.screen.center(2);
46-
21+
4722
switch cfg.aperture.type
48-
23+
4924
case 'none'
50-
25+
5126
Screen('Fillrect', cfg.aperture.texture, transparent);
52-
27+
5328
case 'circle'
54-
29+
5530
diameter = cfg.aperture.widthPix;
56-
31+
5732
if isfield(cfg.aperture, 'xPosPix')
5833
xCenter = cfg.screen.center(1) + cfg.aperture.xPosPix;
5934
end
6035
if isfield(cfg.aperture, 'yPosPix')
6136
yCenter = cfg.screen.center(2) + cfg.aperture.yPosPix;
6237
end
63-
38+
6439
Screen('FillOval', cfg.aperture.texture, transparent, ...
65-
CenterRectOnPoint([0 0 repmat(diameter, 1, 2)], ...
40+
CenterRectOnPoint([0, 0, repmat(diameter, 1, 2)], ...
6641
xCenter, yCenter));
67-
42+
6843
case 'ring'
69-
44+
7045
% expansion speed is log over eccentricity
7146
[cfg] = eccenLogSpeed(cfg, thisEvent.time);
72-
47+
7348
Screen('Fillrect', cfg.aperture.texture, cfg.color.background);
74-
49+
7550
Screen('FillOval', cfg.aperture.texture, transparent, ...
7651
CenterRectOnPoint( ...
77-
[0 0 repmat(cfg.ring.outerRimPix, 1, 2)], ...
52+
[0, 0, repmat(cfg.ring.outerRimPix, 1, 2)], ...
7853
xCenter, yCenter));
79-
54+
8055
Screen('FillOval', cfg.aperture.texture, [cfg.color.background 255], ...
8156
CenterRectOnPoint( ...
82-
[0 0 repmat(cfg.ring.innerRimPix, 1, 2)], ...
57+
[0, 0, repmat(cfg.ring.innerRimPix, 1, 2)], ...
8358
xCenter, yCenter));
84-
59+
8560
case 'wedge'
86-
61+
8762
cycleDuration = cfg.mri.repetitionTime * cfg.volsPerCycle;
88-
63+
8964
% Update angle for rotation of background and for apperture for wedge
9065
switch cfg.direction
91-
66+
9267
case '+'
9368
thisEvent.angle = 90 - ...
9469
cfg.aperture.width / 2 + ...
@@ -97,31 +72,115 @@
9772
thisEvent.angle = 90 - ...
9873
cfg.aperture.width / 2 - ...
9974
(thisEvent.time / cycleDuration) * 360;
100-
75+
10176
end
102-
77+
10378
Screen('Fillrect', cfg.aperture.texture, cfg.color.background);
104-
79+
10580
Screen('FillArc', cfg.aperture.texture, transparent, ...
10681
CenterRect( ...
107-
[0 0 repmat(cfg.stimRect(4), 1, 2)], ...
82+
[0, 0, repmat(cfg.stimRect(4), 1, 2)], ...
10883
cfg.screen.winRect), ...
10984
thisEvent.angle, ... % start angle
11085
cfg.aperture.width); % arc angle
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)]);
111108

112109
otherwise
113-
110+
114111
error('unknown aperture type: %s.', cfg.aperture.type);
115-
112+
116113
end
117-
114+
118115
case 'draw'
116+
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
119129

120-
Screen('DrawTexture', cfg.screen.win, cfg.aperture.texture);
121-
122-
% Screen('DrawTexture', cfg.screen.win, apertureTexture, ...
123-
% cfg.screen.winRect, cfg.screen.winRect, current.apertureAngle - 90);
130+
124131

132+
125133
end
126-
134+
127135
end
136+
137+
138+
function cfg = apertureInit(cfg)
139+
140+
switch cfg.aperture.type
141+
142+
case 'circle'
143+
% we take the screen height as maximum aperture width if not
144+
% specified.
145+
if ~isfield(cfg.aperture, 'width') || isempty(cfg.aperture.width)
146+
cfg.aperture.width = cfg.screen.winRect(4) / cfg.screen.ppd;
147+
end
148+
cfg.aperture = degToPix('width', cfg.aperture, cfg);
149+
150+
case 'ring'
151+
152+
% Set parameters for rings
153+
if strcmp(cfg.aperture.type, 'ring')
154+
% scale of outer ring (exceeding screen until
155+
% inner ring reaches window boarder)
156+
cfg.ring.maxEcc = ...
157+
cfg.screen.FOV / 2 + ...
158+
cfg.aperture.width + ...
159+
log(cfg.screen.FOV / 2 + 1) ;
160+
% ring.CsFuncFact is used to expand with log increasing speed so
161+
% that ring is at ring.maxEcc at end of cycle
162+
cfg.ring.csFuncFact = ...
163+
1 / ...
164+
((cfg.ring.maxEcc + exp(1)) * ...
165+
log(cfg.ring.maxEcc + exp(1)) - ...
166+
(cfg.ring.maxEcc + exp(1))) ;
167+
end
168+
169+
case 'bar'
170+
171+
% Set parameters drifting bars
172+
cfg.aperture.barWidthPix = cfg.stimRect(3) / cfg.volsPerCycle;
173+
cfg.aperture.barPosPix = ...
174+
[ 0:cfg.aperture.barWidthPix:cfg.stimRect(3) - cfg.aperture.barWidthPix ] + ...
175+
(cfg.screen.winRect(3) / 2 - cfg.stimRect(3) / 2) + ...
176+
cfg.aperture.barWidthPix / 2; %#ok<NBRAK>
177+
178+
% Width of bar in degrees of VA (needed for saving)
179+
cfg.aperture.width = cfg.aperture.barWidthPix / cfg.screen.ppd;
180+
cfg.aperture.barPos = ...
181+
(cfg.aperture.barPosPix - cfg.screen.center(1)) / ...
182+
cfg.screen.ppd;
183+
184+
end
185+
186+
end

0 commit comments

Comments
 (0)