C++ 使用ASSIMP和GLSL的骨骼动画:骨骼均匀阵列大小

C++ 使用ASSIMP和GLSL的骨骼动画:骨骼均匀阵列大小,c++,opengl,glsl,skeletal-animation,C++,Opengl,Glsl,Skeletal Animation,我正在制作一个ASSIMP骨骼动画加载程序和渲染器,现在所有数据都正确加载并在当前时间段内插值。但是,仍然有一个部分不能正常工作,那就是顶点着色器阶段 通过VBO我传入两个vec4s,其中包含每个顶点的骨骼ID和权重(每个顶点最多4骨骼/权重),并且顶点着色器具有通过骨骼ID索引的100骨骼变换(每帧预先计算)的矩阵数组 但是,骨骼统一似乎不包含正确的变换。出于调试目的,我使用权重值和骨骼ID值为模型着色,它们包含一种颜色(因此也是有效值)。但是,当我通过骨骼变换变换顶点并使用结果为模型着色时,

我正在制作一个ASSIMP骨骼动画加载程序和渲染器,现在所有数据都正确加载并在当前时间段内插值。但是,仍然有一个部分不能正常工作,那就是顶点着色器阶段

通过VBO我传入两个
vec4
s,其中包含每个顶点的骨骼ID和权重(每个顶点最多4骨骼/权重),并且顶点着色器具有通过骨骼ID索引的100骨骼变换(每帧预先计算)的矩阵数组

但是,骨骼统一似乎不包含正确的变换。出于调试目的,我使用权重值和骨骼ID值为模型着色,它们包含一种颜色(因此也是有效值)。但是,当我通过骨骼变换变换顶点并使用结果为模型着色时,整个模型都被着色为黑色,这意味着变换矩阵都是
0.0
。所以它们没有正确初始化

我认为问题在于将矩阵传递给统一数组,或者可能是允许的统一的最大大小(我也尝试将统一矩阵的数量设置为32(当前模型上的骨骼数量),但没有效果)

在将信息传递给着色器之前,变换矩阵确实是有效矩阵(不是恒等矩阵/空矩阵),因此故障可能发生在GLSL着色器或传递一致性中

以下代码来自顶点着色器:

以下代码片段将矩阵数据传递给GLSL着色器:

还有获取骨骼阵列所有统一位置的代码:

for(无符号整数i=0;i<100;i++)
{
string name=“bones[”;
字符串编号;
细流ss;
ss>数量;
姓名+=号码;
名称+=']';
boneLocations[i]=glGetUniformLocation(this->program,name.c_str());
}

Oké,通过glslDevil我在通过
glUniformMatrix
将骨骼矩阵设置为着色器时遇到一个持续的
Glu无效\u操作
错误。问题的根源确实是在程序将信息传递给着色器的阶段


实际上这是一个相当愚蠢的错误,因为我使用的是
glUniformMatrix3f
而不是
glUniformMatrix4f
。改变这一点确实解决了问题,动画现在工作得很好

@Katianie是的,这是在顶点着色器的最后一行完成的:)
gl_Position=projection*view*model*newPos
newPos
newPos
变量乘以MVP矩阵。@Katianie是的,转换确实是有效的值(我应该把它添加到我的问题中),感谢您的注意。@Katianie这是用于GLSL的旧版本,主要用于旧OpenGL编程(据我所知)。Katianie,我很感谢你的帮助,我无意冒犯你,但现在你似乎在没有骨骼动画(或ASSIMP)方面的专业知识的情况下试图帮助我,这对我没有任何帮助。老实说:p.我不是把这作为一个答案来提交的,因为这只是一个解决办法,但我从来没有在OpenGL中使用过大型统一阵列,因此,在我的引擎中,我将N个骨骼矩阵编码为4N宽1D的float4s纹理,并更新每个帧(我将每个矩阵的4列存储在相邻的texel中)。它速度快,可以在我测试过的所有硬件上工作;但这是一个难题。一个统一的缓冲区对象将是一个比一维纹理更好的选择。但更重要的是,查询数组中每个制服的位置没有意义。你可以用一些代码来检查数组的大小,就像我在这个。。。数组中的每个统一位置都是按顺序分配的,因此您只需要知道数组中第一个统一位置。我认为在每次GL API调用后添加错误检查和/或通过ARB扩展设置错误回调是一个好主意。@是的,我下次一定会这样做
#version 330
layout (location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec3 tangent;
layout(location = 3) in vec3 color;
layout(location = 4) in vec2 texCoord;
layout(location = 5) in ivec4 boneIDs;
layout(location = 6) in vec4 weights;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform mat4 bones[100];

out vec2 TexCoord;
out vec4 colorz;

void main()
{
    vec4 newPos = vec4(position, 1.0);
    colorz = vec4(0.0, 1.0, 0.0, 1.0);
    if (weights != vec4(0.0, 0.0, 0.0, 0.0))
    {
        mat4 boneTransform = bones[boneIDs[0]] * weights[0];
        boneTransform += bones[boneIDs[1]] * weights[1];
        boneTransform += bones[boneIDs[2]] * weights[2];
        boneTransform += bones[boneIDs[3]] * weights[3];

        // newPos = boneTransform * vec4(position, 1.0);
        vec4 test = vec4(1.0);
        colorz = boneTransform * test;
        // newPos = boneTransform * newPos;
    }

    TexCoord = texCoord;
    gl_Position = projection * view * model * newPos;
}
// Sets bone transformation matrices
void Shader::SetBoneMatrix(GLint index, aiMatrix4x4 matrix)
{
    glm::mat4 mat = glm::transpose(glm::make_mat4(&matrix.a1));
    glUniformMatrix3fv(boneLocations[index], 1, GL_FALSE, glm::value_ptr(mat));  
}
for(unsigned int i = 0; i < 100; i++)
{
    string name = "bones[";
    string number;
    stringstream ss;
    ss << i;
    ss >> number;
    name += number;
    name += ']';
    boneLocations[i] = glGetUniformLocation(this->program, name.c_str());
}