Hi,
I have this access violation error when closing my 3D Demo. The rendering window disappears and I get the error message. I found out, that this must be caused somewhere in my 3DS loading code and since it occures when closing the program it might be caused by some memory freeing routine - but I don't know exactly if this is the problem (it only occures if I load a Model with Model::3DSLoad(), it doesn't if I dont load any!). I'm really frustrated - I tried to look up this error, a long time but I couldn't find anything. I'm stuck now and help would be really really great. Either it is just a stupid little mistake or it's a really complicated thing

Some detailed information:
Violation caused by: 0x77f4215c (don't know how to find the function call concerning this address)
To Memory 0x00000000 could not be "written".
Here's my 3DS Class Code if needed. MODEL is the class that holdes the model data (vertices etc.) and Model3DS is the Class that is responsible for loading 3DS Data to the MODEL structure.
//---------#> 3DS File Loader <#---------
#include "main.h"
#include "3ds.h"
//This is the Model class which holdes the object and material data of a model
MODEL::MODEL(void)
{
tSkins = NULL;
bHasDependencies = false;
numOfObjects = 0;
numOfMaterials = 0;
}
MODEL::~MODEL(void)
{
if(tSkins && bHasDependencies)
delete [] tSkins;
tSkins = NULL;
for(int i=0; i < numOfObjects; i++)
{
delete [] Object[i].Faces;
delete [] Object[i].Normals;
delete [] Object[i].TexVerts;
delete [] Object[i].Verts;
}
numOfObjects = 0;
numOfMaterials = 0;
}
bool MODEL::HasModel(void)
{
if(numOfObjects > 0)
return true;
else
return false;
}
bool MODEL::LoadDependencies(char *szPath)
{
bool tmpRetVal = true;
if(HasModel())
{
tSkins = new Texture [numOfMaterials];
for(int i=0; i < numOfMaterials; i++)
{
if(strlen(Materials[i].szFile) > 0)
{
char szTmpFile[255];
wsprintf(szTmpFile, "%s%s", szPath, Materials[i].szFile);
if(tSkins[i].LoadFromFile(szTmpFile) == false)
tmpRetVal = false;
}
Materials[i].texID = i;
}
}
bHasDependencies = true;
return tmpRetVal;
}
void MODEL::Draw(void)
{
for(int i=0; i < numOfObjects; i++)
{
if(Object.size() <= 0) break;
if(Object[i].bHasTexture)
{
glEnable(GL_TEXTURE_2D);
glColor3f(1.0, 1.0, 1.0);
tSkins[Object[i].materialID].Bind();
if(tSkins[Object[i].materialID].GetImageChannels() == 4)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5);
}
}
else
{
glDisable(GL_TEXTURE_2D);
glColor3f(1.0, 1.0, 1.0);
}
glBegin(GL_TRIANGLES);
for(int t=0; t < Object[i].numOfFaces; t++)
{
for(int v=0; v < 3; v++)
{
int index = Object[i].Faces[t].vertIndex[v];
glNormal3f(Object[i].Normals[index].x, Object[i].Normals[index].y, Object[i].Normals[index].z);
if(Object[i].bHasTexture)
{
if(Object[i].TexVerts)
glTexCoord2f(Object[i].TexVerts[index].x, Object[i].TexVerts[index].y);
}
else
{
if(Materials.size() && Object[i].materialID >= 0)
glColor3f(float(Materials[Object[i].materialID].color[0]) / 256.0, float(Materials[Object[i].materialID].color[1]) / 256.0, float(Materials[Object[i].materialID].color[2]) / 256.0);
}
glVertex3f(Object[i].Verts[index].x, Object[i].Verts[index].y, Object[i].Verts[index].z);
}
}
glEnd();
glDisable(GL_ALPHA_TEST);
}
}
void MODEL::PrivateGetBoundingSphere(Vector3 *center, float *radius)
{
float hx = 0.0, hy = 0.0, hz = 0.0;
for(int i=0; i < numOfObjects; i++)
{
for(int n=0; n < ObjectArrays[i].VertexCounter * 3; n += 3)
{
if(ObjectArrays[i].Vertices[n + 0] > hx)
hx = ObjectArrays[i].Vertices[n + 0];
if(ObjectArrays[i].Vertices[n + 0] > hy)
hy = ObjectArrays[i].Vertices[n + 1];
if(ObjectArrays[i].Vertices[n + 0] > hz)
hz = ObjectArrays[i].Vertices[n + 2];
}
}
Vector3 tmp;
tmp.x = hx / 2;
tmp.y = hy / 2;
tmp.z = hz / 2;
if(hx > hy && hx > hz)
*radius = hx * 2;
else if(hy > hx && hy > hz)
*radius = hy * 2;
else
*radius = hz * 2;
*center = tmp;
}
void MODEL::GetBoundingSphere(Vector3 *center, float *radius)
{
*center = vCenter;
*radius = fRadius;
}
void MODEL::GetBoundingSphere(float *x, float *y, float *z, float *radius)
{
*x = vCenter.x;
*y = vCenter.y;
*z = vCenter.z;
*radius = fRadius;
}
//The Model3DS Class which is responsible for loading 3DS model files
Model3DS::Model3DS(void)
{
currentChunk = new CHUNK;
currentChunk->bytesRead = 0;
currentChunk->length = 0;
tmpChunk = new CHUNK;
tmpChunk->bytesRead = 0;
tmpChunk->length = 0;
bChangeAxis = true;
}
Model3DS::~Model3DS(void)
{
}
bool Model3DS::Load(MODEL *Model, char *szFilename)
{
char szMessage[255] = {0};
file = fopen(szFilename, "rb");
if(!file)
{
wsprintf(szMessage, "Error loading 3DS file: %s", szFilename);
MessageBox(NULL, szMessage, "Error", MB_OK | MB_ICONERROR);
return false;
}
ReadChunk(currentChunk);
if(currentChunk->ID != PRIMARY)
{
wsprintf(szMessage, "Not a 3DS file: %s", szFilename);
MessageBox(NULL, szMessage, "Error", MB_OK | MB_ICONERROR);
return false;
}
ProcessNextChunk(Model, currentChunk);
ComputeNormals(Model);
CleanUp();
return true;
}
void Model3DS::CleanUp(void)
{
fclose(file);
delete currentChunk;
delete tmpChunk;
}
void Model3DS::ProcessNextChunk(MODEL *Model, CHUNK *previousChunk)
{
OBJECT_INFO newObject = {0};
MATERIAL_INFO newTexture = {0};
unsigned int version = 0;
int buffer[50000] = {0};
currentChunk = new CHUNK;
while(previousChunk->bytesRead < previousChunk->length)
{
ReadChunk(currentChunk);
switch(currentChunk->ID)
{
case VERSION:
currentChunk->bytesRead += fread(&version, 1, currentChunk->length - currentChunk->bytesRead, file);
if(version > 0x03)
MessageBox(NULL, "The 3DS file is newer than version 3.\n It may load incorrectly!", "Warning", MB_OK | MB_ICONEXCLAMATION);
break;
case OBJECTINFO:
ReadChunk(tmpChunk);
tmpChunk->bytesRead += fread(&version, 1, tmpChunk->length - tmpChunk->bytesRead, file);
currentChunk->bytesRead += tmpChunk->bytesRead;
ProcessNextChunk(Model, currentChunk);
break;
case MATERIAL:
Model->numOfMaterials++;
Model->Materials.push_back(newTexture);
ProcessNextMaterialChunk(Model, currentChunk);
break;
case OBJECT:
Model->numOfObjects++;
Model->Object.push_back(newObject);
memset(&(Model->Object[Model->numOfObjects - 1]), 0, sizeof(OBJECT_INFO));
currentChunk->bytesRead += GetString(Model->Object[Model->numOfObjects - 1].szName);
ProcessNextObjectChunk(Model, &(Model->Object[Model->numOfObjects - 1]), currentChunk);
break;
default:
currentChunk->bytesRead += fread(buffer, 1, currentChunk->length - currentChunk->bytesRead, file);
break;
}
previousChunk->bytesRead += currentChunk->bytesRead;
}
delete currentChunk;
currentChunk = previousChunk;
}
void Model3DS::ProcessNextObjectChunk(MODEL *Model, OBJECT_INFO *Object, CHUNK *previousChunk)
{
int buffer[50000] = {0};
currentChunk = new CHUNK;
while(previousChunk->bytesRead < previousChunk->length)
{
ReadChunk(currentChunk);
switch(currentChunk->ID)
{
case OBJECTMESH:
ProcessNextObjectChunk(Model, Object, currentChunk);
break;
case OBJECT_VERTICES:
ReadVertices(Object, currentChunk);
break;
case OBJECT_FACES:
ReadVertexIndices(Object, currentChunk);
break;
case OBJECT_MATERIAL:
ReadObjectMaterial(Model, Object, currentChunk);
break;
case OBJECT_UV:
ReadUVCoordinates(Object, currentChunk);
break;
default:
currentChunk->bytesRead += fread(buffer, 1, currentChunk->length - currentChunk->bytesRead, file);
break;
}
previousChunk->bytesRead += currentChunk->bytesRead;
}
delete currentChunk;
currentChunk = previousChunk;
}
void Model3DS::ProcessNextMaterialChunk(MODEL *Model, CHUNK *previousChunk)
{
int buffer[50000] = {0};
currentChunk = new CHUNK;
while(previousChunk->bytesRead < previousChunk->length)
{
ReadChunk(currentChunk);
switch(currentChunk->ID)
{
case MATNAME:
currentChunk->bytesRead += fread(Model->Materials[Model->numOfMaterials - 1].szName, 1, currentChunk->length - currentChunk->bytesRead, file);
break;
case MATDIFFUSE:
ReadColorChunk(&(Model->Materials[Model->numOfMaterials - 1]), currentChunk);
break;
case MATMAP:
ProcessNextMaterialChunk(Model, currentChunk);
break;
case MATMAPFILE:
currentChunk->bytesRead += fread(Model->Materials[Model->numOfMaterials - 1].szFile, 1, currentChunk->length - currentChunk->bytesRead, file);
break;
default:
currentChunk->bytesRead += fread(buffer, 1, currentChunk->length - currentChunk->bytesRead, file);
break;
}
previousChunk->bytesRead += currentChunk->bytesRead;
}
delete currentChunk;
currentChunk = previousChunk;
}
void Model3DS::ReadChunk(CHUNK *Chunk)
{
Chunk->bytesRead = 0;
Chunk->bytesRead += fread(&Chunk->ID, 1, 2, file);
Chunk->bytesRead += fread(&Chunk->length, 1, 4, file);
}
int Model3DS::GetString(char *buffer)
{
int index = 0;
fread(buffer, 1, 1, file);
while(*(buffer + index++) != 0)
{
fread(buffer + index, 1, 1, file);
}
return strlen(buffer) + 1;
}
void Model3DS::ReadColorChunk(MATERIAL_INFO *Material, CHUNK *Chunk)
{
ReadChunk(tmpChunk);
tmpChunk->bytesRead += fread(Material->color, 1, tmpChunk->length - tmpChunk->bytesRead, file);
Chunk->bytesRead += tmpChunk->bytesRead;
}
void Model3DS::ReadVertexIndices(OBJECT_INFO *Object, CHUNK *previousChunk)
{
unsigned short index = 0;
previousChunk->bytesRead += fread(&Object->numOfFaces, 1, 2, file);
Object->Faces = new FACE [Object->numOfFaces];
memset(Object->Faces, 0, sizeof(FACE) * Object->numOfFaces);
for(int i=0; i < Object->numOfFaces; i++)
{
for(int j=0; j < 4; j++)
{
previousChunk->bytesRead += fread(&index, 1, sizeof(index), file);
if(j < 3)
{
Object->Faces[i].vertIndex[j] = index;
}
}
}
}
void Model3DS::ReadUVCoordinates(OBJECT_INFO *Object, CHUNK *previousChunk)
{
previousChunk->bytesRead += fread(&Object->numTexVertex, 1, 2, file);
Object->TexVerts = new Vector2 [Object->numTexVertex];
previousChunk->bytesRead += fread(Object->TexVerts, 1, previousChunk->length - previousChunk->bytesRead, file);
}
void Model3DS::ReadVertices(OBJECT_INFO *Object, CHUNK *previousChunk)
{
previousChunk->bytesRead += fread(&(Object->numOfVerts), 1, 2, file);
Object->Verts = new Vector3 [Object->numOfVerts];
memset(Object->Verts, 0, sizeof(Vector3) * Object->numOfVerts);
previousChunk->bytesRead += fread(Object->Verts, 1, previousChunk->length - previousChunk->bytesRead, file);
if(bChangeAxis)
{
for(int i=0; i < Object->numOfVerts; i++)
{
float tmpY = Object->Verts[i].y;
Object->Verts[i].y = Object->Verts[i].z;
Object->Verts[i].z = -tmpY;
}
}
}
void Model3DS::ReadObjectMaterial(MODEL *Model, OBJECT_INFO *Object, CHUNK *previousChunk)
{
char szMaterial[255] = {0};
int buffer[50000] = {0};
previousChunk->bytesRead += GetString(szMaterial);
for(int i=0; i < Model->numOfMaterials; i++)
{
if(strcmp(szMaterial, Model->Materials[i].szName) == 0)
{
Object->materialID = i;
if(strlen(Model->Materials[i].szFile) > 0)
{
Object->bHasTexture = true;
}
break;
}
else
{
Object->materialID = -1;
}
}
previousChunk->bytesRead += fread(buffer, 1, previousChunk->length - previousChunk->bytesRead, file);
}
void Model3DS::ComputeNormals(MODEL *Model)
{
Vector3 vVector1, vVector2, vNormal, vTriangle[3];
if(Model->numOfObjects <= 0)
return;
for(int index=0; index < Model->numOfObjects; index++)
{
OBJECT_INFO *Object = &(Model->Object[index]);
Vector3 *Normals = new Vector3 [Object->numOfFaces];
Vector3 *tmpNormals = new Vector3 [Object->numOfFaces];
Object->Normals = new Vector3 [Object->numOfVerts];
for(int i=0; i < Object->numOfFaces; i++)
{
vTriangle[0] = Object->Verts[Object->Faces[i].vertIndex[0]];
vTriangle[1] = Object->Verts[Object->Faces[i].vertIndex[1]];
vTriangle[2] = Object->Verts[Object->Faces[i].vertIndex[2]];
vVector1 = Distance(vTriangle[0], vTriangle[2]);
vVector2 = Distance(vTriangle[2], vTriangle[1]);
vNormal = CrossProduct(vVector1, vVector2);
tmpNormals[i] = vNormal;
vNormal = Normalize(vNormal);
Normals[i] = vNormal;
}
Vector3 vSum;
vSum.x = 0.0; vSum.y = 0.0; vSum.z = 0.0;
Vector3 vZero = vSum;
int shared = 0;
for(int i=0; i < Object->numOfVerts; i++)
{
for(int j=0; j < Object->numOfFaces; j++)
{
if(Object->Faces[j].vertIndex[0] == i || Object->Faces[j].vertIndex[1] == i || Object->Faces[j].vertIndex[2] == i)
{
vSum = AddVector(vSum, tmpNormals[j]);
shared++;
}
}
Object->Normals[i] = DivideVector(vSum, float(-shared));
Object->Normals[i] = Normalize(Object->Normals[i]);
vSum = vZero;
shared = 0;
}
delete [] tmpNormals;
delete [] Normals;
}
}
void Model3DS::UnLoad(MODEL *Model)
{
Model->~MODEL();
}
[edited by - ZMaster on June 23, 2003 12:56:31 PM]
[edited by - ZMaster on June 23, 2003 12:58:35 PM]