矢量中骨骼重量到 GPU 的重量
Bone weights to GPU in vectors
本文关键字:GPU 更新时间:2023-10-16
我一直在使用 OPenGL 制作骨骼动画,并在包含一对数组的结构中向 GPU 发送骨量影响,但是将这些数组更改为矢量似乎不起作用(就像模型中停止渲染一样,好像骨骼信息以某种方式丢失或错误(。
除了结构中向量的声明之外,代码路径是相同的。我已经调试并确保元素的大小/值正常。我唯一能想到的是,C++在将矢量上传到 GPU 之前释放了矢量的内容,但我没有看到任何证据支持这一说法。
值得注意的是,使用的调整大小是为了使结构与现有数组功能兼容,并且在解决此问题后将被删除以允许动态缩放。
以下是使用向量的结构:
struct VertexBoneData
{
std::vector<glm::uint> IDs;
std::vector<float> weights;
VertexBoneData()
{
Reset();
IDs.resize(NUM_BONES_PER_VEREX);
weights.resize(NUM_BONES_PER_VEREX);
};
void Reset()
{
IDs.clear();
weights.clear();
}
void AddBoneData(glm::uint p_boneID, float p_weight);
};
编辑:附加信息。
下面是将骨骼信息获取到结构中的循环:
void Skeleton::LoadBones(glm::uint baseVertex, const aiMesh* mesh, std::vector<VertexBoneData>& bones)
{
for (glm::uint i = 0; i < p_mesh->mNumBones; i++) {
glm::uint boneIndex = 0;
std::string boneName(mesh->mBones[i]->mName.data);
if (_boneMap.find(boneName) == _boneMap.end()) {
//Allocate an index for a new bone
boneIndex = _numBones;
_numBones++;
BoneInfo bi;
_boneInfo.push_back(bi);
SetMat4x4(_boneInfo[boneIndex].boneOffset, mesh->mBones[i]->mOffsetMatrix);
_boneMap[boneName] = boneIndex;
}
else {
boneIndex = _boneMap[boneName];
}
for (glm::uint j = 0; j < mesh->mBones[i]->mNumWeights; j++) {
glm::uint vertId = baseVertex + mesh->mBones[i]->mWeights[j].mVertexId;
float weight = mesh->mBones[i]->mWeights[j].mWeight;
bones[vertId].AddBoneData(boneIndex, weight);
}
}
}
将 ID/权重添加到顶点的代码:
void VertexBoneData::AddBoneData(glm::uint p_boneID, float p_weight)
{
for (glm::uint i = 0; i < ARRAY_SIZE_IN_ELEMENTS(IDs); i++) {
if (weights[i] == 0.0) {
IDs[i] = p_boneID;
weights[i] = p_weight;
return;
}
}
assert(0); //Should never get here - more bones than we have space for
}
循环加载框架并从 Mesh 类插入到 VBO 对象:
if (_animator.HasAnimations())
{
bones.resize(totalIndices);
for (unsigned int i = 0; i < _scene->mNumMeshes; ++i){
_animator.LoadSkeleton(_subMeshes[i].baseVertex, _scene->mMeshes[i], bones);
}
_vertexBuffer[2].AddData(&bones);
}
插入到 VBO 对象:
void VertexBufferObject::AddData(void* ptr_data)
{
data = *static_cast<std::vector<BYTE>*>(ptr_data);
}
最后,将信息从 Mesh 类添加到 GPU 的代码:
_vertexBuffer[2].BindVBO();
_vertexBuffer[2].UploadDataToGPU(GL_STATIC_DRAW);
glEnableVertexAttribArray(BONE_ID_LOCATION);
glVertexAttribIPointer(BONE_ID_LOCATION, 4, GL_INT, sizeof(VertexBoneData), (const GLvoid*)0);
glEnableVertexAttribArray(BONE_WEIGHT_LOCATION);
glVertexAttribPointer(BONE_WEIGHT_LOCATION, 4, GL_FLOAT, GL_FALSE, sizeof(VertexBoneData), (const GLvoid*)(sizeof(VertexBoneData) / 2));
这
不可能奏效。std::vector
实例是一个对象,它内部包含指向动态分配数据的指针。
所以有了这个定义:
struct VertexBoneData
{
std::vector<glm::uint> IDs;
std::vector<float> weights;
IDs
和weights
的值不会直接存储在结构中。位于动态分配的堆内存中。该结构仅包含vector
对象,这些对象包含指针和一些簿记属性。
您不能将这些结构直接存储在 OpenGL 缓冲区中,并让 GPU 访问数据。OpenGL不知道如何处理vector
对象。
相关文章:
- 没有找到相关文章