Skip to main content
gamedev.net
🔒 Locked

Structures and pointers

Started by Thomo Jun 4, 2006 at 7:22 AM 9 replies 700+ views
Original Post
Thomo
Thomo
I want to load in mesh information into my C app from a direct x mesh files. My custom MODEL is as follows:

typedef struct Vertex {

	float x, y, z;
	float u, v;
	float nx, ny, nz;

} VERTEX;

typedef struct FaceIndex {

	int nFacesIndices;

	int *nIndices;

} FACE_INDEX;

typedef struct Mesh {

	char name[512];

	char textureName[1024];

	int nVertices;
	int nTextureCoords;
	int nFaces;

	VERTEX *pVertexBuffer;
	FACE_INDEX *pFaceIndexBuffer;


} MESH;

typedef struct Model {

	MESH *pMesh;

} MODEL;

Basicallly, this says that I have a model file, which will contain sub meshes. It's fairly self explanatory. I parse the information from the x file into the custom model in c file separate from the main fucntion. I wont post the parsing code as it is a bit long winded. I know the information is being loaded correctly as I print information as it parses. In my main function I do the following:

pModels = (MODEL*) calloc (MAX_MODELS, sizeof(MODEL));

for (model = 0; model < 7; model++) {

	pModels[model].pMesh = (MESH*) calloc (10, sizeof(MESH));

}

loadXModels(&pModels);


This creates MAX_MODELS number of models and 7 submeshes for each model. pModels and pMesh are both global variables. After the load X models code I try to print the some information from the first (and only, at present) model to the console window. printf("faces = %d ", pModels[0].pMesh[0].nFaces); The program crashes on this piece of code. The debugger says that MESH name, nFaces etc are bad pointers. Not sure what hte problem is. Can someone hepl please? Thanks, Thomo
Hot Dog
Hot Dog
I may be wrong, but I have never seen a for loop in C/C++ with 4 statements as its control:

for (model = 0; model < 7; model++) {
}

Did you mistype something here?


Joshua


EDIT: sorry...ignore my post. My bad...
Thomo
Thomo
The statement is correct in the program (as you have typed it). Something must have changed during the copy and paste process from VS to the post.
_goat
_goat
The easy answer is yes: The problem is in your loading code somewhere.

The better answer is no: We need to see more code. :D

