Problem mit XFile Loader!!!



  • Hi!
    Ich habe jetzt mal einen XFile Loader für meine Engine geschrieben!Aber irgendwas habe ich falsch gemacht!Es wird nichts angezeigt!Wahrscheinlich liegt der Fehler irgendwio beim Renderer!Könnt ihrmir mal bitte helfen!ICh bin echt am verzweifeln!

    Hier der Code:

    #include <stdio.h>
    #include "RBWModell.h"
    #include <rmxftmpl.h>  // Direct3D RM Template Definitionen
    #include <rmxfguid.h> 
    
    CAModell::CAModell(char *chDateiName, int nLOD, LPDIRECT3DDEVICE9 lpDevice)
    {
    	this->m_blnMesh           = FALSE;
    	this->m_dwAnz_Vertices  = 0;
    	this->m_dwAnz_Indices    = 0;
    	this->m_dwAnz_Materials = 0;
    	this->m_pVertexliste    = NULL;
    	this->m_pMaterialliste  = NULL;
    	this->m_pTriangles      = NULL;
    	this->m_pNextLOD        = NULL;
    	this->m_pKind           = NULL;
    
    	if((chDateiName != NULL) && (lpDevice != NULL))
    	{
    		this->Lade_Datei(chDateiName, nLOD, lpDevice);
    	};
    };
    
    CAModell::~CAModell(void)
    {
    	if(this->m_pVertexliste) {
    		free(this->m_pVertexliste);
    		this->m_pVertexliste = NULL;
    	}
    	if(this->m_pMaterialliste) {
    		free(this->m_pMaterialliste);
    		this->m_pMaterialliste = NULL;
    	}
    	if(this->m_pTriangles) {
    		free(this->m_pTriangles);
    		this->m_pTriangles = NULL;
    	}
    	if(this->m_pNextLOD) {
    		free(this->m_pNextLOD);
    		this->m_pNextLOD = NULL;
    	}
    	if(this->m_pKind) {
    		free(this->m_pKind);
    		this->m_pKind = NULL;
    	}
    };
    
    CATEXTUR g_aTextur[20];
    DWORD    g_dwAnz_Texturen = 0;
    
    bool CAModell::Lade_Datei(char *chDateiName, int nLOD, LPDIRECT3DDEVICE9 lpDevice)
    {
    	LPDIRECTXFILE           pDXFile;
    	LPDIRECTXFILEENUMOBJECT pEnumObj;
    	LPDIRECTXFILEDATA       pFileData;
    	const GUID              *pGUID;
    	CAModell                *pVater;
    	HRESULT                 xfrval;
    	char                    chDatei[130];
    
    	g_aTextur[0].pTextur = NULL;
    
        //DirectXFile Object erzeugen
    	DirectXFileCreate(&pDXFile);
    
    	//Template registrieren
    	pDXFile->RegisterTemplates((LPVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
    
    	//Alle Lod-Stufen
    	for(int i = 0; i <= nLOD; ++i)
    	{
    		pVater = this;
    		sprintf(chDatei, "%s.x", chDateiName);
    
    		//DirectXFileEnumObject Objekt erzeugen
    		xfrval = pDXFile->CreateEnumObject(chDatei, DXFILELOAD_FROMFILE, &pEnumObj);
    
    		if(xfrval != DXFILE_OK)
    		{
    			pDXFile->Release();
    			return false;
    		}
    
    		//Dateien aus dem Objekt extrahieren
    		while(SUCCEEDED(pEnumObj->GetNextDataObject(&pFileData)))
    		{
    			pFileData->GetType(&pGUID);
    			//Falls es sich um ein Mesh Objekt handelt laden wir es
    			if(*pGUID == TID_D3DRMMesh)
    			{
    				Lade_Mesh(pFileData, pVater, lpDevice);
    			} else ;
    			pFileData->Release();
    		}
    	}
    	pDXFile->Release();
    	return true;
    };
    
    bool CAModell::Lade_Mesh(LPDIRECTXFILEDATA pMeshData, CAModell *pVaterObj, LPDIRECT3DDEVICE9 lpDevice)
    {
    	LPDIRECTXFILEOBJECT pKindObj;
    	LONG lDatenzeiger;
    	DWORD dwTemp;
    	D3DVECTOR *pVertices;
    	DWORD *pdwFaces, dwAnz_Indices = 0;
    
    	//Daten aus dem Template auslesen
    	pMeshData->GetData(NULL, &dwTemp, (LPVOID*)&lDatenzeiger);
    
    	//Wird später das Kind Object des jetzigen Objektes
    	CAModell *pMesh = new CAModell(NULL, 0, NULL);
    
    	//Speichert die Anzahl an Vertices und verschiebt den Datenzeiger
    	//um 4 Byte , also an den Anfang der Vertexliste
    	pMesh->m_dwAnz_Vertices = *((DWORD*)lDatenzeiger);
    	lDatenzeiger += 4;
    
    	pVertices = (D3DVECTOR*)lDatenzeiger;
    	pMesh->m_pVertexliste = (D3DVERTEX*) malloc (sizeof(D3DVERTEX) * pMesh->m_dwAnz_Vertices);
    	if(!pMesh->m_pVertexliste)
    		return false;
    	ZeroMemory(pMesh->m_pVertexliste, sizeof(D3DVERTEX) * pMesh->m_dwAnz_Vertices);
    
    	//Alle Vertices durchgehen und sie in dem Objekt speichern
    	for(DWORD i = 0; i < pMesh->m_dwAnz_Vertices; ++i)
    	{
    		pMesh->m_pVertexliste[i].vPosition = caVector3(pVertices[i].x, pVertices[i].y, pVertices[i].z);
    	}
    
    	lDatenzeiger += sizeof(D3DVECTOR) * pMesh->m_dwAnz_Vertices;
    
    	//Anzahl Faces speichern und Zeíger auf die Stelle vershcieben, 
    	//wo die eigentlichen Face Datem beginnen
    	DWORD dwTemp_AnzFaces = *((DWORD*)lDatenzeiger);
    	lDatenzeiger += 4;
    
    	pdwFaces = (DWORD*)lDatenzeiger;
    
    	//Alle Faces durchlaufen und die Anzahl an Indices feststellen
    	while(dwTemp_AnzFaces-- < 0)
    	{
    		pMesh->m_dwAnz_Indices += (*pdwFaces - 2)*3;
    		pdwFaces += *pdwFaces + 1;
    	};
    
    	pMesh->m_pTriangles = (CATRIANGLE*) malloc (sizeof(CATRIANGLE) * (pMesh->m_dwAnz_Indices/3));
    
    	if(!pMesh->m_pTriangles)
    		return false;
    
    	ZeroMemory(pMesh->m_pTriangles, sizeof(CATRIANGLE) * (pMesh->m_dwAnz_Indices/3));
    
    	//Zeiger wieder zurück auf den Anfang der Faceliste setzen
    	pdwFaces = (DWORD*)lDatenzeiger;
    
    	while(SUCCEEDED(pMeshData->GetNextObject(&pKindObj)))
    	{
    		LPDIRECTXFILEDATA pKindDaten;
    
    		//Handelt es sich um ein DirectX File Objekt?
    		if(SUCCEEDED(pKindObj->QueryInterface(IID_IDirectXFileData, (LPVOID*)&pKindDaten)))
    		{
    
    			const GUID *pGUID;
    	        LONG lDaten;
    			DWORD dwTemp;
    
    			//Um welchen Typ handelt es sich
    			pKindDaten->GetType(&pGUID);
    
    			//Daten aus diesem Objekt extrahieren
    			pKindDaten->GetData(NULL, &dwTemp, (LPVOID*)&lDaten);
    
    			if(*pGUID == TID_D3DRMMeshMaterialList) {
    
    				pMesh->m_dwAnz_Materials = *((DWORD*)lDaten);
    				lDaten += 4;
    				DWORD dwAnz_MatFaces = *((DWORD*)lDaten);
    				lDaten += 4;
    
    				//Startadresse für Material-Face Liste
    				DWORD *pdwMat_Faces = (DWORD*)lDaten;
    
    				//Speicher für Materialliste reservieren
    				pMesh->m_pMaterialliste = (CAMATERIAL*) malloc (sizeof(CAMATERIAL) * pMesh->m_dwAnz_Materials);
    
    				if(!pMesh->m_dwAnz_Materials)
    					return false;
    				//Speicher leeren
    				ZeroMemory(pMesh->m_pMaterialliste, sizeof(CAMATERIAL) * pMesh->m_dwAnz_Materials);
    
    				//Startadresse der Triangle Struct im CAModell Objekt
    				CATRIANGLE *pwTriangle = pMesh->m_pTriangles;
    
    				//Durchlaufe alle Faces
    				for(DWORD cdwFaces = 0; cdwFaces < dwAnz_MatFaces; cdwFaces++)
    				{
    					CATRIANGLE triTriangle;
    					DWORD dwMat = pdwMat_Faces[cdwFaces];
    					WORD wV1, wV2, wV3;
    					DWORD dwVerts_im_Face = *pdwFaces++;
    
    					//Alle Vertices des Faces durchlaufen
    					for(DWORD dwi = 0; dwi < dwVerts_im_Face; dwi++)
    					{
    						if(dwi == 0)
    							wV1 = (WORD) (*pdwFaces++);
    						else if(dwi == 1)
    							wV2 = (WORD) (*pdwFaces++);
    						else {
    							wV3 = (WORD) (*pdwFaces++);
    							pMesh->m_pMaterialliste[dwMat].dwAnz_Indices += 3;
    							triTriangle.wIndices[0] = wV1;
    							triTriangle.wIndices[1] = wV2;
    							triTriangle.wIndices[2] = wV3;
    							*pwTriangle++ = triTriangle;
    							wV2 = wV3;
    						}
    					}
    				}	
    
    				LPDIRECTXFILEOBJECT pMaterial_Obj;
    				DWORD dwAkt_Material;
    
    				while(SUCCEEDED(pKindDaten->GetNextObject(&pMaterial_Obj)))
    				{
    					LPDIRECTXFILEDATA pMatDaten;
    				    LPDIRECTXFILEDATAREFERENCE pMatDatenRef;
    				    HRESULT xfrval; 
    
    				    xfrval = pMaterial_Obj->QueryInterface(IID_IDirectXFileData, (LPVOID*) &pMatDaten);
    
    				    if(FAILED(xfrval))
    					{
    					    xfrval = pMaterial_Obj->QueryInterface(IID_IDirectXFileDataReference, (LPVOID*) &pMatDatenRef);
    					    if(SUCCEEDED(xfrval))
    					    pMatDatenRef->Resolve(&pMatDaten);
    					}
    
    				    if(SUCCEEDED(xfrval))
    					{
    					    const GUID *pGUID;
    
    					    pMatDaten->GetType(&pGUID);
    
    					    if(*pGUID == TID_D3DRMMaterial)
    						{
    						    Lade_Material(lpDevice, pMesh, pMatDaten, dwAkt_Material);
    						    dwAkt_Material++;
    						}
    					    pMatDaten->Release();
    					    if(pMatDatenRef)
    						    pMatDatenRef->Release();
    					}
    				}
    			}
    
    			else if(*pGUID == TID_D3DRMMeshTextureCoords)
    			{
    				DWORD dwAnz_TextureCoords = *((DWORD*)lDaten);
    				lDaten += 4;
    				float *pfKoordinaten = (float*) lDaten;
    
    				//Durchlaufe alle Koordinaten und speichere sie
    				for(DWORD dwi = 0; dwi < dwAnz_TextureCoords; ++dwi)
    				{
    					pMesh->m_pVertexliste[dwi].vTexture = caVector2(pfKoordinaten[2 * dwi], pfKoordinaten[2 * dwi +1]);
    				}
    			}
    			else ;
    			pKindDaten->Release();
    		}
    		pKindObj->Release();
    	}
    	pMesh->m_blnMesh = true;
    	pMesh->Erzeuge_Normalvektoren();
    
    	pVaterObj->Neues_Kind(pMesh);
    	return true;
    };
    
    void CAModell::Neues_Kind(CAModell *pKind)
    {
    	if(this->m_pKind != NULL)
    	{
    		this->m_pKind->Neues_Kind(pKind);
    	} else {
    		this->m_pKind = pKind;
    	}
    };
    
    void CAModell::Lade_Material(LPDIRECT3DDEVICE9 lpDevice, CAModell *pMesh, LPDIRECTXFILEDATA pMaterialDaten, DWORD dwMaterial_Index)
    {
    	LONG lDaten;
    	DWORD dwTemp;
    	D3DMATERIAL9 mat;
    
    	pMaterialDaten->GetData(NULL, &dwTemp, (LPVOID*)&lDaten);
    
    	ZeroMemory(&mat, sizeof(D3DMATERIAL9));
    	memcpy(&mat.Diffuse, (LPVOID) (lDaten), sizeof(float) * 4);
    	memcpy(&mat.Ambient, (LPVOID) (lDaten), sizeof(float) * 4);
    	memcpy(&mat.Power, (LPVOID) (lDaten + 16), sizeof(float));
    	memcpy(&mat.Specular, (LPVOID) (lDaten + 20), sizeof(float) * 3);
    	memcpy(&mat.Emissive, (LPVOID) (lDaten + 32), sizeof(float) * 3);
    
    	int nFlag = 0;
    
    	LPDIRECTXFILEOBJECT pKind_Obj;
    
    	if(SUCCEEDED(pMaterialDaten->GetNextObject(&pKind_Obj)))
    	{
    		LPDIRECTXFILEDATA pTexturDaten;
    
    		if(SUCCEEDED(pKind_Obj->QueryInterface(IID_IDirectXFileData, (LPVOID*) &pTexturDaten)))
    		{
    			const GUID *pGUID;
    
    			pTexturDaten->GetType(&pGUID);
    
    			if(*pGUID == TID_D3DRMTextureFilename)
    			{
    				static char **ppchName;
    				nFlag = 1;
    				BOOL blnTextur = false;
    
    				pTexturDaten->GetData(NULL, &dwTemp, (LPVOID*)&lDaten);
    
    				for(DWORD dwi = 0; dwi < g_dwAnz_Texturen; dwi++)
    				{
    					if(!lstrcmpi(&g_aTextur[dwi].chTexturName[0], *ppchName))
    					{
    						blnTextur = true;
    						pMesh->m_pMaterialliste[dwMaterial_Index].nTextureIndex = dwi;
    					}
    				}
    
    				if(blnTextur == false)
    				{
    					if(g_dwAnz_Texturen >= 20)
    						;
    					else {
    						g_dwAnz_Texturen++;
    
    							pMesh->m_pMaterialliste[dwMaterial_Index].nTextureIndex = g_dwAnz_Texturen;
    
    						g_aTextur[g_dwAnz_Texturen].pTextur = Load_Texture(*ppchName, lpDevice);
    
    						lstrcpyn(&g_aTextur[g_dwAnz_Texturen].chTexturName[0], *ppchName, 128);
    					}
    				}
    			}
    			pTexturDaten->Release();
    		}
    	}
    	if(nFlag == 0)
    		pMesh->m_pMaterialliste[dwMaterial_Index].nTextureIndex = 0;
    };
    
    LPDIRECT3DTEXTURE9 CAModell::Load_Texture(char *ppChTexturName, LPDIRECT3DDEVICE9)
    {
    	static LPDIRECT3DTEXTURE9 text;
    	return text;
    };
    
    void CAModell::Erzeuge_Normalvektoren(void)
    {
    	DWORD dwAnz_Indices;
    	caVector3 *pvNormals = (caVector3*) malloc (sizeof(caVector3) * this->m_dwAnz_Vertices);
    
    	if(!pvNormals)
    		return;
    	ZeroMemory(pvNormals, sizeof(D3DVECTOR) * this->m_dwAnz_Vertices);
    
    	for(DWORD dwi = 0; dwi < this->m_dwAnz_Materials; dwi++)
    		dwAnz_Indices = this->m_pMaterialliste[dwi].dwAnz_Indices;
    
    	for(dwi = 0; dwi < (dwAnz_Indices / 3); dwi++)
    	{
    		WORD wP1 = this->m_pTriangles[dwi].wIndices[0],
    		     wP2 = this->m_pTriangles[dwi].wIndices[1],
    		     wP3 = this->m_pTriangles[dwi].wIndices[2];
    
    	    caVector3 vV1, vV2, vV3;
    
    	    vV1.x = this->m_pVertexliste[wP1].vPosition.x;
    		vV1.y = this->m_pVertexliste[wP1].vPosition.y;
    		vV1.z = this->m_pVertexliste[wP1].vPosition.z;
    	    vV2.x = this->m_pVertexliste[wP2].vPosition.x;
    		vV2.y = this->m_pVertexliste[wP2].vPosition.y;
    		vV2.z = this->m_pVertexliste[wP2].vPosition.z;
    	    vV3.x = this->m_pVertexliste[wP3].vPosition.x;
    		vV3.y = this->m_pVertexliste[wP3].vPosition.y;
    		vV3.z = this->m_pVertexliste[wP3].vPosition.z;
    
    		caVector3 vD1 = vV2 - vV1;
    		caVector3 vD2 = vV3 - vV2;
    		caVector3 vK  = vK.caVector3Cross(vD1, vD2);
    
    		caVector3 vN = vN.caVector3Normalize(vK);
    
    		pvNormals[wP1] = pvNormals[wP1] + vN;
    		pvNormals[wP2] = pvNormals[wP2] + vN;
    		pvNormals[wP3] = pvNormals[wP3] + vN;
    	}
    	for(dwi = 0; dwi < this->m_dwAnz_Vertices; ++dwi)
    	{
    		pvNormals[dwi] = pvNormals[dwi].caVector3Normalize(pvNormals[dwi]);
    
    		this->m_pVertexliste[dwi].vNormal = pvNormals[dwi];
    	}
    	delete pvNormals;
    };
    
    void CAModell::Render(LPDIRECT3DDEVICE9 lpDevice, float n)
    {
    	float f = 0;
    	for(DWORD i = 0; i < (this->m_dwAnz_Indices/3); ++i)
    	{
    		WORD *pwIndices = this->m_pTriangles[i].wIndices;
    		DWORD dwMat = this->m_pTriangles[i].dwMaterial;
    		D3DMATERIAL9 *pMat = &this->m_pMaterialliste[dwMat].mtrMaterial;
    
    		CATEXTUR *pTextur = &g_aTextur[this->m_pMaterialliste[dwMat].nTextureIndex];
    
    		LPDIRECT3DTEXTURE9 *ppTextur;
    
    		ppTextur = &pTextur->pTextur;
    
    		lpDevice->SetMaterial(pMat);
    		lpDevice->SetFVF(D3DFVF_XYZ |D3DFVF_DIFFUSE);
    
    		lpDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, this->m_dwAnz_Vertices, 1, pwIndices, D3DFMT_INDEX16, this->m_pVertexliste, sizeof(D3DVERTEX));
    	}
    	if(this->m_pKind != NULL)
    		this->m_pKind->Render(lpDevice, f);
    }
    

    Die Daten müssten eigentlich alle richtig zwischen gespeichert sein!Der Fehler muss irgendwo beim Renderer liegen(Letzte Methode im Quelltext)!



  • Sagen denn die debug runtimes was dazu? Den Source les ich mir nämlich sicher nicht durch.



  • Die einzige Methode, die du dir angucken musst ist die Render Methode(ganz unten)!Villeicht habe ich da irgendwas falsch gemacht!



  • Kann mir denn keiner helfen?



  • na das nenne ich mal hardcore 😃

    2 Fragen und antworten:
    1. Wieso kein D3DX? Da gibts funktionen die sowas viel einfacher machen im DX SDK gibts sampels dazu
    2. Der code sieht mir stark nach Zerbst aus, also die laderoutine! Geh mal auf die Buchseite von ihm und vergleich da mal den code aus dem listening!



  • Hi!
    Aber die Laderoutinen von der D3DX Bibliothek sind doch nih´cht besonders gut geeignet, um später einen AA-OBB Baum daraus zu erstellen, um genaue Kollisionsabfragen oder genaues Culling zu ermöglichen, da man dort keinen Zugriff auf die einzelen Triangles hat,oder?

    Habe das Buch von Zerbie gelesen, deshalb erinnert die Methode auch etwas an ihn 😃 !



  • Wie lädst du deine Modelle denn?


Anmelden zum Antworten