OpenGL - GLSL, присваивающий переменной, нарушает позиционирование вершины

Однажды я делал проект в OpenGL версии 3.2, где использовал "sampler2DArray" для хранения нескольких изображений с одинаковыми размерами и рендеринга их с использованием текстурированных точек.

Сейчас я пытаюсь перенести этот проект на мой компьютер GNU / Linux. Этот компьютер поддерживает только до OpenGL версии до 2.1 и GLSL до версии 1.20 (в которой нет sampler2DArray). Насколько я знаю, нет способа обновить OpenGL для поддержки новых функций.

В настоящее время я пытаюсь использовать sampler3D для хранения моих изображений и использовать значение глубины для выбора нужного изображения.

Чтобы передать глубину текстуры из вершинного шейдера во фрагментный шейдер, я объявил "переменную" переменную с плавающей точкой, содержащую значение глубины (от 0,0 до 1,0).

Я рендеринг 4 изображений в местах: (-0,5, +0,5), (+0,5, +0,5), (-0,5, -0,5) и (+0,5, -0,5).

Кажется, работает метод переключения изображений (изменение переменной "index" изменяет изображение). Но по какой-то странной причине все изображения отображаются в (0.0, 0.0), а не в назначенных им местах. Эта проблема исчезает, когда я не назначаю переменную, содержащую значение глубины для текстуры, и устанавливаю значение глубины 0.0 в фрагментном шейдере.

Вот вершинный шейдер:

#version 120

attribute vec2 position
attribute float index
varying float v_index

void main()
{
    gl_Position = vec4(position, 0.0, 1.0);
    v_index = index; // Removing this assignment makes the images appear at their assigned locations.
}

Вот фрагментный шейдер:

#version 120

uniform sampler3D texture;
varying float v_index;

void main()
{
    gl_FragColor = texture3D(texture, vec3(gl_PointCoord, v_index));
}

Структура, которую я использую, представляет вершины:

struct vertex {
    GLfloat x;
    GLfloat y;
    GLfloat texture_index;
};

Призывы к glVertexAttribPointer функция (проблема может быть и здесь):

glBindAttribLocation(shader_program, 0, "position");
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (void *)0);
glBindAttribLocation(shader_program, 1, "index");
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (void *)(2 * sizeof(GLfloat));

Я также нашел очень похожий вопрос. Ответ, помеченный как "принятый", утверждает, что причина проблемы в том, что шейдеры имеют более 16 различных векторов (что не так для меня).

Вот ссылка: Странная ошибка в GLSL при назначении атрибута варьирующемуся вершинному шейдеру

1 ответ

Решение

Похоже, что ваши атрибуты местоположения не эффективны, и местоположения назначены на GL. Без назначения, index атрибут не используется, и только position один, так что очень вероятно, что он получает местоположение 0. Whe index фактически используется, может получить 0 (на nvidia эти местоположения, похоже, назначены в алфавитном порядке).

glBindAttribLocation() вызовы влияют только при связывании программы, поэтому они должны быть вызваны до glLinkProgram(), и вы должны повторно связать программу, когда вы хотите изменить те (которых вы действительно должны избегать). Код, который вы дали, предполагает, что он вызывается во время ваших обычных вызовов отрисовки, поэтому они никогда не влияют на связанную программу.

Другие вопросы по тегам