can someone explain me why this isn't working?!

Started by
13 comments, last by Pipo DeClown 19 years, 7 months ago
Hi, I'm trying to load a custom model file format, that is somthing like this:

MDXVersion 1
nummeshes 1
mesh 0 {
	name "mesh0"
	position 0.000000 0.000000 0.000000
	shader "fatty"
 	numfaces 1274
	0 1 2           // vertIndexes
	1 3 2
	4 5 6
	7 5 4
	2 8 7
	7 8 5
	2 3 8
	9 0 10
	10 7 4
	0 7 10
	0 2 7
	11 1 0
	12 0 9
	12 11 0
	13 14 15
	15 14 16
	4 6 17
	18 4 17
	14 18 19
	18 17 19
	14 19 16
	9 10 13
	10 4 18
	13 10 18
	13 18 14
	20 13 15
	12 9 13
	12 13 20
	21 22 23
	24 25 26
	27 28 29
	30 28 27
	31 32 33
	34 35 36
	37 30 38
	38 30 27
	23 22 28
	37 39 30
	31 33 22
	39 23 30
	23 28 30
	40 32 31
	21 31 22
	41 42 24
	24 42 25
	43 34 36
	41 44 42	
        ....
	numverts 874
	11.502138 3.866233 41.562920  0.566084 0.647433      // x y z  u v
	7.626759 7.955867 42.226231  0.636396 0.654303
	10.920886 5.859262 45.897800  0.592573 0.692329
	7.447500 7.572735 47.273094  0.630541 0.706572
	12.999125 0.000000 47.671406  0.514699 0.710698
	10.947019 3.065768 52.062096  0.555445 0.756172
	10.788542 0.000000 52.921532  0.514699 0.765073
	12.800956 3.280507 46.921501  0.558300 0.702930
	9.189686 5.917538 51.321003  0.593348 0.748497
	12.126164 0.000000 40.651314  0.514699 0.637991
	13.320319 0.000000 43.548985  0.514699 0.668003
	7.638112 6.067189 39.755192  0.595338 0.620508
	9.155236 0.000000 38.396923  0.514699 0.606440
	11.502138 -3.866233 41.562920  0.463312 0.647433
	10.920897 -5.859269 45.897850  0.436823 0.692329
	7.626759 -7.955867 42.226231  0.393247 0.654303
	7.447493 -7.572727 47.273045  0.399102 0.706572
	10.947018 -3.065768 52.062096  0.473952 0.756172
	12.800942 -3.280504 46.921455  0.471097 0.702930
	9.189686 -5.917538 51.320999  0.436048 0.748497
	7.638112 -6.067189 39.755192  0.434059 0.620508
	2.277341 11.187534 34.578468  0.848979 0.937457
	2.735829 10.527866 38.762482  0.845042 0.976082
	7.339963 8.921386 35.316368  0.811320 0.944269
	-8.446324 3.128572 32.720997  0.954816 0.920310
	-9.017501 3.379551 35.457867  0.954457 0.945575	
        .....
}




this is how I'm parsing the file:

struct Vertex
{
	D3DXVECTOR3 position;
	D3DXVECTOR3 normal;
	float texCoord[2];
};

struct Face
{
	int vertIndex[3];
};

struct Tex
{
	char texPath[255];
};

struct Mesh
{
	int m_iNumVerts;
	Vertex *m_pVert;

	int m_iNumFaces;
	Face *m_pFace;

	Tex *m_pTex;

	D3DXVECTOR3 position;

	char meshName[255];
};

class CMdx
{
public:
	CMdx();
	~CMdx();

	bool Load(char *fileName);
	void Draw();

	char *path;

	int m_iVersion;

	int m_iMeshIndex;

	int m_iNumMeshes;
	Mesh *m_pMeshes;
private:
	void BuildNormals();
	void ReadObject(FILE *file, Mesh &oMesh);
};

...

bool CMdx::Load(char *fileName)
{
	char strWord[255];
	FILE *file = fopen(fileName, "r");
	if(!file)
		return false;

	// Read MDX Version
	fscanf(file, "MDXVersion %d\n", &m_iVersion);
	if(m_iVersion != MDX_VERSION)
	{
		// Wrong Version
		return false;
	}

    // Read Number of Meshes
	fscanf(file, "nummeshes %d\n", &m_iNumMeshes);
	if(m_iNumMeshes<=0)
	{
		return false;
	}
	else
	{
		// Allocate Memory For Meshes
		m_pMeshes = new Mesh[m_iNumMeshes];
	}

	while(!feof(file))
	{
		fscanf(file, "%s", &strWord);

		if(!strcmp(strWord, "mesh"))
		{
			// Get mesh index and start reading object
			fscanf(file, " %d {", &m_iMeshIndex);
			ReadObject(file, m_pMeshes[m_iMeshIndex]);
		}
	}

	fclose(file);

	return true;
}

