File: BitsPlusMovieDemo.m

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (171 lines) | stat: -rw-r--r-- 6,477 bytes parent folder | download | duplicates (5)
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
% BitsPlusMovieDemo
%
% BitsPlusMovieDemo displays a counterphase flickering grating, by lookup
% table animation, using the Bits++ box.
%
% Note that you need to precompute the cluts and write them into
% offscreen memory in advance, so that the blits happen fast.  In
% this example, each clut goes into its own offscreen window.  In
% real applications, we have found that the precomputation is considerably
% faster if we allocate one large offscreen window and put each clut
% into a different rect inside of it.

% 9/20/02  dhb  Version created from ClutMovieDemo.
% 10/xx/02 jmh  Fixed it up.
% 11/4/02  dhb, jmh Comments, etc.
% 9/20/03  dhb  No more calls to BitsPlus mex file.
% 18/4/05  ejw  Converted it to run with OSX version of Psychtoolbox

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);

% 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.   
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);

% Generate a uniform clut to hide the grating for the moment
offClut = ones(256,3)*(2^16-1)/2;
BitsPlusSetClut(window,offClut);

% find out how big the window is
[screenWidth, screenHeight]=Screen('WindowSize', window);

% textures can't seem to be bigger than the screen, though they have to be
% square. So the max texture size is the smaller of the screen dimensions!!
max_texture_size = min([screenWidth screenHeight]);

% Create a sinusoidal image in a Matlab matrix. The grating is
% scaled between 1 and 255. The creation happens in two steps. First
% create a sinusoidal vector, then replicate this vector to produce a
% sinusoidal image. The replication is done by an outer product. This is
% not the fastest way to do it in Matlab, but it is a little clearer.

% because we are going to borrow the top line of the image to encode a
% LUT, we need to make the image at least 524 pixels square.
nPixels = max_texture_size;
cyclesPerImage = 4;
sinVector = 1+(1+sin(2*pi*cyclesPerImage*(1:nPixels)/nPixels))/2*254;
sinImage = ones(nPixels,1)*sinVector;

% Create a set of color lookup tables (cluts) for animating the
% grating. Each clut starts life as a 256 by three matrix. But
% since we write them into the frame buffer to talk to the Bits++
% box, we then create an offscreen window for each clut and write
% it in.  This needs to be done in advance so that the blit of
% the lookup table is fast. 
%
% The computed set of cluts produces one cycle of counterphase flicker.
% We also create a uniform clut (offClut) to initialize the display.
%
% The variable nCluts determines the number of temporal quantization intervals.
%
% This routine does not do gamma correction -- it's purpose is just
% to show how to interface to the Bits++.
nCluts = 80;
theCluts = zeros(256,3,nCluts);
theContrasts = sin(2*pi*(0:nCluts-1)/nCluts);
fprintf('Computing %g cluts: ',nCluts);

% Draw grating onto the screen using PsychToolbox.
% We don't see it at this stage because we've got
% a uniform clut in the Bits++.
textureIndex= Screen('MakeTexture',whichScreen,sinImage);
Screen('DrawTexture',window,textureIndex);
Screen(window,'Flip');

% Loop through, compute clut, make textures including these LUTs.
for i = 1:nCluts
	if (rem(i,10) == 0)
		fprintf('%g ',i);
	end
	contrast = theContrasts(i);
	lowValDev = (1-contrast)/2;
	highValDev = (1+contrast)/2;
    
    % =====================================================
    % CODE NEEDED HERE !
    % "clutEntries" should be modified to give the inverse
    % characteristic of the monitor.
    % =====================================================    
	clutEntries = round(linspace(lowValDev*(2^16-1),highValDev*(2^16-1),256)');
    
	theCluts(:,:,i) = [clutEntries clutEntries clutEntries];
	bitsPlusClutRow(i,:,:) = BitsPlusEncodeClutRow(theCluts(:,:,i));  % converts to 1X524X3
    
    % copy the encoded LUT to the top line of the texture
    sinImage(1,1:524,1:3) = bitsPlusClutRow(i,:,:);
    
    % create the texture
    w(i)= Screen('MakeTexture',whichScreen,sinImage);    
    
end
fprintf('. Done.\n');

% Animate the clut.
nCycles=8;
clutCounter = 1;
for i=1:nCluts*nCycles
    Screen('DrawTexture',window,w(clutCounter));
   	Screen(window,'Flip');
	if (clutCounter == nCluts); clutCounter = 1; else; clutCounter = clutCounter +1; end
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 Bits++ 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
    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