1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
|
% demoMonoCSF
% Draws a variant of a Campbell-Robson CSF chart using a Bits++.
% -----------------------------------------------------------------------------
% This demonstration illustrates the use of the high bit depth drawing modes
% available on the Bits++ to display (a variant of) the Campbell-Robson
% Contrast Sensitivity Function chart. This particular demo uses the high
% bit depth mono drawing mode. (14bitGreyScaleMode). Another similar
% demonstration is available that uses the high resolution colour mode
% (42bitColourMode).
%
% View the source code for this file for pointers on how to use the high bit
% depth mono drawing mode.
% Please be aware that in this source description, some of the CSF chart
% parameters have been modified to improve it's appearance on screen.
% Please do not rely on this file as a reference for how to produce a CSF
% chart.
% originally written by wp for Visage
% converted to Bits++ and OSX Psychtoolbox by ejw
clear; close all
% Define screen
whichScreen=max(Screen('Screens'));
% Find the color values which correspond to white and black. Though on OS
% X we currently only support true color and thus, for scalar color
% arguments,
% black is always 0 and white 255, this rule is not true on other platforms will
% not remain true on OS X after we add other color depth modes.
white=WhiteIndex(whichScreen);
black=BlackIndex(whichScreen);
gray=GrayIndex(whichScreen);
% Open up the a window on the screen.
% This is done by calling the Screen function of the Psychophysics
% Toolbox. We need to open the onscreen window first, so that
% the offscreen storage allocated subsequently is properly
% matched to the onscreen frame buffer.
[window,screenRect] = Screen('OpenWindow',whichScreen,128,[],32,2);
% THE FOLLOWING STEP IS IMPORTANT.
% make sure the graphics card LUT is set to a linear ramp
% (else the encoded data will not be recognised by Bits++).
% There is a bug with the underlying OpenGL function, hence the scaling 0 to 255/256.
% This demo will not work using a default gamma table in the graphics card,
% or even if you set the gamma to 1.0, due to this bug.
% This is NOT a bug with Psychtoolbox!
Screen('LoadNormalizedGammaTable',window,linspace(0,(255/256),256)'*ones(1,3));
% draw a gray background on front and back buffers
Screen('FillRect',window, gray);
Screen('Flip', window);
Screen('FillRect',window, gray);
% =================================================================
% CODE NEEDED HERE !
% "linear_lut" should be replaced here with one giving the inverse
% characteristic of the monitor.
% =================================================================
% restore the Mono++ overlay LUT to a linear ramp
linear_lut = repmat(round(linspace(0, 2^16 -1, 256))', 1, 3);
BitsPlusSetClut(window,linear_lut);
% find out how big the window is
[POINTS_ACROSS, POINTS_DOWN]=Screen('WindowSize', window);
% ===========================
% DEFINE SPATIAL FREQUENCY GP
% ===========================
SF_LOW = 1.5;
SF_HIGH = 300;
SF_BASE = (SF_HIGH/SF_LOW) .^ (1/POINTS_ACROSS); % base
SF_POW = [1:POINTS_ACROSS]; % power
SF_FORM = SF_BASE .^ SF_POW; % functional form
SF_MUL = (SF_LOW/SF_BASE); % scaling factor
SF_VALU = SF_FORM * SF_MUL; % values
% ==================
% DEFINE CONTRAST GP
% ==================
CT_LOW = 1/1024;
CT_HIGH = 1;
CT_BASE = (CT_HIGH/CT_LOW) .^ (1/POINTS_DOWN); % base
CT_POW = [1:POINTS_DOWN]; % power
CT_FORM = CT_BASE .^ CT_POW; % functional form
CT_MUL = (CT_LOW/CT_BASE); % scaling factor
CT_VALU = CT_FORM .* CT_MUL; % values
% ============================
% FORM IMAGE FROM PROGRESSIONS
% ============================
[XGRID,YGRID] = meshgrid(sin(SF_VALU),CT_VALU); % CT & SF are orthogonal
IMAGE = XGRID .* YGRID; % contrast modulates amplitude
IMAGE = (IMAGE + 1) / 2; % map values to between 0 and 1.
% ==================================================================
% CODE NEEDED HERE !
% "IMAGE" should be corrected here for the inverse characteristic of
% the monitor.
% ==================================================================
% encode the image in mono++ format
encoded_image = BitsPlusPackMonoImage(IMAGE*((2^16)-1));
% put the csf chart image up on the back buffer
Screen('PutImage', window, encoded_image);
% make the make buffer current during the next blanking period
Screen(window,'Flip');
fprintf('Displaying CSF chart, hold a key to exit \n');
while(~KbCheck)
end;
% if the system only has one screen, set the LUT in Bits++ to a linear ramp
% if the system has two or more screens, then blank the screen.
if (whichScreen == 0)
% =================================================================
% CODE NEEDED HERE !
% "linear_lut" should be replaced here with one giving the inverse
% characteristic of the monitor.
% =================================================================
% restore the Mono++ overlay LUT to a linear ramp
linear_lut = repmat(round(linspace(0, 2^16 -1, 256))', 1, 3);
BitsPlusSetClut(window,linear_lut);
% draw a gray background on front and back buffers to clear out any old LUTs
Screen('FillRect',window, gray);
Screen('Flip', window);
Screen('FillRect',window, gray);
Screen('Flip', window);
% Close the window.
Screen('CloseAll');
else
% Blank the screen (zero the Mono++ overlay LUT),
% - doesn't actually quite blank the screen.
BitsPlusSetClut(window,zeros(256,3));
% draw a black background on front and back buffers to clear out any old LUTs
Screen('FillRect',window, black);
Screen('Flip', window);
Screen('FillRect',window, black);
Screen('Flip', window);
Screen('CloseAll');
end
|