2016-08-14 5 views
-1

Я использую openglEs 2.0. Я работаю над аппаратным скинированием. Я пытаюсь передать индексы костей как ivec4, однако компилятор говорит мне, что невозможно использовать ivec4 как атрибут вершины. Как я могу преодолеть эту путаницу?ivec4 как атрибут вершины Opengl ES 2.0

Вот мой шейдерный код вершин.

0(1) : error C7507: OpenGL does not allow attributes of type ivec4 
"struct Bone" 
    "{" 
    " mat4 transform;" 
    " mat4 bindPose;" 
    "};" 
    "attribute vec3 vPosition;" 
    "attribute vec3 vNormal;" 
    "attribute vec2 vTexture;" 
    "attribute ivec4 vBones;" 
    "attribute vec4 vWeights;" 
    "uniform mat4 projectViewModel;" 
    "uniform Bone bones[64];" 
    "varying vec3 v_normal;" 
    "varying vec2 v_texCoord;" 
    "void main()" 
    "{" 
    " gl_Position = bones[vBones.x].transform * bones[vBones.x].bindPose * vec4(vPosition, 1.0) * vWeights.x;" 
    " gl_Position += bones[vBones.y].transform * bones[vBones.y].bindPose * vec4(vPosition, 1.0) * vWeights.y;" 
    " gl_Position += bones[vBones.z].transform * bones[vBones.z].bindPose * vec4(vPosition, 1.0) * vWeights.z;" 
    " gl_Position += bones[vBones.w].transform * bones[vBones.w].bindPose * vec4(vPosition, 1.0) * vWeights.w;" 
    " gl_Position = projectViewModel * gl_Position;" 
    " v_texCoord = vTexture;" 
    " v_normal = vNormal;" 
    "}"; 

UPDATE:

Как я уже сказал, я изменил код шейдера и на стороне клиента код. Вот код на стороне клиента:

glEnableVertexAttribArray(3); // Bones 
glVertexAttribPointer(3, 4, GL_INT, GL_FALSE, object->m_mesh->GetVertexSize(), (const void*)offset); 

И это, как я получить доступ к индексам костей в коде шейдера:

gl_Position = bones[int(vBones.x)].transform * bones[int(vBones.x)].bindPose * vec4(vPosition, 1.0) * vWeights.x; 

Если я запускаю этот код на Windows PC. Он работает отлично, но когда я скомпилировал его с emscripten для веб-браузеров. Он дает gl error 1282 (Invalid Operation).

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

+0

Я использую glVertexAttribIPointer для привязки атрибута вершины. Я изменил с ivec4 на vec4 и лидировал индексы от float до int. Я считаю, что это безопасно, поскольку индексы костей находятся между 0 и 64. – Cihan

ответ

1

Целочисленные атрибуты не поддерживаются в ES 2.0. Из GLSL ES 1,00 спецификации (который является версией GLSL используется с ES 2.0):

Атрибут классификатор может быть использован только с типами данных с плавающей точкой, vec2, vec3, vec4, MAT2, mat3 и mat4.

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

Если ваши данные на стороне клиента находятся в целочисленном формате, вы должны быть осторожны в своем вызове glVertexAttribPointer(). Булевское значение, переданное как 4-й аргумент, указывает, хотите ли вы, чтобы значения были нормализованы, или если они должны быть преобразованы в float без нормализации. В вашем случае вы захотите пройти GL_FALSE. Например, если у вас есть данные байта в вашем клиентском коде:

glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0); 

ES 3.0 и выше поддержка целочисленных атрибутов. Итак, вы можете использовать ivec4 для атрибута и указать значения с помощью glVertexAttribIPointer() (обратите внимание на дополнительный I в имени функции) в код вашего клиента.