File: AlphaImageTutorial.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 (249 lines) | stat: -rw-r--r-- 8,208 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
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
function AlphaImageTutorial
% AlphaImageTutorial
%
% Display a gaussian masked image, locked to the cursor position,
% using the Screen('DrawTexture') command.
%
% This illustrates an application of OpenGL Alpha blending by displaying
% an image masked with a gaussian transparency mask.
%
% In each frame, first the image is drawn. Then a texture acting as a
% transparency mask is drawn "over" the image, leaving only selected
% parts of the image.
%
% Please note that we only use two textures: One holding the image,
% the other defining the mask.
%
% see also: PsychDemos, MovieDemo, DriftDemo

% HISTORY
%
% mm/dd/yy
%
%  6/28/04    awi     Adapted from Denis Pelli's DriftDemo.m for OS 9
%  7/18/04    awi     Added Priority call.  Fixed.
%  9/8/04     awi     Added Try/Catch, cosmetic changes to comments and see also.
%  1/4/05     mk      Adapted from awi's DriftDemoOSX.
%  24/1/05    fwc     Adapted from AlphaImageDriftDemoOSX, bug in
%                     drawtexture prevents it from doing what I really want
%  28/1/05    fwc     Yeah, works great now after bug was removed from
%                     drawtexture by mk, cleaned up code
%  02/07/05   fwc     slightly simplified demo by removing some options
%                       such as automode
%  3/30/05    awi     Added 'BlendFunction' call to set alpha blending mode
%                     The default alpha blending mode for Screen has
%                     changed, this added call sets it to the previous
%                     default.
%  4/23/05    mk      Small modifications to make it compatible with
%                     "normal" Screen.mexmac.
%  12/31/05   mk      Small modifications to make it compatible with Matlab-5
%  10/14/06   dhb     Rename without OSX bit.  Fewer warnings.
%             dhb     More comments, cleaned.

% PsychDefaultSetup(featurelevel) - Perform standard setup for Psychtoolbox, 
% the feature level of 2 sets PTB up to use an unclamped 0 - 1 color range.
PsychDefaultSetup(2);

% Screen is able to do a lot of configuration and performance checks on
% open, and will print out a fair amount of detailed information when
% it does.  These commands supress that checking behavior and just let
% the demo go straight into action.  See ScreenTest for an example of
% how to do detailed checking.
oldVisualDebugLevel = Screen('Preference', 'VisualDebugLevel', 3);
oldSupressAllWarnings = Screen('Preference', 'SuppressAllWarnings', 1);
oldSkipSyncTests = Screen('Preference', 'SkipSyncTests', 2);

