Можно ли упаковать как плавающие, так и целые числа в один и тот же буфер массива? - PullRequest
1 голос
/ 05 февраля 2012

... потому что кажется, что поплавки выходят нормально, но что-то не так с ними.

По сути, у меня есть структура с именем "BlockInstance", которая содержит vec3 и int. У меня есть массив этих BlockInstances, которые я буферизирую следующим образом (для ясности перевод с C # на C):

glBindBuffer(GL_ARRAY_BUFFER, bufferHandle);
glBufferData(GL_ARRAY_BUFFER, sizeof(BlockInstance)*numBlocks, blockData, GL_DYNAMIC_DRAW);
glVertexAttribPointer(3,3,GL_FLOAT,false,16,0);
glVertexAttribPointer(4,1,GL_INT,false,16,12);
glVertexAttribDivisor(3,1);
glVertexAttribDivisor(4,1);

И мой вершинный шейдер выглядит так:

#version 330

layout (location = 0) in vec3 Position;
layout (location = 1) in vec2 TexCoord;
layout (location = 2) in vec3 Normal;
layout (location = 3) in vec3 Translation;
layout (location = 4) in int TexIndex;

uniform mat4 ProjectionMatrix;

out vec2 TexCoord0;

void main()
{
    mat4 trans = mat4(
        1,0,0,0,
        0,1,0,0,
        0,0,1,0,
        Translation.x,Translation.y,Translation.z,1);
    gl_Position = ProjectionMatrix * trans * vec4(Position, 1.0);
    TexCoord0 = vec2(TexCoord.x+TexIndex,TexCoord.y)/16;
}

Когда я заменяю TexIndex в последней строке моего шейдера GLSL на константу, такую ​​как 0, 1 или 2, мои текстуры получаются хорошо, но если я оставляю это как есть, они выходят все искаженными, так должно быть что-то не так с номером, верно? Но я не знаю, что из этого выйдет, так что сложно отлаживать.

Я посмотрел на мой массив BlockInstances, и все они установлены в 1,2 или 19, так что я не думаю, что мой ввод неправильный ...

Что еще это может быть?


Обратите внимание, что я использую текстуру карты спрайтов, где каждая из плиток имеет размер 16x16 пикселей, но мои TexCoords находятся в диапазоне 0-1, поэтому я добавляю к нему целое число, чтобы выбрать какую плитку, а затем делю ее на 16 (карта также размером 16x16), чтобы вернуть ее в нужный диапазон. Идея в том, что я заменю эту последнюю строку на

TexCoord0 = vec2(TexCoord.x+(TexIndex%16),TexCoord.y+(TexIndex/16))/16;

- GLSL выполняет целочисленные вычисления, верно? Int, разделенное на int, получится как целое число?


Если я попробую это:

TexCoord0 = vec2(TexCoord.x+(TexIndex%16),TexCoord.y)/16;

Текстура выглядит отлично, но она не использует правильный спрайт. (Похоже, использует первый спрайт)

Если я сделаю это:

TexCoord0 = vec2(TexCoord.x+(TexIndex%16),TexCoord.y+(TexIndex/16))/16;

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

1 Ответ

6 голосов
/ 05 февраля 2012
layout (location = 4) in int TexIndex;

Ваша проблема.

glVertexAttribPointer используется для отправки данных, которые будут преобразованы в значения с плавающей запятой .Он используется для подачи атрибутов с плавающей точкой.Передача целых чисел возможна, но эти целые числа преобразуются в числа с плавающей точкой, потому что для этого glVertexAttribPointer.

Вам нужно glVertexAttribIPointer (обратите внимание на I ).Это используется для предоставления целочисленных данных со знаком и без знака.

Поэтому, если вы объявляете ввод вершинного шейдера как float или какой-то нефиксированный vec, вы используете glVertexAttribPointer для подачи в него.Если вы объявляете ввод как int, uint, ivec или uvec, то вы используете glVertexAttribIPointer.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...