void CMdx::ReadObject(FILE *file, Mesh &oMesh)
{
	// Read Mesh Name
	fscanf(file, "\tname \"%s", &oMesh.meshName);
	oMesh.meshName[strlen(oMesh.meshName)-1] = '\0';

	// Read Mesh Position
	fscanf(file, "\tposition %f %f %f", &oMesh.position.x, &oMesh.position.y, &oMesh.position.z);

	// Read shader
	oMesh.m_pTex = new Tex;
	fscanf(file, "\tshader \"%s\"", &oMesh.m_pTex->texPath);
	oMesh.m_pTex->texPath[strlen(oMesh.m_pTex->texPath)-1] = '\0';

	// Read Faces
	fscanf(file, "\tnumfaces %d", &oMesh.m_iNumFaces);
	oMesh.m_pFace = new Face[oMesh.m_iNumFaces];
	for(int j=0; j<oMesh.m_iNumFaces; j++)
	{
		Face &f = oMesh.m_pFace[j];
		fscanf(file, "\t%d %d %d", &f.vertIndex[0], &f.vertIndex[1], &f.vertIndex[2]);
	}

	// Read Vertices
	fscanf(file, "\tnumverts %d", &oMesh.m_iNumVerts);
	oMesh.m_pVert = new Vertex[oMesh.m_iNumVerts];
	for(int i=0; i<oMesh.m_iNumVerts; i++)
	{
		Vertex &v = oMesh.m_pVert;
		// Y <-> Z (3ds max purposes)
		fscanf(file, "\t%f %f %f  %f %f", &v.position.x, &v.position.z, &v.position.y,													
													&v.texCoord[0], &v.texCoord[1]);
		v.position.z = -v.position.z;
	}
}




and this is how I'm trying to draw:

IDirect3DVertexBuffer9 *g_pVB = NULL;
IDirect3DIndexBuffer9* g_pIB = NULL;

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

CMdx *mdx;

...

g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, true);

bool InitializeGeometry()
{
	mdx = new CMdx();
	mdx->Load("C://fatty.mdx");

	if(FAILED(g_pd3dDevice->CreateVertexBuffer(sizeof(Vertex)*mdx->m_pMeshes[0].m_iNumVerts, 0,
		D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL)))
		return false;

	if(FAILED(g_pd3dDevice->CreateIndexBuffer(sizeof(WORD)*mdx->m_pMeshes[0].m_iNumFaces, D3DUSAGE_WRITEONLY,
		D3DFMT_INDEX16, D3DPOOL_MANAGED, &g_pIB, NULL)))
		return false;

	Vertex* verts;
	if(FAILED(g_pVB->Lock(0, 0, (void**)&verts, 0)))
		return false;
	memcpy(verts, mdx->m_pMeshes[0].m_pVert, sizeof(Vertex)*mdx->m_pMeshes[0].m_iNumVerts);
	g_pVB->Unlock();

    WORD* indices;
	if(FAILED(g_pIB->Lock(0, 0, (void**)&indices, 0)))
		return false;
	memcpy(indices, mdx->m_pMeshes[0].m_pFace, sizeof(WORD)*mdx->m_pMeshes[0].m_iNumFaces);
	g_pIB->Unlock();

	return true;
}

void SetupMatrices()
{
	D3DXMATRIX matWorld;
	UINT  iTime  = timeGetTime() % 1000;
    float fAngle = iTime * (2.0f * D3DX_PI) / 1000.0f;
	D3DXMatrixRotationY(&matWorld, fAngle);
	g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);

	D3DXMATRIX matView;
	D3DXMatrixLookAtLH(&matView, new D3DXVECTOR3(0.0f, 70.0f, -270.0f), new D3DXVECTOR3(2.0f, 30.0f, -30.0f), new D3DXVECTOR3(0.0f, 1.0f, 0.0f));
	g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);

    D3DXMATRIX matProj;
	D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 500.f);
	g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}