% Standard coding practice, use try/catch to allow cleanup on error.
try
	% Say hello in command window
	fprintf('\nAlphaImageDemo\n');
	
	% Get the list of screens and choose the one with the highest screen number.
	% Screen 0 is, by definition, the display with the menu bar. Often when
	% two monitors are connected the one without the menu bar is used as
	% the stimulus display.  Chosing the display with the highest dislay number is
	% a best guess about where you want the stimulus displayed.
	screenNumber=max(Screen('Screens'));
	
	% Open a double buffered fullscreen window and draw a gray background
	% and front and back buffers.
	[w, wRect]=PsychImaging('OpenWindow',screenNumber, 0.5, [], 32, 2);
	
	%This is our alpha blending mode
	Screen(w,'BlendFunction',GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	
	% Find the color values which correspond to white, gray and black.
	black=BlackIndex(w);
	gray=GrayIndex(w);
	white=WhiteIndex(w);
	
	% Import image and and convert it, stored in
	% MATLAB matrix, into a Psychtoolbox OpenGL texture using 'MakeTexture';
	myimgfile = [ PsychtoolboxRoot 'PsychDemos' filesep 'AlphaImageDemo' filesep 'konijntjes1024x768.jpg'];
	fprintf('Using image ''%s''\n', myimgfile);
	imdata=imread(myimgfile);
	
	% Crop image if it is larger then screen size. There's no image scaling
	% in maketexture
	[iy, ix, iz]=size(imdata); %#ok<NASGU>
	[wW, wH]=WindowSize(w);
	if ix>wW || iy>wH
		fprintf('Image size exceeds screen size\n');
		fprintf('Image will be cropped\n');
	end
	if ix>wW
		cl=round((ix-wW)/2);
		cr=(ix-wW)-cl;
	else
		cl=0;
		cr=0;
	end
	if iy>wH
		ct=round((iy-wH)/2);
		cb=(iy-wH)-ct;
	else
		ct=0;
		cb=0;
	end
	
	% Set up texture and rects
	imagetex=Screen('MakeTexture', w, imdata(1+ct:iy-cb, 1+cl:ix-cr,:));
	tRect=Screen('Rect', imagetex);
	[ctRect, dx, dy]=CenterRect(tRect, wRect);
	
	% We create a Luminance+Alpha matrix for use as transparency mask:
	% Layer 1 (Luminance) is filled with luminance value 'gray' of the
	% background.
	ms = 100;
	transLayer = 2;
	[x,y] = meshgrid(-ms:ms, -ms:ms);
	maskblob = ones(2*ms+1, 2*ms+1, transLayer) * gray;
	size(maskblob);
	
	% Layer 2 (Transparency aka Alpha) is filled with gaussian transparency
	% mask.
	xsd = ms/2.0;
	ysd = ms/2.0;
	maskblob(:,:,transLayer)= white - exp(-((x/xsd).^2)-((y/ysd).^2))*white;
	
	% Build a single transparency mask texture
	masktex=Screen('MakeTexture', w, maskblob);
	mRect=Screen('Rect', masktex);
	fprintf('Size image texture: %d x %d\n', RectWidth(tRect), RectHeight(tRect));
	fprintf('Size  mask texture: %d x %d\n', RectWidth(mRect), RectHeight(mRect));
	
	% Blank sceen
	Screen('FillRect',w, gray);
	Screen('Flip', w);
	
	% initialize mouse position at center
	[a,b]=WindowCenter(w);
	SetMouse(a,b,screenNumber);
	HideCursor;
	
	% Bump priority for speed
	priorityLevel=MaxPriority(w);
	Priority(priorityLevel);
	
	% Pre-load textures
	Screen('DrawTexture', w, imagetex);
	Screen('DrawTexture', w, masktex);
	Screen('FillRect',w, gray);
	Screen('Flip', w);
	
	mode = 0;
	
	% Main mouse tracking loop
	mxold=0;
	myold=0;
	while (1)
		% We wait at least 10 ms each loop-iteration so that we
		% don't overload the system in realtime-priority:
		WaitSecs(0.01);
		
		% We only redraw if mouse has been moved:
		[mx, my, buttons]=GetMouse(screenNumber);
		if (mx~=mxold || my~=myold)
			myrect=[mx-ms my-ms mx+ms+1 my+ms+1]; % center dRect on current mouseposition
			dRect = ClipRect(myrect,ctRect);
			sRect=OffsetRect(dRect, -dx, -dy);
			
			if ~IsEmptyRect(dRect)
				
				if mode == 0
					% Draw whole image:
					Screen('DrawTexture', w, imagetex);
					% Useful info for user about how to quit.
					Screen('DrawText', w, 'No mask Visible.  Click mouse to begin...', 20, 20, black);
				end
				
				if mode == 1
					% Draw whole image:
					Screen('DrawTexture', w, imagetex);
					
					% Draw selected aperture rectangle:
					Screen('FillRect', w, [1 0 0 0.25], dRect);
					% Useful info for user about how to quit.
					Screen('DrawText', w, 'Red FillRect with 0.25 alpha.  Click mouse for next mode...', 20, 20, black);
				end
				
				if mode >= 2
					% Draw image for current frame:
					Screen('DrawTexture', w, imagetex, sRect, dRect);
					if mode==2;Screen('DrawText', w, 'No mask, just destination rect.  Click mouse for next mode...', 20, 20, black);end
				end
				
				if mode == 3
					% Overdraw -- and therefore alpha-blend -- with gaussian alpha mask
					Screen('DrawTexture', w, masktex, [], myrect);
					% Useful info for user about how to quit.
					Screen('DrawText', w, 'Gaussian mask.  Click mouse to exit...', 20, 20, black);
				end
							
				% Show result on screen:
				Screen('Flip', w);
			end
		end
		mxold=mx;
		myold=my;
		
		% Break out of loop on mouse click
		if find(buttons)
			while any(buttons)
				[mx, my, buttons]=GetMouse(screenNumber);
			end
			
			mode = mode + 1;
			
			if mode == 4
				break;
			end
		end
	end
	
	% The same command which closes onscreen and offscreen windows also
	% closes textures.
	sca;
	ShowCursor;
	Priority(0);
	
	% Restore preferences
	Screen('Preference', 'VisualDebugLevel', oldVisualDebugLevel);
	Screen('Preference', 'SuppressAllWarnings', oldSupressAllWarnings);
	Screen('Preference', 'SkipSyncTests', oldSkipSyncTests);
	
	% This "catch" section executes in case of an error in the "try" section
	% above.  Importantly, it closes the onscreen window if it's open.
catch
	
	sca;
	ShowCursor;
	Priority(0);
	
	% Restore preferences
	Screen('Preference', 'VisualDebugLevel', oldVisualDebugLevel);
	Screen('Preference', 'SuppressAllWarnings', oldSupressAllWarnings);
	Screen('Preference', 'SkipSyncTests', oldSkipSyncTests);

	psychrethrow(psychlasterror);
end