我一直在使用OPenGL處理骨骼動畫,並在包含一對數組的結構中向GPU發送骨骼重量影響,但是將這些數組更改爲向量似乎不起作用(如在模型中不再呈現,就好像骨信息以某種方式丟失或錯誤)。骨骼向量中的GPU權重
除了聲明struct中的向量,代碼路徑是相同的。我已經過調試並確保了元素的大小/值是可以的。我能想到的唯一的事情就是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
}
循環加載骨架和插入從網格類到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);
}
最後的代碼在網格類的信息添加到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));
您的代碼實際上並不包含任何有助於解決問題的方法。除了構造函數很愚蠢之外,這很好。我不知道爲什麼你認爲問題會出現在C++/gpu的屏障上(你甚至懶得告訴我們是否使用d3d或OpenGL) – Cubic 2014-12-07 16:20:41
公平點,我試圖減少我發佈的代碼量。我剛剛添加了很多! – Mark 2014-12-07 17:05:25