OpenGL GLSL Отправить цвет в виде целого числа для шейдера для разложения как vec4 RGBA - PullRequest
0 голосов
/ 06 ноября 2018

Я могу отправить цвет шейдеру как 4 поплавка - без проблем. Однако я хочу отправить его как целое число (или целое число без знака, на самом деле не имеет значения, что имеет значение 32 бита) и разложить в vec4 на шейдер.

Я использую OpenTK в качестве оболочки C # для OpenGL (хотя это должна быть просто прямая оболочка).

Давайте рассмотрим один из самых простых шейдеров с вершинами, содержащими позицию (xyz) и цвет (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 бита (на цвет) на вершину.

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Хорошо, так что это сделало работу для меня:

Имея данные как int[], где это плотно упакованный массив только цветов (где int формат: RGBA означает 0xAABBGGRR), а затем определение атрибута вершины как: GL.VertexAttribPointer(index, 4, VertexAttribPointerType.UnsignedByte, true, sizeof(int), IntPtr.Zero) и использовать его в шейдере как: in vec4 in_color;.

0 голосов
/ 06 ноября 2018

Вы должны использовать VertexAttribPointer, а не VertexAttribIPointer, когда входные данные в вашем шейдере являются плавающими (vec4).

Установите нормализованный параметр на GL_TRUE.

Спец говорит:

glVertexAttribPointer, если для normalized установлено значение GL_TRUE, это означает, что значения, хранящиеся в целочисленном формате, должны отображаться в диапазон [-1,1] (для значений со знаком) или [0,1] (для значений без знака) когда они доступны и конвертируются в плавающую точку. В противном случае значения будут напрямую преобразованы в числа с плавающей запятой без нормализации.

...