void Render()
{
	if(g_pd3dDevice == NULL)
		return;

	g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(234, 234, 234), 1.0f, 0);

	g_pd3dDevice->BeginScene();

	SetupMatrices();

	g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(Vertex));
	g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
	g_pd3dDevice->SetIndices(g_pIB);
	g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, mdx->m_pMeshes[0].m_iNumVerts, 0, mdx->m_pMeshes[0].m_iNumFaces);

	g_pd3dDevice->EndScene();
	g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}




this is what I get, when I run the app: (I was expecting a doom3 model) I'm not trying to draw it textured, or even lighted... I just want to see the damn model! Any help with be hugely appreciated Thanks [Edited by - xyz on September 2, 2004 12:19:52 PM]
Advertisement
Tip: write a save-function to save the data into a file again. Now you can check if you loaded properly. (This is better than testing with rendering)

Have you set up the Z-Buffer in your Present Parameters?
Quote:Original post by Pipo DeClown
Tip: write a save-function to save the data into a file again. Now you can check if you loaded properly. (This is better than testing with rendering)


this is the exact same loader I use in my (functioning!) opengl app...

Quote:Original post by Pipo DeClown
Have you set up the Z-Buffer in your Present Parameters?


yep...
The triangles you see, going into 'infinty', are a result of missing vertices. Look in your modelfile: it says 'numverts 874', but there is nowhere near that many vertices listed, or didn't you post them all?
Quote:Original post by Kenneth Gorking
The triangles you see, going into 'infinty', are a result of missing vertices. Look in your modelfile: it says 'numverts 874', but there is nowhere near that many vertices listed, or didn't you post them all?


I didn't post them all... I use this file and this loader in my ogl renderer, and it works just fine...
Your FVF for the D3D VertexBuffer and DrawPrim calls don't match the vertex for the data.

Your Vertex struct has position, normal, and texcoords, your FVF only has position and color. You are using memcpy to fill the VB with different data than you are telling DrawPrimitive it has.

Change this line:

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

to

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)

Also, if you want color (D3DFVF_DIFFUSE) then you need to add it to your Vertex struct.
Quote:Original post by reltham
Your FVF for the D3D VertexBuffer and DrawPrim calls don't match the vertex for the data.

Your Vertex struct has position, normal, and texcoords, your FVF only has position and color. You are using memcpy to fill the VB with different data than you are telling DrawPrimitive it has.

Change this line:

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

to

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)

Also, if you want color (D3DFVF_DIFFUSE) then you need to add it to your Vertex struct.


well... makes sense, but the result is the same... :(

Any other thoughts?
Whenever you get a polygon soup like that, it's because either your vertex stream doesn't match the structure, the structure doesn't match the FVF, or both. Simplify it, then build on that. Try this:
struct Vertex{	D3DXVECTOR3 position;};

and this:
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ)

Ryan Buhr

Technical Lead | Sector 13

Reactor Interactive, LLC

Facebook | Twitter

Quote:Original post by HanSoL0
Whenever you get a polygon soup like that, it's because either your vertex stream doesn't match the structure, the structure doesn't match the FVF, or both. Simplify it, then build on that. Try this:
struct Vertex{	D3DXVECTOR3 position;};

and this:
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ)


tried... and got the same "polygon soup" :(

I suspect the problem is somewhere in the index buffer creation:

by myself
if(FAILED(g_pd3dDevice->CreateIndexBuffer(sizeof(WORD)*mdx->m_pMeshes[0].m_iNumFaces, D3DUSAGE_WRITEONLY,		D3DFMT_INDEX16, D3DPOOL_MANAGED, &g_pIB, NULL)))		return false;	    WORD* indices;	if(FAILED(g_pIB->Lock(0, 0, (void**)&indices, 0)))		return false;	memcpy(indices, mdx->m_pMeshes[0].m_pFace, sizeof(WORD)*mdx->m_pMeshes[0].m_iNumFaces);	g_pIB->Unlock();



more specifically in the first param of CreateIndexBuffer, and the 2nd param in memcpy. Couse, for basic stuff, like a quad, you would set up the indices like this:

short indices[] = { 0, 1, 2, 3, 0, 2 };


but what I have here is an array of 3 indices of a time... what do you think? if this is the problem, how can I solve it?

Huge thanks again


I have a question. For example, your vertex number 36 are being used twice. In this case, the first time it is being used is using UV(1.0, 0.0), the second time it MAY use UV(1.1, -0.4). But in your MDX file, your UVs stick with every vertex, how do you resolve this?

Thanks,

Andy

This topic is closed to new replies.

Advertisement