我正在使用Assimp的模型加載器中實現動畫;用於渲染的C++/OpenGL。我一直在關注這個教程:http://ogldev.atspace.co.uk/www/tutorial38/tutorial38.html廣泛。只需說我沒有完全按照教程進行操作,因爲有些代碼我不同意,所以我對它進行了修改。請注意,我不使用作者在其中使用的數學組件,所以我使用了glm。無論如何,問題在於有時我的程序運行,而在其他時間則不會。當我運行我的程序時,它會運行,然後立即崩潰,而在其他時候,它會正常運行。產生intel_drm錯誤的動畫
有幾件事情要考慮到:
加入之前的動畫/加載的骨頭,模型加載器的工作完全沒品裝載模式沒有任何未造成死機;
沒有骨骼的模型仍然加載一樣好;只有裝有骨骼的模型纔會成爲問題。
請注意,骨頭上沒有東西正在呈現。我甚至沒有開始將骨骼分配給頂點屬性;甚至沒有爲此修改着色器。
一切正在單線程上運行;沒有多線程......但是。
所以,自然我採取了這一點的代碼實際上加載骨頭。我調試的應用程序,發現問題在哪裏大多是在這裏:
Mesh* processMesh(uint meshIndex, aiMesh *mesh)
{
vector<VertexBoneData> bones;
bones.resize(mesh->mNumVertices);
// .. getting other mesh data
if (pAnimate)
{
for (uint i = 0; i < mesh->mNumBones; i++)
{
uint boneIndex = 0;
string boneName(mesh->mBones[i]->mName.data);
auto it = pBoneMap.find(boneName);
if (it == pBoneMap.end())
{
boneIndex = pNumBones;
++pNumBones;
BoneInfo bi;
pBoneInfo.push_back(bi);
auto tempMat = mesh->mBones[i]->mOffsetMatrix;
pBoneInfo[boneIndex].boneOffset = to_glm_mat4(tempMat);
pBoneMap[boneName] = boneIndex;
}
else boneIndex = pBoneMap[boneName];
for (uint j = 0; j < mesh->mBones[i]->mNumWeights; j++)
{
uint vertexID = mesh->mBones[i]->mWeights[j].mVertexId;
float weit = mesh->mBones[i]->mWeights[j].mWeight;
bones.at(vertexID).addBoneData(boneIndex, weit);
}
}
}
}
在最後一行筆者使用的[]
運營商訪問的元素,但我決定用'.at
的範圍檢查。功能to_glm_mat4
被這樣定義:
glm::mat4 to_glm_mat4(const aiMatrix4x4 &m)
{
glm::mat4 to;
to[0][0] = m.a1; to[1][0] = m.a2;
to[2][0] = m.a3; to[3][0] = m.a4;
to[0][1] = m.b1; to[1][1] = m.b2;
to[2][1] = m.b3; to[3][1] = m.b4;
to[0][2] = m.c1; to[1][2] = m.c2;
to[2][2] = m.c3; to[3][2] = m.c4;
to[0][3] = m.d1; to[1][3] = m.d2;
to[2][3] = m.d3; to[3][3] = m.d4;
return to;
}
我也不得不改變VertexBoneData因爲它使用哪個我認爲有缺陷的原始陣列:
結構VertexBoneData { 矢量boneIDs; 矢量權重;
VertexBoneData()
{
reset();
boneIDs.resize(NUM_BONES_PER_VERTEX);
weights.resize(NUM_BONES_PER_VERTEX);
}
void reset()
{
boneIDs.clear();
weights.clear();
}
void addBoneData(unsigned int boneID, float weight)
{
for (uint i = 0; i < boneIDs.size(); i++)
{
if (weights.at(i) == 0.0) // SEG FAULT HERE
{
boneIDs.at(i) = boneID;
weights.at(i) = weight;
return;
}
}
assert(0);
}
};現在
,我不完全知道是什麼原因導致崩潰,但什麼最困擾我的是,有時候程序運行(這意味着該代碼不一定是罪魁禍首)。所以我決定做一個調試砸碎,其中涉及我檢查每個骨頭(我跳過一些,有很多骨頭!),並發現後,所有的骨頭已經加載,我會得到這個非常奇怪的錯誤:
No source available for "drm_intel_bo_unreference() at 0x7fffec369ed9"
,有時我會得到這個錯誤:
Error in '/home/.../: corrupted double-linked list (not small): 0x00000 etc ***
,有時我會得到從GLM關於vec4實例化一個賽格故障;
有時...我的程序運行時沒有崩潰!
公平地說,實現動畫對我的筆記本電腦來說可能會非常苛刻,所以可能是CPU/GPU問題,因爲它無法處理大量數據,導致此次崩潰。我的理論是,由於無法處理那麼多的數據,所以這些數據永遠不會分配給矢量。
我不使用任何多線程無論如何,但它已經越過我的腦海。我認爲它可能是CPU無法處理這麼多的數據,因此機會運行。如果我實現了線程,那麼在另一個線程上完成骨骼加載;或更好,使用互斥鎖,因爲我發現通過慢慢地調試應用程序運行程序,這很有意義,因爲每個任務都被分解爲多個塊;而這本質上就是一個互斥體。
對於參數的緣故,並沒有公開宣佈的嘲弄,我的技術規格:
Ubuntu 15.04 64-bit
Intel i5 dual-core
Intel HD 5500
Mesa 10.5.9 (OpenGL 3.3)
Programming on Eclipse Mars
我這樣問,這到底是怎麼造成這些intel_drm錯誤?
當我寫這篇教程中,我使用的NVIDIA GPU。我們需要了解問題是否與MESA驅動程序有關(無論是驅動程序錯誤還是應用程序方面的問題,這些錯誤都可能沒有被正確實現,但在某種程度上通過了NVIDIA)。任何機會,你可以採取這些代碼,並在NVIDIA上運行它?另外,你是否嘗試使用GDB運行它? –
不幸的是我沒有一臺擁有NVIDIA GPU的機器(我曾經用過)。但這是有趣的;我將骨骼加載代碼封裝到它自己的函數loadBones(..)中,然後把它放在'if(pAnimate)'條件中的一個線程中。有趣的是,我得到的崩潰數量大大減少了。但是,它仍然會崩潰;所以可以肯定的說它可能是CPU/GPU問題,或者僅僅是缺乏多線程。 – Poriferous