所以再次遇到了我無法通過的障礙! 我想解析,加載OpenGL的obj文件!C++改進內存映射obj文件
我已經成功,但它非常慢(用於ifstream) 所以我現在內存映射文件並從那裏解析(加載到內存非常快!)。
問題是我不知道如何保持速度,即使解析它!
目前代碼:
HANDLE file = CreateFile((LPCSTR)loc.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(file == INVALID_HANDLE_VALUE) { /* Error handling code! */ }
HANDLE file2 = CreateFileMapping(file, NULL, PAGE_READONLY, NULL, NULL, (LPCSTR)"CurrentParsingOBJ");
VOID* mappedData = MapViewOfFile(file2, FILE_MAP_READ, 0, 0, NULL);
const char* data = new(mappedData) char[];
int i = 0;
bool v = false, vn = false, vt = false;
while(*(data + i) != '\0')
{
if(*(data + i) == '\n') { v = false; vn = false; vt = false; ++i; continue; }
if((*(data + i) == 'v' && *(data + i + 1) == ' ') || v)
{
int a = 0;
int p = 0;
int pp = 0;
v = true;
}
++i;
}
//Free Mapped Data!
if(UnmapViewOfFile(mappedData) == NULL) { /* Error handling code! */ }
mappedData = NULL;
data = NULL;
到目前爲止,這是非常不錯的速度! 但我無法弄清楚如何解析它並保持速度! 我已經嘗試了很多解決方案,但所有這些都導致無法接受的速度!
這是我如何與ifstream的做(我想這裏加載相同OBJData結構,內存映射版本藏漢!):
std::ifstream stream(loc);
if(stream.is_open())
{
for(std::string line; std::getline(stream, line);)
{
if(StringUtil::StringStartsWith(line, "v "))
{
Vector3f vec = Vector3f((float)atof((StringUtil::Split(line, ' ')[1])->c_str()), (float)atof((StringUtil::Split(line, ' ')[2])->c_str()), (float)atof((StringUtil::Split(line, ' ')[3])->c_str()));
d->V.push_back(vec);
}else if(StringUtil::StringStartsWith(line, "vn "))
{
Vector3f vec = Vector3f((float)atof((StringUtil::Split(line, ' ')[1])->c_str()), (float)atof((StringUtil::Split(line, ' ')[2])->c_str()), (float)atof((StringUtil::Split(line, ' ')[3])->c_str()));
d->VN.push_back(vec);
}else if(StringUtil::StringStartsWith(line, "vt "))
{
Vector3f vec = Vector3f((float)atof((StringUtil::Split(line, ' ')[1])->c_str()), (float)atof((StringUtil::Split(line, ' ')[2])->c_str()), 0.0F);
d->VT.push_back(vec);
}else if(StringUtil::StringStartsWith(line, "f "))
{
Vector3f vert = Vector3f((float)atof(StringUtil::Split(StringUtil::Split(line, ' ')[1]->c_str(), '/')[0]->c_str()), (float)atof(StringUtil::Split(StringUtil::Split(line, ' ')[2]->c_str(), '/')[0]->c_str()), (float)atof(StringUtil::Split(StringUtil::Split(line, ' ')[3]->c_str(), '/')[0]->c_str()));
Vector3f norms = Vector3f((float)atof(StringUtil::Split(StringUtil::Split(line, ' ')[1]->c_str(), '/')[2]->c_str()), (float)atof(StringUtil::Split(StringUtil::Split(line, ' ')[2]->c_str(), '/')[2]->c_str()), (float)atof(StringUtil::Split(StringUtil::Split(line, ' ')[3]->c_str(), '/')[2]->c_str()));
Vector3f textures = Vector3f((float)atof(StringUtil::Split(StringUtil::Split(line, ' ')[1]->c_str(), '/')[1]->c_str()), (float)atof(StringUtil::Split(StringUtil::Split(line, ' ')[2]->c_str(), '/')[1]->c_str()), (float)atof(StringUtil::Split(StringUtil::Split(line, ' ')[3]->c_str(), '/')[1]->c_str()));
d->F.push_back(OBJFace(vert, norms, textures));
}
}
}else { /* Error handling code! */ }
stream.close();
上述版本花費的時間waaay高達1分鐘更大的目標!
所以我的問題:如何在最短的時間內解析「內存映射版本」!並加載與較慢版本相同的OBJData結構!
向我們展示一個小例子輸入。 –
我會發布一些代碼給你看看,這將有望解釋更多比我的描述可能 – GMasucci
你可以做的是避免複製和分配字符串。你可以直接從映射的內存中解析。這會更復雜,但速度更快。 – zch