/usr/share/psychtoolbox-3/PsychOpenGL/LoadGLSLProgramFromFiles.m is in psychtoolbox-3-common 3.0.9+svn2579.dfsg1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | function handle = LoadGLSLProgramFromFiles(filenames, debug, extraShaders)
% handle = LoadGLSLProgramFromFiles(filenames [, debug] [, extraShaders])
% Loads a GLSL OpenGL shading language program. All shader definition files in
% 'filenames' are read, shaders are built for each definition and all
% shaders are linked together into a new GLSL program. Returns a handle to
% the new program, if successfull. The optional 'debug' flag allows to enable
% debugging output: Zero = no output, 1 = a bit of outpt, 2 = detailed
% output, 3 = Don't compile and link anymore, but print out the shaders
% source code as OpenGL would see it.
%
% The program can then be used at any time by calling glUseProgram(handle). One
% can switch back to the standard OpenGL fixed-function pipeline by calling
% glUseProgram(0). The same handles can be passed to the
% Screen('MakeTexture', ...), Screen('DrawTexture', ...); et al. routines
% to define procedural textures - or some processing operations on them
% via the 'textureShader' argument -- See 'help ProceduralShadingAPI' for
% more info about procedural texturing. The handle is also used to build
% GLOperators for Screen('TransformTexture') or as plugins for the imaging
% pipeline: See 'help CreateGLOperator' or 'help AddToGLOperator' for info.
%
% 'filenames' can have one of two formats: If filenames is a array of
% strings that define the names of the shaders to use, then all shader
% files are loaded, compiled and linked into a single program. E.g.,
% shaderfiles={ 'myshader.vert' , 'myothershader.frag'}; will try to load
% the two shaderfiles myshader.vert and myothershader.frag and link them
% into a valid program.
%
% If only a single filename is given, then all shaders beginning with that
% name are linked into a program. E.g., shaderfiles = 'Phonglighting' will
% try to link all files starting with Phonglighting.
%
% The optional argument 'extraShaders' if present, should be a vector of
% additinal shader handles - Handles returned by the LoadShaderFromFile()
% or by your self-compiled shaders via glCompileShader(). All precompiled
% shaders referenced by those handles get also linked into the final GLSL
% program.
% 29-Mar-2006 written by MK
global GL;
if isempty(GL)
% Load & Initalize constants and moglcore, but don't set the 3D gfx
% flag for Screen():
InitializeMatlabOpenGL([], [], 1);
end;
if nargin < 2
debug = [];
end;
if isempty(debug)
debug = 0;
end
if nargin < 1
filenames = [];
end
if isempty(filenames)
error('No filenames for GLSL program provided! Aborted.');
end;
if nargin < 3
extraShaders = [];
end
% Make sure we run on a GLSL capable system.
AssertGLSL;
% Create new program object and get handle to it:
handle = glCreateProgram;
if handle <= 0
fprintf('The handle created by glCreateProgram is %i -- An invalid handle!\n', handle);
error('LoadGLSLProgramFromFiles: glCreateProgram failed to create a valid program object! Something is wrong with your graphics drivers!');
end
if ischar(filenames)
% One single name given. Load and link all shaders starting with that
% name:
if debug>1
fprintf('Compiling all shaders matching %s * into a GLSL program...\n', filenames);
end;
% Add default shader path if no path is specified as part of
% 'filenames':
if isempty(fileparts(filenames))
filenames = fullfile(PsychtoolboxRoot,'PsychOpenGL','PsychGLSLShaders', filenames);
end;
% Fixup use of wrong fileseparators for platform:
if IsWin
prep = strfind(filenames, '/');
filenames(prep) = filesep;
else
prep = strfind(filenames, '\');
filenames(prep) = filesep;
end
shaderobjs=dir([filenames '*']);
shaderobjpath = [fileparts([filenames '*']) filesep];
numshaders=size(shaderobjs,1)*size(shaderobjs,2);
if numshaders == 0
fprintf('\n\n\nIn LoadGLSLProgramFromFiles: When trying to load shaders matching %s ...\n', filenames);
error('Could not find any shader definition files matching that name. Check spelling.');
end
filenames=[];
for i=1:numshaders
[dummy1 curname curext] = fileparts(shaderobjs(i).name);
shadername = [curname curext];
filenames{i} = [shaderobjpath shadername]; %#ok<AGROW>
end;
end;
% Any additional shader handles provided? If so, we attach them first,
% before the shaders specified via files. Normally attachment order
% shouldn't matter, but due to a driver bug in many 169.x and 175.x NVidia
% drivers for Windows, it does. This is a known GLSL linker bug, cfe.
%
% http://www.stevestreeting.com/2007/12/27/nvidia-16921-driver-bug-in-glsl/
%
% The workaround is to attach shaders that define subfunctions (are part of
% a library of common functions) first, before the shaders utilizing them.
% Our color correction shaders are passed as extraShaders, so it is crucial
% to attach extraShaders first to workaround this driver bug.
if ~isempty(extraShaders)
% Attach all of them as well:
for i=1:length(extraShaders)
glAttachShader(handle, extraShaders(i));
end
end
% Load, compile and attach each single shader of each single file:
for i=1:length(filenames)
shadername = char(filenames(i));
% We only load the shader if its name does not end in tilde or .asv,
% because that would mean it is a Matlab- or emacs backup file...
if (shadername(end)~='~') & (isempty(strfind(shadername, '.asv'))) %#ok<AND2>
% Load, compile and link the shader:
if debug < 3
shdebug = 1;
else
shdebug = debug;
end
shader = LoadShaderFromFile(shadername, [], shdebug);
glAttachShader(handle, shader);
end;
end;
if debug > 1
% We need to temporarily raise moglcores debuglevel to 2 to get extended
% error/validation information:
oldDebug = InitializeMatlabOpenGL(-1);
moglcore('DEBUGLEVEL', 2);
% Link the program:
glLinkProgram(handle);
% Restore old debuglevel for moglcore:
moglcore('DEBUGLEVEL', oldDebug);
else
% Link the program without raised debug level for moglcore:
glLinkProgram(handle);
end
% Ready to use it? Hopefully.
return;
|