1

I need to draw an animated texture with many parameters. All of these parameters (matrix 10x200) will be changed in each frame.

I try to send them to fragment shader as uniforms with glUniform*fv but it seems it is too much. If I try to use fewer (let's say just 2 circles) everything works:

Matlab/Psychtoolbox-3 code:

%%
circ1pos = [100 100]; circ2pos = [200 200]; % circle positions
circ1color = [1 0 0]; circ2color = [0 1 0]; % circle colors
%%
global GL
PsychDefaultSetup(2);
Screen('Preference', 'SkipSyncTests', 1);
screenid = max(Screen('Screens'));
win=PsychImaging('OpenWindow', screenid, 0.5);

texShader = LoadGLSLProgramFromFiles('./circle.frag', 1);
glUseProgram(texShader);

glUniform2fv( glGetUniformLocation(texShader, 'circ1pos'),...
    1, single(circ1pos));
glUniform3fv( glGetUniformLocation(texShader, 'circ1color'),...
    1, single(circ1color));

glUniform2fv( glGetUniformLocation(texShader, 'circ2pos'),...
    1, single(circ2pos));
glUniform3fv( glGetUniformLocation(texShader, 'circ2color'),...
    1, single(circ2color));

glUseProgram(0);
tex=Screen('SetOpenGLTexture', win, [], 0, GL.TEXTURE_RECTANGLE_EXT, 1000, 1000, 1, texShader);

Screen('DrawTexture',win,tex);
Screen('Flip', win);

Fragment shader:

#version 120
uniform vec3 circ1color;
uniform vec3 circ2color;

uniform vec2 circ1pos;
uniform vec2 circ2pos;

void main()
{
    vec4 out_color = vec4(0,0,0,0);
    vec2 pos = gl_TexCoord[0].xy;
    // plot first circle
    float x0 = circ1pos.x;
    float y0 = circ1pos.y;
    float is_inside = (pos.x-x0)*(pos.x-x0)+(pos.y-y0)*(pos.y-y0)-1600;
    out_color=vec4(-circ1color*is_inside,1);

    // plot second circle
    x0 = circ2pos.x;
    y0 = circ2pos.y;
    is_inside = (pos.x-x0)*(pos.x-x0)+(pos.y-y0)*(pos.y-y0)-1600;
    out_color= out_color + vec4(-circ2color*is_inside,1);
    gl_FragColor= out_color;
}

I thought about using the sampler2d class to send the whole matrix, but I could not find any good explanation for Matlab/Psychtoolbox-3 and GLSL version 120.

If terms of my example - my problem is to send parameters of the large number of circles into fragment shader.

Update:

In this related question there is some discussion about passing the arrays to fragment shader. It seems I may use only 1D textures, as I need to use OpenGL2.1.

But the problem is that I could not find a normal explanation for glCopyTexSubImage2D() usage in Matlab/Psychtoolbox-3.

I tried the following:

arrXY = [100 200 200 100];
texture = glGenTextures(1);
glBindTexture(GL.TEXTURE_1D_ARRAY, texture);
glTexImage1D(GL.TEXTURE_1D, 0, GL.R32F, 4, 0, GL.RED, GL.FLOAT, single(arrXY));

But now I could not understand how to use these data in my fragment shader.

glTexImage2D variant:

I try to use glTexImage2D:

data = [1,0.5,0.4];
%%
global GL
PsychDefaultSetup(2);
Screen('Preference', 'SkipSyncTests', 1);
screenid = max(Screen('Screens'));
win=PsychImaging('OpenWindow', screenid, 0.5);

texShader = LoadGLSLProgramFromFiles('./circle2.frag', 1);
glUseProgram(texShader);
texture = glGenTextures(1);
glBindTexture(GL.TEXTURE_1D_ARRAY, texture);
glTexImage2D(GL.TEXTURE_1D_ARRAY, 0, GL.R32F, 3,1, 0, GL.RED, GL.FLOAT, single(data));
glUseProgram(0);
tex=Screen('SetOpenGLTexture', win, [], 0, GL.TEXTURE_RECTANGLE_EXT, 1000, 1000, 1, texShader);

Screen('DrawTexture',win,tex);
Screen('Flip', win);

circle2.frag

#version 120
uniform sampler2D data;
void main()
{
    vec3 texel = texture2D(data,vec2(0,0));    
    gl_FragColor= vec4(texel[0],0,0,0);
}

with this code I have 2 problems:

1) if I define texel like anything else, not vec4 shader did not compile:Incompatible types in initialization (and no available implicit conversion)

2) I expect the red color of the screen as a result of shader, but it is black.

What am I doing wrong?

zlon
  • 812
  • 8
  • 24
  • @NicolBolas thank You for a link, but I am still could not understand how to deal with my problem. – zlon Sep 23 '19 at 14:27

0 Answers0