我正在尝试为DirectX引擎编写模型文件加载器......
目前看起来像这样:
irrFireMesh* irrFireDevice::loadModel(char* filename)
{
ifstream in_stream;
string line;
in_stream.open(filename);
int vertexCount = 0;
int vCount = -1;
irrFireMesh* triangleMesh = new irrFireMesh();
irrFireVertex* vertices;
unsigned long* indices;
irrFireMaterial* mat;
while(getline(in_stream, line, '\n'))
{
std::string word;
std::stringstream stream(line);
std::string param[15];
int i = 0;
while( getline(stream, word, ' ') ){
param[i] = word;
i++;
}
then = timeGetTime();
if(param[0] == "newbuf")
{
vertexCount = StI(param[1]);
vertices = new irrFireVertex[vertexCount];
if(!vertices) return NULL;
indices = new unsigned long[vertexCount];
if(!indices) return NULL;
mat = new irrFireMaterial(this);
cout<<"Begin buffer width "<<vertexCount<<" vertices"<<endl;
vCount = -1;
continue;
}
if(vertexCount <= 0) continue;
if(param[0] == "endbuf")
{
irrFireMeshBuffer* mbuf = new irrFireMeshBuffer();
mbuf->vertexCount = vertexCount;
mbuf->indexCount = vertexCount;
mbuf->vertices = vertices;
mbuf->indices = indices;
mat->INITIALIZE();
mbuf->material = mat;
triangleMesh->addMeshBuffer(mbuf);
vertexCount = 0;
cout<<"End buffer width "<<vCount+1<<" vertices."<<endl;
continue;
}
if(param[0] == "v")
{
vCount++;
vertices[vCount].position = D3DXVECTOR3(StF(param[1]), StF(param[3]), StF(param[2]));
vertices[vCount].color = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
vertices[vCount].uv = D3DXVECTOR2((StF(param[1]) + StF(param[3]))*10.0f, StF(param[2])*10.0f);
indices[vCount] = vCount;
if((vCount+1) % 3 == 0)
{
D3DXVECTOR3 NRML, D1, D2;
D1 = vertices[vCount-2].position - vertices[vCount-1].position;
D2 = vertices[vCount-1].position - vertices[vCount].position;
D3DXVec3Cross(&NRML, &D1, &D2);
D3DXVec3Normalize(&NRML, &NRML);
vertices[vCount-2].normal = NRML;
vertices[vCount-1].normal = NRML;
vertices[vCount].normal = NRML;
}
continue;
}
}
in_stream.close();
return triangleMesh;
}
三角形的模型文件如下所示:
newbuf 3
v 0.0 0.0 0.0
v 0.5 1.0 0.0
v 1.0 0.0 0.0
endbuf
在加载复杂模型时,它的工作原理应该如此,但速度太慢...... 你能否指出我的瓶颈并指出一种解决这个问题的更快方法?
编辑: 好吧,我对一些函数所需的时间进行了基准测试,结果表明,解析部分
if(param[0] == "v")
{
.
.
.
}
解析23400个顶点时,总共需要大约4000毫秒。但是当我更换
vertices[vCount].position = D3DXVECTOR3(StF(param[1]), StF(param[3]), StF(param[2]));
与
vertices[vCount].position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
总共需要大约300毫秒。所以性能杀手似乎是StF()看起来像这样:
float StF(string in)
{
stringstream mystr("");
mystr<<in;
float res = 0;
mystr>>res;
return res;
}
任何想法,怎么做对吗?因为这显然太慢了......
答案 0 :(得分:1)
“新”命令的开销取决于遇到多少“newbuf”部分,但在我看来,您需要新命令,因为您需要保存每个数组。转换为矢量可能不是一个选项,具体取决于您是否可以修改网格类。
如果您有权访问分析器,那么最好用它来验证它花费时间的位置。它可以显示哪些代码行比其他行更差。很多时候,这应该是您尝试优化时的第一步;通常情况下,如果你只是试着注视它,你最终会猜错了。
以文本格式阅读会变慢。此外,从字符串到float的转换需要一些时间,以及新命令。您可能可以在每个“newbuf”部分中读取一个字符串数组,并多线程处理(并行处理新的和其他处理)。在将数组添加回目标网格之前,必须先同步事物。