File: VRHMDDemo.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 (144 lines) | stat: -rw-r--r-- 4,567 bytes parent folder | download
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
function VRHMDDemo(stereoscopic, checkerboard, withGazeTracking, deviceindex)
%
% VRHMDDemo([stereoscopic=1][, checkerboard=0][, withGazeTracking=0][, deviceindex=0])
%
% A very basic demo for the most basic setup of VR HMDs, e.g., the Oculus
% VR Rift DK2. It shows the absolute minimum of steps needed - one line of
% code - to use the first connected HMD as mono or stereo display.
%
% 'stereoscopic' if set to 1 (which is the default), configures the
% HMD as a stereoscopic display. A setting of 0 configures it as a
% monoscopic display.
%
% 'checkerboard' if set to 1 draws a checkboard pattern instead of the
% regular test image.
%
% The optional parameter 'withGazeTracking', if provided and non-zero, will
% enable some basic test of eye gaze tracking with VR HMD's which support
% eye tracking. Please note that this functionality is not available in
% official Psychtoolbox releases yet, at least not as of v3.0.19.1, and the
% api used in this demo is highly experimental and subject to backwards
% incompatible changes!
%
% 'deviceindex' if provided, selects the HMD with given index. Otherwise
% the first HMD (deviceindex 0) is chosen.
%
% The demo just renders one static simple 2D image, or image pair in
% stereoscopic mode, then displays it in a loop until a key is pressed.

% History:
% 05-Sep-2015  mk Written.
% 30-Mar-2017  mk Adapt to the reality of new VR runtimes.

% Setup unified keymapping and unit color range:
PsychDefaultSetup(2);

if nargin < 1 || isempty(stereoscopic)
  stereoscopic = 1;
end

if nargin < 2 || isempty(checkerboard)
  checkerboard = 0;
end

% Disable test of eye gaze tracking by default:
if nargin < 3 || isempty(withGazeTracking)
  withGazeTracking = 0;
end

if withGazeTracking
  % Tell that eyetracking is desired:
  reqGazeTracking = 'Eyetracking ';
else
  reqGazeTracking = '';
end

if nargin < 4
  deviceindex = [];
end

% Select screen with highest id as Oculus output display:
screenid = max(Screen('Screens'));

% Open our fullscreen onscreen window with black background clear color:
PsychImaging('PrepareConfiguration');

% Build final task requirements:
basicReqs = ['NoTimingSupport NoTimestampingSupport ' reqGazeTracking];

% We do collect timestamps for benchmarking, but don't require them to be especially precise or trustworthy:
if ~stereoscopic
  % Setup the HMD to act as a regular "monoscopic" display monitor
  % by displaying the same image to both eyes:
  hmd = PsychVRHMD('AutoSetupHMD', 'Monoscopic', basicReqs, [], [], deviceindex);
else
  % Setup for stereoscopic presentation:
  hmd = PsychVRHMD('AutoSetupHMD', 'Stereoscopic', basicReqs, [], [], deviceindex);
end

if isempty(hmd)
  fprintf('No support for VR, so can not run this demo. Bye.\n');
  return;
end

[win, rect] = PsychImaging('OpenWindow', screenid);
hmdinfo = PsychVRHMD('GetInfo', hmd);

% Disable gaze tracking test if unsupported by setup:
if withGazeTracking && ~hmdinfo.eyeTrackingSupported
  withGazeTracking = 0;
end

Screen('TextStyle', win, 1);
Screen('TextSize', win, 100);

if checkerboard
  % Apply regular checkerboard pattern as texture:
  bv = zeros(32);
  wv = ones(32);
  myimg = double(repmat([bv wv; wv bv],32,32) > 0.5);
  mytex = Screen('MakeTexture', win, myimg, [], 1);
end

% Render one view for each eye in stereoscopic mode:
vbl = [];
while ~KbCheck
  for eye = 0:stereoscopic
    Screen('SelectStereoDrawBuffer', win, eye);
    Screen('FillRect', win, [0 0 1]);
    if checkerboard
      Screen('DrawTexture', win, mytex);
    end
    Screen('FrameRect', win, [1 1 0], [], 20);
    if ~checkerboard
      Screen('FillOval', win, [0.5 0.5 0.5], CenterRect([0 0 700 700], rect));
      DrawFormattedText(win, sprintf('HELLO\nWORLD!\n%i', eye), 'center', 'center', [0 1 0]);
    end
    Screen('FillOval', win, [mod(GetSecs, 1) 0 0], CenterRect([0 0 10 10], rect));

    if withGazeTracking
      if eye == 0
        state = PsychVRHMD('PrepareRender', hmd, [], 4);
      end

      Screen('FrameArc',win, [0,1,1], CenterRect([0 0 500 500], rect), mod(GetSecs, 10) * 36, 10, 20);
      for i = 1:length(state.gazeStatus)
        % fprintf('Eye %i: status %i pos = %i %i\n', i, state.gazeStatus(i), state.gazePos{i}(1), state.gazePos{i}(2));
        % disp(state.gazeRayLocal{i}.gazeC);
        if state.gazeStatus(i) >= 3
          Screen('DrawDots', win, state.gazePos{i}, 5, [1, 0, i - 1], [], 1);
        end
      end
    end
  end
  vbl(end+1) = Screen('Flip', win); %#ok<AGROW>
end

KbStrokeWait;
sca;

close all;
plot(1000 * diff(vbl));
fps = 1 / mean(diff(vbl)) %#ok<NOPRT,NASGU>

end