Можете ли вы использовать glVertexAttribPointer для присвоения меньшего вектора большему?

#opengl-es #glsl #opengl-es-2.0

#opengl-es #glsl #opengl-es-2.0

Вопрос:

Из раздела 5.8 Языка затенения OpenGL® ES (v1.00, r17) [PDF] (выделено мной):

Оператор присваивания сохраняет значение rvalue-выражения в l-значение и возвращает r-значение с типом и точностью lvalue-выражения. Lvalue-expression и rvalue-expression должны иметь один и тот же тип. Все желаемые преобразования типов должны быть указаны явно с помощью конструктора.

Похоже, что делать что-то подобное было бы не законно:

 vec3 my_vec3 = vec3(1, 2, 3);
vec4 my_vec4 = my_vec3;
  

И чтобы сделать это законным, вторая строка должна быть чем-то вроде:

 vec4 my_vec4 = vec4(my_vec3, 1); // add 4th component
  

Я предположил, что у glVertexAttribPointer были аналогичные требования. То есть, если бы вы присваивали vec4 этому size параметру, он должен был бы быть равен 4.

Затем я наткнулся на образец GLES20TriangleRenderer для Android. Некоторые соответствующие фрагменты:

 attribute vec4 aPosition;

maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");

GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
        TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
  

Итак, aPosition это vec4 , но вызов glVertexAttribPointer , который используется для его установки, имеет size значение 3. Этот код правильный, GLES20TriangleRenderer полагается на неопределенное поведение или есть что-то еще, чего мне не хватает?

Ответ №1:

Размер данных атрибута, передаваемых шейдеру, не обязательно должен соответствовать размеру атрибута в этом шейдере. Вы можете передать 2 значения (из glVertexAttribPointer ) в атрибут, определенный как vec4 ; оставшиеся два значения равны нулю, за исключением компонента W, который равен 1. И аналогично, вы можете передать 4 значения vec2 атрибуту; дополнительные значения отбрасываются.

Таким образом, вы можете смешивать и сопоставлять атрибуты вершин с загруженными значениями сколько угодно.

Комментарии:

1. Интересно. Это поведение где-нибудь задокументировано?

2. @LaurenceGonsalves: Это задокументировано в спецификации OpenGL ES.

3. Я надеялся на что-то более конкретное. 🙂 Для справки, это, похоже, задокументировано в разделе 2.8 спецификации «Массивы вершин» под заголовком «Передача элементов массива».