OpenGL GLSL Отправить цвет в виде целочисленного значения для шейдера для разложения как vec4 RGBA
Я могу отправить цвет в шейдер в виде 4-х чисел - без проблем. Однако я хочу отправить его как целое число (или целое число без знака, на самом деле не имеет значения, что имеет значение 32 бита) и разложить в vec4 на шейдер.
Я использую OpenTK в качестве оболочки C# для OpenGL (хотя это должна быть просто прямая оболочка).
Давайте рассмотрим один из самых простых шейдеров с вершинами, содержащими position(xyz) и color(rgba).
Вершинный шейдер:
#version 150 core
in vec3 in_position;
in vec4 in_color;
out vec4 pass_color;
uniform mat4 u_WorldViewProj;
void main()
{
gl_Position = vec4(in_position, 1.0f) * u_WorldViewProj;
pass_color = in_color;
}
Фрагмент шейдера:
#version 150 core
in vec4 pass_color;
out vec4 out_color;
void main()
{
out_color = pass_color;
}
Давайте создадим буфер вершин:
public static int CreateVertexBufferColor(int attributeIndex, int[] rawData)
{
var bufferIndex = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, bufferIndex);
GL.BufferData(BufferTarget.ArrayBuffer, sizeof(int) * rawData.Length, rawData, BufferUsageHint.StaticDraw);
GL.VertexAttribIPointer(attributeIndex, 4, VertexAttribIntegerType.UnsignedByte, 0, rawData);
GL.EnableVertexAttribArray(attributeIndex);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
return bufferIndex;
}
И я получаю все нули для vec4 'in_color' в вершинном шейдере. Не уверен, что не так.
Ближайшая вещь, которую я нашел: https://www.opengl.org/discussion_boards/showthread.php/198690-I-cannot-send-RGBA-color-as-unsigned-int.
Также в VertexAttribIPointer я передаю 0 как шаг, потому что у меня есть VertexBufferArray и храню данные отдельно. Так что цвета плотно упакованы по 32 бита (на цвет) на вершину.
1 ответ
Хорошо, так что это сделало работу для меня:
Управляя данными как int[]
где это плотно упакованный массив только цветов (где int
Формат: RGBA
имея в виду 0xAABBGGRR
), затем определяем атрибут вершины как: GL.VertexAttribPointer(index, 4, VertexAttribPointerType.UnsignedByte, true, sizeof(int), IntPtr.Zero)
и использовать его в шейдере как: in vec4 in_color;
,
Вы должны использовать VertexAttribPointer, а не VertexAttribIPointer, когда входные данные в вашем шейдере являются плавающими (vec4).
Установите нормализованный параметр в GL_TRUE.
Спец говорит:
glVertexAttribPointer, если для normalized установлено значение GL_TRUE, это означает, что значения, хранящиеся в целочисленном формате, должны отображаться в диапазон [-1,1] (для значений со знаком) или [0,1] (для значений без знака), когда они доступ и преобразован в число с плавающей точкой. В противном случае значения будут преобразованы в числа с плавающей запятой напрямую без нормализации.