Feel free.
Thomo
Thomo
Ok...here's the code that parses the x file....
void loadXModels(MODEL *pModel) {	FILE *fp;	BOOL bFound;	int index;	int faceIndex;	char name[512];	char buffer[512];	float verts[3];	char *token1;	char delims[512] = " ,;{}\n\"";	int model;	int mesh;	int nMeshes = 0;	int nOccur = 0;		for (model = 0; model < 1; model++) {				fp = fopen("head 1.x", "r");		if (!fp)			printf("poo");				while (nOccur < 2) {			fgets(buffer, 512, fp);			token1 = strtok(buffer, delims);			while (token1 != NULL) {								if (strcmp(token1, "FrameTransformMatrix") == 0) {										nOccur++;					printf("%d\n", nOccur);									}				token1 = strtok(NULL, delims);							}								}		/*			fgets(buffer, 512, fp);			fgets(buffer, 512, fp);			fgets(buffer, 512, fp);			fgets(buffer, 512, fp);			fgets(buffer, 512, fp);			fgets(buffer, 512, fp);*/			nOccur = 0;		for (mesh = 0; mesh < 7; mesh++) {			bFound = FALSE;			while (bFound == FALSE) {				fgets(buffer, 512, fp);				token1 = strtok(buffer, delims);				while (token1 != NULL) {					if (strcmp(token1, "Mesh") == 0) {												bFound = TRUE;						token1 = strtok(NULL, delims);						strcpy(pModel[model].pMesh[mesh].name, token1);					}										token1 = strtok(NULL, delims);						}										}			printf("name = %s\n", pModel[model].pMesh[mesh].name);			fgets(buffer, 512, fp);			token1 = strtok(buffer, delims);			pModel[model].pMesh[mesh].nVertices = atoi(token1);			pModel[model].pMesh[mesh].pVertexBuffer = (VERTEX*) calloc (pModel[model].pMesh[mesh].nVertices, sizeof(VERTEX));			printf("verts = %d\n", pModel[model].pMesh[mesh].nVertices);			for (index = 0; index < pModel[model].pMesh[mesh].nVertices; index++) {				fgets(buffer, 512, fp);				token1 = strtok(buffer, ";");				pModel[model].pMesh[mesh].pVertexBuffer[index].x = atof(token1);				//printf("%f\n", pMesh[mesh].pVertexBuffer[index].x);				token1 = strtok(NULL, ";");				pModel[model].pMesh[mesh].pVertexBuffer[index].y = atof(token1);				//printf("%f\n", pMesh[mesh].pVertexBuffer[index].y);				token1 = strtok(NULL, ";");				pModel[model].pMesh[mesh].pVertexBuffer[index].z = atof(token1);				//printf("%f\n", pMesh[mesh].pVertexBuffer[index].z);				//while (getchar() != '\n') {}			}			fgets(buffer, 512, fp);			fgets(buffer, 512, fp);			token1 = strtok(buffer, delims);			pModel[model].pMesh[mesh].nFaces = atoi(token1);			printf("faces = %d\n", pModel[model].pMesh[mesh].nFaces);			pModel[model].pMesh[mesh].pFaceIndexBuffer = (int*) calloc (pModel[model].pMesh[mesh].nVertices, sizeof(int));			printf("test 2");			for (index = 0; index < pModel[model].pMesh[mesh].nFaces; index++) {				fgets(buffer, 512, fp);				token1 = strtok(buffer, delims);				pModel[model].pMesh[mesh].pFaceIndexBuffer->nFacesIndices = atoi(token1);				pModel[model].pMesh[mesh].pFaceIndexBuffer->nIndices = (int*) calloc (pModel[model].pMesh[mesh].pFaceIndexBuffer->nFacesIndices, sizeof(int));				for (faceIndex = 0; faceIndex < pModel[model].pMesh[mesh].pFaceIndexBuffer->nFacesIndices; faceIndex++) {					token1 = strtok(NULL, delims);					pModel[model].pMesh[mesh].pFaceIndexBuffer->nIndices[faceIndex] = atoi(token1);					//printf("Index = %d\n", pMesh[mesh].pFaceIndexBuffer->nIndices[faceIndex]);					//while (getchar() != '\n') {}				}			}			printf("test 1");			bFound = FALSE;			while (bFound == FALSE) {				fgets(buffer, 512, fp);				token1 = strtok(buffer, delims);				while (token1 != NULL) {					if (strcmp(token1, "TextureFilename") == 0) {												bFound = TRUE;												strcpy(name, token1);						printf("%s\n", token1);					}										token1 = strtok(NULL, delims);				}								}			fgets(buffer, 512, fp);			token1 = strtok(buffer, delims);			strcpy(pModel[model].pMesh[mesh].textureName, token1);			printf("name = %s\n", pModel[model].pMesh[mesh].textureName);			bFound = FALSE;			while (bFound == FALSE) {				fgets(buffer, 512, fp);				token1 = strtok(buffer, delims);				while (token1 != NULL) {					if (strcmp(token1, "MeshTextureCoords") == 0) {												bFound = TRUE;												strcpy(name, token1);						printf("%s\n", token1);					}										token1 = strtok(NULL, delims);				}								}			fgets(buffer, 512, fp);			token1 = strtok(buffer, delims);			pModel[model].pMesh[mesh].nTextureCoords = atoi(token1);			printf("tex coords = %d\n\n", pModel[model].pMesh[mesh].nTextureCoords);			for (index = 0; index < pModel[model].pMesh[mesh].nTextureCoords; index++) {				fgets(buffer, 512, fp);				token1 = strtok(buffer, delims);				pModel[model].pMesh[mesh].pVertexBuffer[index].u = atof(token1);				//printf("u = %f", pMesh[mesh].pVertexBuffer[index].u);				token1 = strtok(NULL, delims);				pModel[model].pMesh[mesh].pVertexBuffer[index].v = atof(token1);				//printf("v = %f", pMesh[mesh].pVertexBuffer[index].v);				//while (getchar() != '\n') {}			}			nMeshes++;		}	}	return;}


hope this sheds light on it.
Thomo
Thomo
OK....I figured out a possible cause.

I am now returning a pointer from loadXModels and assigning it to pModels in main.

Now I get this error on assignment:

The instruction at '
' referenced memory at '
'.
The memory could not be read.

Does this shed any light on it???
Thomo
Thomo
OK I resolved my problem....but, can someone tell me the difference between these two pieces of code:

typedef struct Model {	MESH *pMesh;} MODEL;int _tmain(int argc, _TCHAR* argv[]){	MODEL *pModels;	MODEL *pMod;	pModels = (MODEL*) calloc (MAX_MODELS, sizeof(MODEL));	pModels = loadXModels(&pMod);	printf("faces = %s ", pModels[0].pMesh[0].name);


The above works fine.
int _tmain(int argc, _TCHAR* argv[]){	MODEL *pModels;		pModels = (MODEL*) calloc (MAX_MODELS, sizeof(MODEL));	pModels = loadXModels(&pModels);	printf("faces = %s ", pModels[0].pMesh[0].name);

The above code produces spurious results (the printed value is garbage).

Thomo
_goat
_goat
pModels is a MODEL*!! (Something I should have caught in your first post). You don't need to take the address of it. I have no idea why your "working" code is actually working - it is probably a coincidence. If you were following good practice, and had initialised pMod to NULL, it'd probably bork.

Here:

int _tmain(int argc, _TCHAR* argv[]){	MODEL *pModels;	pModels = (MODEL*) calloc (MAX_MODELS, sizeof(MODEL));        // not &pModels - that would make it a MODEL**	pModels = loadXModels(pModels);	printf("faces = %s ", pModels[0].pMesh[0].name);}
jsaade
jsaade
well just a simple question, wouldnt be easier to use D3DXLoadMeshFromFile ?
u can read the model info from the mesh vertex buffer.
Zahlman
Zahlman
That shouldn't even compile: You defined loadXModel() to return void, and then try to assign the void back to your pointer (for no good reason).

I would just return a MODEL* from loadXModel(), having it do the memory allocation. Although you should probably call it loadXModels(), since it looks like you're designing to be able to load more than one model in a loop in the future o_o

Beyond that, there's lots of opportunity for cleanup, but C makes me shudder anyway. And do you really need strtok()? Do you have any control over this file format? But yeah, please cut it up into subfunctions and see what obvious changes happen as a result. :)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.