Отправить большую матрицу фрагментному шейдеру в GLSL версии 120 - PullRequest
1 голос
/ 23 сентября 2019

Мне нужно нарисовать анимированную текстуру с множеством параметров.Все эти параметры (матрица 10x200) будут изменены в каждом кадре.

Я пытаюсь отправить их во фрагментный шейдер в виде униформы с glUniform*fv, но, похоже, это слишком много.Если я пытаюсь использовать меньше (скажем, всего 2 круга), все работает:

Код Matlab / Psychtoolbox-3:

%%
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);

Фрагмент шейдера:

#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;
}

Я думал об использовании класса sampler2d для отправки всей матрицы, но не смог найти хорошего объяснения для Matlab / Psychtoolbox-3 и GLSL версии 120.

Если использовать условия моего примера - моя проблема заключается вотправьте параметры большого числа кругов в фрагментный шейдер.

Обновление:

В этом связанном вопросе обсуждается вопрос о передаче массивов в фрагментный шейдер.Кажется, я могу использовать только 1D текстуры, так как мне нужно использовать OpenGL2.1.

Но проблема в том, что я не смог найти нормальное объяснение для использования glCopyTexSubImage2D() в Matlab / Psychtoolbox-3.

Я попробовал следующее:

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));

Но теперь я не мог понять, как использовать эти данные в моем фрагментном шейдере.

вариант glTexImage2D:

Я пытаюсь использовать 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);
}

с этим кодом у меня 2 проблемы:

1) если я определю texel, как и все остальное, не vec4 шейдер не скомпилируется: Incompatible types in initialization (and no available implicit conversion)

2) Я ожидаю красный цвет экрана в результате шейдера,но он черный.

Что я делаю не так?

...