Error when loading 3ds file
Hi, I've written a 3Ds file loader for my OpenGL program. It is very simple and only includes the model.
This is one of my first C++ programs and I know this is quite advanced but I found a nice tutorial and decided to let go of Flash and learn C++ along with OpenGL.
Anyway, this is the loader code:
(Code in TDs.h)
Code:
#ifndef _3DS_H
#define _3DS_H
#include "main.h"
#include <vector>
#define CHUNK_MAIN 0x4D4D
#define CHUNK_3D_EDITOR 0x3D3D
#define CHUNK_BLOCK 0x4000
#define CHUNK_TRIANGULAR 0x4100
#define CHUNK_VERTICES 0x4110
#define CHUNK_FACES 0x4120
#define CHUNK_MAPPING 0x4140
using namespace std;
struct vector3{
vector3(){}
float x;
float y;
float z;
vector3(float newX, float newY, float newZ){
x=newX;
y=newY;
z=newZ;
}
};
struct tFace
{
int vertexIndex[3];
int coordIndex[3];
};
struct tDobj
{
int numOfVerts;
int numOfFaces;
char name;
vector3 *pVerts;
tFace *pFaces;
};
struct tDmodel
{
int numOfObjects;
vector<tDobj> pObject;
};
struct tChunk
{
unsigned short int id;
unsigned int length;
unsigned int bytesRead;
};
class TdsLoader
{
public:
TdsLoader();
bool TdsLoader::load3Ds(char* filename, tDmodel* pModel);
private:
void TdsLoader::readToNextChunk(tDmodel* pModel, tChunk* mainChunk);
void TdsLoader::readVertices(tDobj* pObject, tChunk* mainChunk);
void TdsLoader::readChunk(tChunk* chunk);
void TdsLoader::readObjectChunk(tDobj* pObject, tChunk* mainChunk);
void TdsLoader::readVertexIndicies(tDobj* pObject, tChunk* mainChunk);
tChunk* mainChunk;
tChunk* brChunk;
FILE* file;
};
#endif
(Code in TDs.cpp)
Code:
#include "main.h"
#include "TDs.h"
#include <stdio.h>
#include <vector>
TdsLoader::TdsLoader() {}
bool TdsLoader::load3Ds (char *filename, tDmodel* pModel)
{
tChunk* mainChunk;
tChunk* brChunk;
file = NULL;
MessageBox(NULL, "Opening File...", "Information", MB_OK);
if (!filename)
{
return false;
}
file = fopen(filename, "rb");
if (!file)
{
MessageBox(NULL, "Unable to open file", "Error", 0);
return false;
}
readToNextChunk(pModel, mainChunk);
}
void TdsLoader::readToNextChunk(tDmodel *pModel, tChunk *mainChunk)
{
int i=0;
int* buffer;
tDobj newObject = {0};
MessageBox(NULL, "Reading Chunk", "Information", MB_OK);
readChunk(mainChunk);
MessageBox(NULL, "Checking chunk...", "Information", MB_OK);
switch (mainChunk->id)
{
case CHUNK_MAIN:
MessageBox(NULL, "Main chunk found", "Information", MB_OK);
readToNextChunk(pModel, mainChunk);
break;
case CHUNK_BLOCK:
MessageBox(NULL, "Block chunk found", "Information", MB_OK);
pModel->numOfObjects++;
pModel->pObject.push_back(newObject);
char temp_name;
do
{
fread(&temp_name, 1, 1, file);
pModel->pObject[pModel->numOfObjects-1].name += temp_name;
i++;
}
while (&temp_name != "\0" && i<20);
readObjectChunk(&pModel->pObject[pModel->numOfObjects-1], mainChunk);
break;
default:
MessageBox(NULL, "Default chunk found", "Information", MB_OK);
mainChunk->bytesRead += fread(buffer, 1, mainChunk->length - mainChunk->bytesRead, file);
readToNextChunk(pModel, mainChunk);
break;
}
}
void TdsLoader::readChunk(tChunk* chunk)
{
MessageBox(NULL, "Checking id", "Information", MB_OK);
chunk->bytesRead = fread(&chunk->id, 1, 2, file);
MessageBox(NULL, "Checking length", "Information", MB_OK);
chunk->bytesRead += fread(&chunk->length, 1, 4, file);
}
void TdsLoader::readObjectChunk(tDobj* pObject, tChunk* mainChunk)
{
brChunk = new tChunk;
brChunk->length = mainChunk->length;
readChunk(brChunk);
while (mainChunk->bytesRead < mainChunk->length)
{
switch (brChunk->id)
{
case CHUNK_TRIANGULAR:
readObjectChunk(pObject, brChunk);
break;
case CHUNK_VERTICES:
readVertices(pObject, brChunk);
break;
case CHUNK_FACES:
readVertexIndicies(pObject, brChunk);
break;
default:
brChunk->bytesRead += fread(NULL, brChunk->length - brChunk->bytesRead, 1, file);
break;
}
mainChunk->bytesRead += brChunk->bytesRead;
}
}
void TdsLoader::readVertices(tDobj* pObject, tChunk* mainChunk)
{
brChunk->bytesRead += fread(&(pObject->numOfVerts), sizeof(unsigned short), 1, file);
pObject->pVerts = new vector3[pObject->numOfVerts];
mainChunk->bytesRead += fread(pObject->pVerts, 1, mainChunk->length - mainChunk->bytesRead, file);
}
void TdsLoader::readVertexIndicies(tDobj* pObject, tChunk* mainChunk)
{
unsigned short index=0;
mainChunk->bytesRead += fread(&(pObject->numOfFaces), 1, 2, file);
pObject->pFaces = new tFace [pObject->numOfFaces];
for (int i=0; i < pObject->numOfFaces; i++)
{
for (int j=0; j < 4; j++)
{
mainChunk->bytesRead += fread(&index, 1, sizeof(index), file);
if (j>3)
{
pObject->pFaces[i].vertexIndex[j] = index;
}
}
}
}
And finally the code to initialize this in main.cpp:
Code:
tDmodel theModel;
TdsLoader modelLoader;
if (!modelLoader.load3Ds("modell.3DS", &theModel))
{
MessageBox(NULL, "Unable to load model", "ERROR", MB_OK);
}
This program compiles nicely (after some hours of struggeling :rolleyes: ) but when I run it and it reaches the TdsLoader::readChunk function Visual C++ sends me this message:
"Unhandled exception at 0x00422012 in GLengine.exe: 0xC0000005: Access violation writing location 0xcccccccc.
And when I compiled it in Dev-Cpp it just crashed at that point. From the debugging information I've noticed that the file pointer is "BadPntr" or something similar in the Visual Studio "Whatch" window.
Anyone knows what might cause this? Help is really appreciated.
Thanks - The Wazaa