I’d like to add a fragment shader to the processing pipeline so that it is executed automatically in each flip. I managed to run the fragment shader explicitly by specifying it as an argument during a call of Screen(‘DrawTexture’), but I failed to run it automatically in each flip.
To do so, I added the following task to PsychImaging.m:
floc = find(mystrcmp(reqs, 'EnableTetraShader'));
if ~isempty(floc)
shader = LoadGLSLProgramFromFiles('TetraShaderTrans', 1);
glUseProgram(shader);
glUniform1i(glGetUniformLocation(shader, 'Image'), 0);
glUniform1f(glGetUniformLocation(shader, 'Offset'), 640);
glUseProgram(0);
% Append our new shader and enable chain:
if outputcount > 0
% Need a bufferflip command:
Screen('HookFunction', win, 'AppendBuiltin', 'FinalOutputFormattingBlit', 'Builtin:FlipFBOs', '');
end
Screen('HookFunction', win, 'PrependShader', 'FinalOutputFormattingBlit', 'TetraShader', shader)
Screen('HookFunction', win, 'Enable', 'FinalOutputFormattingBlit');
outputcount = outputcount + 1;
end
and I called the corresponding task before opening the screen window:
PsychImaging('PrepareConfiguration');
PsychImaging('AddTask', 'General', 'EnableTetraShader');
PsychImaging('OpenWindow', screenNumber, 127.5);
According to the output of Screen(‘HookFunction’, win, ‘DumpAll’), the fragment shader is registered, but it doesn’t seem to be doing anything during the flips:
Hook chain FinalOutputFormattingBlit is currently enabled.
Following hook slots are assigned to this hook-chain:
=====================================================
Slot 0: Id='TetraShader' : GLSL-Shader : id=1 , luttex1=0 , blitter=
=====================================================
Is there something wrong with setting up the hook chain?
Here is the code of the fragment shader:
/* TetraShaderTrans.frag.txt - Shader for tetrachromatic projector:
*
*
*/
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect Image;
uniform float Offset;
/*out vec4 fragColor;*/
void main()
{
/* Get default texel read position (x,y): x is column, y is row of image. */
vec2 pos = gl_FragCoord.xy;
/* transpose x and y*/
pos = vec2(pos.y, pos.x);
pos.x = 1080-pos.x;
int channel = int(floor((pos.y-0.5)/Offset));
float start = mod(pos.y-0.5,Offset);
pos.y = (start)*3.0+0.5;
vec4 redChannel = texture2DRect(Image,pos);
pos.y = pos.y + 1.0;
vec4 greenChannel = texture2DRect(Image,pos);
pos.y = pos.y + 1.0;
vec4 blueChannel = texture2DRect(Image,pos);
if (channel == 0) {
gl_FragColor = vec4(redChannel.r, greenChannel.r, blueChannel.r, 1.0);
}
if (channel == 1) {
gl_FragColor = vec4(redChannel.g, greenChannel.g, blueChannel.g, 1.0);
}
if (channel == 2) {
gl_FragColor = vec4(redChannel.b, greenChannel.b, blueChannel.b, 1.0);
}
if (channel == 3) {
gl_FragColor = vec4(redChannel.a, greenChannel.a, blueChannel.a, 1.0);
}
}
Best,
Alexander