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
|