I've written my own code to parse an .obj model file - essentially just ASCII text. The file gets parsed and stored in the class correctly according to my tests. I can read back the values (from data members) just fine in the loading function.
The problem occurs when I try to read back the values in my main rendering loop. There is an access violation error on the line beginning "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);
}
}
I'm not exactly sure why this happens, and I've checked everything I could possibly think of. I'm not very experienced in C++. Most of my programming experience is in Java, Python and PHP although I have previously written a medium sized project in C++.
I'm sure the problem is something basic related to memory allocation or pointers used for the dynamic arrays.
Here are the relevant parts of code in the obj loading class:
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;
}
And the structs ObjFace, ObjVert, ObjUV and ObjNormal are defined as:
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;
};
Thanks for any help. Also, any good sources on avoiding these types of errors in future would be appreciated.
_data? Also, in the top code, isdatathe same as_datain the later code, or is there an assignment somewhere that we're not seeing? We're being asked to make too many assumptions about your code, in my opinion.LoadObjmethod and then again on thedataobject after you've assigned it. I suspect you'll find they are not in sync.