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?