Cocoa и OpenGL, как мне установить атрибут вершины GLSL с помощью массива?

StackOverflow https://stackoverflow.com/questions/1965027

Вопрос

Я довольно новичок в OpenGL, и, похоже, испытываю некоторые трудности.Я написал простой шейдер на GLSL, который должен преобразовывать вершины с помощью заданных совместных матриц, позволяя выполнять простую скелетную анимацию.Каждая вершина имеет максимум два влияния кости (хранятся как компоненты x и y Век2), индексы и соответствующие веса, которые связаны с массивом матриц преобразования и указаны как "Переменные атрибута" в моем шейдере, затем устанавливаются с помощью функции "glVertexAttribPointer".

Вот тут-то и возникает проблема...Мне удалось правильно настроить массив матриц "Однородная переменная", когда я проверяю эти значения в шейдере, все они импортируются правильно и содержат правильные данные.Однако, когда я пытаюсь установить переменную joint Indexes, вершины умножаются на произвольные матрицы преобразования!Они переходят к кажущимся случайными позициям в пространстве (которые каждый раз разные), исходя из этого, я предполагаю, что индексы установлены неправильно, и мой шейдер считывает данные после конца моего объединенного матричного массива в следующую память.Я не совсем уверен почему, потому что, прочитав всю информацию, которую я смог найти по этому вопросу, я был удивлен, увидев тот же (если не очень похожий) код в их примерах, и, похоже, у них это сработало.

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

Код, который я использую для установки переменных, выглядит следующим образом...

// this works properly...
GLuint boneMatLoc = glGetUniformLocation([[[obj material] shader] programID], "boneMatrices");
glUniformMatrix4fv( boneMatLoc, matCount, GL_TRUE, currentBoneMatrices );

GLfloat testBoneIndices[8] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};

// this however, does not...
GLuint boneIndexLoc = glGetAttribLocation([[[obj material] shader] programID], "boneIndices");
glEnableVertexAttribArray( boneIndexLoc );
glVertexAttribPointer( boneIndexLoc, 2, GL_FLOAT, GL_FALSE, 0, testBoneIndices );

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

// this shader is supposed to transform the bones by a skeleton, a maximum of two
// bones per vertex with varying weights...

uniform mat4 boneMatrices[32];  // matrices for the bones
attribute vec2 boneIndices;  // x for the first bone, y for the second

//attribute vec2 boneWeight;  // the blend weights between the two bones

void main(void)
{
 gl_TexCoord[0] = gl_MultiTexCoord0; // just set up the texture coordinates...


 vec4 vertexPos1 = 1.0 * boneMatrices[ int(boneIndex.x) ] * gl_Vertex;
 //vec4 vertexPos2 = 0.5 * boneMatrices[ int(boneIndex.y) ] * gl_Vertex;

 gl_Position = gl_ModelViewProjectionMatrix * (vertexPos1);
}

Это действительно начинает меня расстраивать, и любая помощь будет оценена по достоинству,

- Эндрю Гото

Это было полезно?

Решение

Хорошо, я с этим разобрался.OpenGL рисует треугольники с помощью функции drawArrays, считывая каждые 9 значений в виде треугольника (3 вершины с 3 компонентами в каждой).Из-за этого вершины переставляются между треугольниками, поэтому, если два соседних треугольника имеют общую вершину, она появляется в массиве дважды.Итак, мой куб, который, как я изначально думал, имеет 8 вершин, на самом деле имеет 36!

шесть сторон, по два треугольника на сторону, по три вершины на треугольник, все это умножается на 36 независимых вершин вместо 8 общих.

Вся проблема заключалась в том, что было задано слишком мало значений.Как только я расширил свой тестовый массив, включив в него 36 значений, он сработал идеально.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top