Мне нужно нарисовать анимированную текстуру с множеством параметров.Все эти параметры (матрица 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) Я ожидаю красный цвет экрана в результате шейдера,но он черный.
Что я делаю не так?