File: BitsLutStereoDemo.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 (210 lines) | stat: -rw-r--r-- 7,517 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
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
% BitsLutStereoDemo
%
% demonstration of displaying a precalculated texture based movie, whilst
% separately animating the LUT, and whilst
% controlling the FE1 goggles using a Tlock packet.
%
% For use with the OSX version of Psychtoolbox.
% tested with version 1.0.5, Matlab release 14 sp 2 and OSX 10.3.9
% uses the hidden 'LoadNormalizedGammaTable' screen function.
%
% Please note that this demo needs the Bits++ from Cambridge Research Systems!!
%
% Sections have been lifted from the OSX movie demo etc.
%
% 26/04/2005    ejw     wrote it.

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 Bits++ 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
[screenWidth, screenHeight]=Screen('WindowSize', window);

[y,x] = meshgrid(-(screenHeight - 1)/2: (screenHeight - 1)/2, -(screenWidth - 1)/2: (screenWidth - 1)/2);

blend_image = sqrt((exp(-abs(5*x/((screenWidth - 1)/2))).^2) + (exp(-abs(5*y/((screenHeight - 1)/2))).^2));

% encode the image in mono++ format
encoded_image = BitsPlusPackMonoImage(blend_image*((2^16)-1));

Screen('PutImage', window, encoded_image);
Screen(window,'Flip');

Screen('PutImage', window, encoded_image);

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

% pre calculate two counter rotating gratings

% some graphics cards have a hardware texture size limit of 256 square
% (any bigger and it is slow). Be aware that textures use up RAM very quickly.
texture_size=180;   % the diagonal dimension of 180 x 180 is 255, which is our
                    % maximum number of LUT entries

if (max_texture_size < texture_size)
    error('screen must have a minimum resolution of 256');
end 

% check that the screen width is at least 524 pixels
if (screenWidth < 524)
    error('window is not big enough to encode the Bits++ CLUT');
end 

image=zeros(texture_size,texture_size,3);
[x,y] = meshgrid(-(texture_size - 1)/2: (texture_size - 1)/2, -(texture_size - 1)/2: (texture_size - 1)/2);

% number of cycles of sine wave in patch
speed=10/359;
cycles_across=5;
 
% unfortunately we have to iterate this, to generate the textures??
for orient=0:359
    fprintf('Calculating angle %d\n',orient);
    
    phase = round(128 + sin(pi*orient/180)*y + cos(pi*orient/180)*x);
    
    image(:,:,1) = 0;
    image(:,:,2) = 0;
    image(:,:,3) = phase;     
  
    left(orient + 1)= Screen('MakeTexture',whichScreen,image); 

    phase = round(128 - sin(pi*orient/180)*y + cos(pi*orient/180)*x);
    
    image(:,:,1) = 0;
    image(:,:,2) = 0;
    image(:,:,3) = phase; 
    
    right(orient + 1)= Screen('MakeTexture',whichScreen,image); 
end 

% create some drifting sinewave LUTs
[index,offset,gun] = meshgrid(0: 255, 0: 359, 1: 3);

% =================================================================
% CODE NEEDED HERE !
% the code needs to apply the inverse characteristic of the monitor.
% =================================================================

luts = (2^16 - 1) * (sin(cycles_across * 2 * pi * (index/255 + (offset*speed))) + 1) / 2;

% now quickly display the previously calculated textures,
% addind the control for the goggles

fprintf('Displaying counter-rotating gratings, hold a key to exit \n');


while(~KbCheck)
    for orient= 1:360
        % encode the LUT
        newClutRow = BitsPlusEncodeClutRow(squeeze(luts(orient,:,:)));

        rect=[0 0 size(newClutRow,2) 1];
        Screen('PutImage', window, newClutRow, rect, rect);       
        
        Screen('DrawTexture',window,left(orient));
        % bitsgoggles adds the one line image to control the digital o/p
        % then calls 'Flip'
        % Note that bitsGoggles controls the goggle state for the frame
        % >after< it is displayed, hence we set the right goggle open now
        bitsGoggles(1,0,window);
        
        % encode the LUT
        newClutRow = BitsPlusEncodeClutRow(squeeze(luts(orient,:,:)));

        rect=[0 0 size(newClutRow,2) 1];
        Screen('PutImage', window, newClutRow, rect, rect);        
    
        Screen('DrawTexture',window,right(orient));
        % bitsgoggles adds the one line image to control the digital o/p
        % then calls 'Flip'
        % Note that bitsGoggles controls the goggle state for the frame
        % >after< it is displayed, hence we set the left goggle open now        
        bitsGoggles(0,1,window);    
    end
end

% reset the digital output data
Mask=0;
Command=0;
Data=zeros(1,248);
bitsEncodeDIO(Mask,Data,Command, window);

% 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