【发布时间】:2011-03-04 04:24:21
【问题描述】:
我已经编写了自己的代码来解析 .obj 模型文件 - 基本上只是 ASCII 文本。根据我的测试,该文件被正确解析并存储在类中。我可以在加载函数中很好地读取值(来自数据成员)。
当我尝试读回主渲染循环中的值时会出现问题。以“int v”开头的行出现访问冲突错误:
for(int i = 0; i<data.numFaces; i++){
for(int j = 0; j<3; j++){ //Assuming triangles for now.
int v = data.faceList[i].vertex[j]; // Access violation here.
double vX = data.vertexList[v].x;
double vY = data.vertexList[v].y;
double vZ = data.vertexList[v].z;
glVertex3d(vX, vY, vZ);
}
}
我不确定为什么会发生这种情况,并且我已经检查了我可能想到的所有内容。我在 C++ 方面不是很有经验。尽管我之前用 C++ 编写过一个中等规模的项目,但我的大部分编程经验是 Java、Python 和 PHP。
我确定问题与内存分配或用于动态数组的指针有关。
这里是obj加载类的相关代码:
ObjData ObjLoader::LoadObj(std::string filename){
//... Initalization ...
// 1st pass: find number of elements so array sizes can be defined.
while(!file.eof()){
//...
}
//...close file...
_data.faceList = new ObjFace[_data.numFaces];
_data.vertexList = new ObjVert[_data.numVertices];
_data.uvList = new ObjUV[_data.numUVcoords];
_data.normalList = new ObjNormal[_data.numNormals];
//TODO: Make size dynamic according to each face. Just use the first 3 points for now.
for (int i = 0; i < _data.numFaces; i++){
_data.faceList[i].vertex = new int[3];
_data.faceList[i].normal = new int[3];
_data.faceList[i].uv = new int[3];
}
//... file stuff ...
// 2nd pass: read values into arrays.
while(!file.eof()){
//...
if(type=="v"){
_data.vertexList[currentVertex].x = atof(param1.c_str());
_data.vertexList[currentVertex].y = atof(param2.c_str());
_data.vertexList[currentVertex].z = atof(param3.c_str());
currentVertex++;
}else if(type=="vt"){
_data.uvList[currentUV].u = atof(param1.c_str());
_data.uvList[currentUV].v = atof(param2.c_str());
currentUV++;
}else if(type=="vn"){
_data.normalList[currentNormal].x = atof(param1.c_str());
_data.normalList[currentNormal].y = atof(param2.c_str());
_data.normalList[currentNormal].z = atof(param3.c_str());
currentNormal++;
}else if(type=="f"){
//...Within loop over each vertex in a single face ...
if(endPos != string::npos){
// Value before 1st "/" (Vertex index).
// ...find value in string...
_data.faceList[currentFace].vertex[i] = atoi(token.c_str()) -1; // File format begins indices from 1.
// Value between slashes (UV index).
// ...find value in string...
_data.faceList[currentFace].uv[i] = atoi(token.c_str()) -1;
// Value after 2nd "/" (Normal index).
// ...find value in string...
_data.faceList[currentFace].normal[i] = atoi(token.c_str()) -1;
}
//...End of loop over every vertex in a single face...
currentFace++;
}
}
return _data;
}
而结构体 ObjFace、ObjVert、ObjUV 和 ObjNormal 定义为:
struct ObjVert{
float x, y, z;
};
struct ObjUV{
float u, v;
};
struct ObjNormal{
float x, y, z;
};
// Contains indexes.
struct ObjFace{
int* vertex;
int* uv;
int* normal;
};
感谢您的帮助。此外,任何有关在未来避免此类错误的良好资源都将不胜感激。
【问题讨论】:
-
您能否添加更多相关代码?比如
_data是什么类型?另外,在上面的代码中,data是否与后面的代码中的_data相同,或者是否有我们没有看到的赋值?在我看来,我们被要求对您的代码做出太多假设。 -
哦,对了,我尽量删除不相关的代码。顶部的 sn-p 在我的主渲染循环中,就在此之前,调用了 LoadObj(即较低的 2 个 sn-ps),其中返回的值被分配给数据,如下所示: data = LoaderClass.LoadObj("立方体.obj"); _data 和 data 都是 ObjData 类型,存储加载的 .obj。
-
虽然问题(有些)不同,但您可能想查看我之前发布的有关读取 obj 文件的答案中的代码:stackoverflow.com/questions/2908854/…
-
@usm:我在看到你的评论之前写了一个答案,但你似乎证实了我对你的作业的期望。我完全承认我不是这个确切主题的专家,但我相信我的回答应该能帮助你到达你需要去的地方。作为对此的快速测试,您可以在
LoadObj方法中使用指针地址编写输出,然后在分配后再次在data对象上编写输出。我怀疑你会发现它们不同步。
标签: c++ arrays multidimensional-array access-violation