X-File Loader



  • Hi,

    ich bin gerade dabei, den X-File-Loader aus dem zweiten Band von Stefan Zerbst zu implementieren, allerdings mit ein paar Änderungen. Unter anderem wollte ich konsequent std::string verwenden, anstatt char-Pointern. Dabei stoß ich jetzt aber auf ein Problem.

    Hier erstmal der Ausschnitt aus dem Buch:

    void XXXModell::Lade_Material(LPDIRECT3DDEVICE8 lpDevice, XXXModell *pMesh,
                                  LPDIRECTXFILEDATA pMaterial_Daten,
                                  DWORD dwMaterial_Index) {
       LONG   lDaten;
       DWORD  dwTemp;
    
       // ... alle möglichen Initialisierungen, die ich kürze ...
    
       pMaterial_Daten->GetData(NULL, &dwTemp, (LPVOID*)&lDaten);
       LPDIRECTXFILEOBJECT pKind_Obj;
       if (SUCCEEDED(pMaterial_Daten->GetNextObject(&pKind_Obj))) {
          LPDIRECTXFILEDATA pTextur_Daten;
          if (SUCCEEDED(pKind_Obj->QueryInterface(IID_IDirectXFileData,
                                                  (LPVOID*)&pTextur_Daten))) {
             const GUID *pGUID;
             pTextur_Daten->GetType(&pGUID);   
             if (*pGUID == TID_D3DRMTextureFileName) {
                // ### HIER IST DER KRITISCHE TEIL ###
                char **ppchName;
                pTextur_Daten->GetData(NULL, &dwTemp, (LPVOID*)&ppchName);
                // ... und so weiter ...
              }
           }
        }   
    }
    

    ich wollte das so machen (nur den kritischen Teil):

    string strName="";
    pTextur_Daten->GetData(NULL, &dwTemp, (LPVOID*)strName.begin());
    

    allerdings steht jetzt nie was gescheites in strName drin. Ich hab mir schon gedacht, dass ich vielleicht erst den String auf die richtige Größe bringen muss oder so. Aber wie macht man so was??? Gibt's da ne Möglichkeit oder sollte ich besser in solchen Situationen wieder char-Pointer benutzen???

    Danke schon mal im Voraus, smasher1985



  • änder die Methode GetData das sie ein std::string bekommt



  • @<$>: Das geht ja wohl schlecht, schließlich ist es eine Methode der Klasse LPDIRECTXFILEDATA, die von DirectX bereitgestellt wird... 😕



  • Er meint wohl, dass Du Dir eine Kapselungsfunktion schreiben sollst, die die Schnittstelle als zusätzlichen Parameter erwartet, und die dann GetData aufruft und den String in std::string umwandelt.



  • hmmhh...das ging mir ein bisschen zu schnell 😉

    Kann das mal jemand noch ein bisschen genauer erklären? wär echt super 😃



  • sorry dachte das wäre was von dir. dann kannst du da keinen std::string benutzen



  • OK, ich geh jetzt mal davon aus, dass es keine Möglichkeit gibt, hier direkt einen String zu benutzen (@TomasRiker: ich lass mich gerne eines besseren belehren :)). Kann ich dann wenigstens einen **char benutzen und den dann in std::string konvertieren. Ich brauch das nämlich als std::string, weil meine ganzen Textur-Ladefunktionen damit arbeiten.
    Das mit der Konvertierung hat aber irgendwie auch nicht rictig funktioniert...vielleicht bin ich auch einfach nur zu blöd 😉

    Also, hat jemand noch ein paar Anregungen für mich??? 🙄



  • Original erstellt von smasher1985:
    **hmmhh...das ging mir ein bisschen zu schnell 😉

    Kann das mal jemand noch ein bisschen genauer erklären? wär echt super :D**

    So in der Art:

    std::string GetDataKapselung(LPDIRECTXFILEDATA pSchnittstelle,
                                 Erster Parameter von IDirectXFileData::GetData,
                                 Zweiter Parameter von IDirectXFileData::GetData,
                                 Dritter Parameter von IDirectXFileData::GetData)
    {
        // Jetzt rufst Du pSchnittstelle->GetData mit den drei angegebenen
        // Parametern auf, und wandelst den char*-String irgendwie in
        // std::string um, den Du dann zurücklieferst.
    }
    


  • @TomasRiker: Danke, so weit hab ich's verstanden

    Aber jetzt noch eine blöde Frage: wie funktioniert die Konvertierung von char** in std::string?

    Und wie sieht das hier

    char **ppchName;
       pTexture_Daten->GetData(NULL, &dwTemp, (LPVOID*)&ppchName);
    

    aus mit der Speicherallokierung für den char*-Pointer? Macht das GetData automatisch auf die richtige Größe?



  • Ich würde den ganzen Zerbst Code erstmal kicken, X-Files und ihre Materialien laden sollte viel einfacher gehen. Schau z.b. in die DXSDK Samples:

    // Load the mesh from the specified file
        hr = D3DXLoadMeshFromX( strMesh, D3DXMESH_SYSTEMMEM, m_pd3dDevice, 
                                ppAdjacencyBuffer, &pD3DXMtrlBuffer, 
                                &m_dwNumMaterials, &pMeshSysMem );
        if( FAILED(hr) )
            goto End;
    
        // remember if the mesh is 32 or 16 bit, to be added in on the clones
        dw32Bit = pMeshSysMem->GetOptions() & D3DXMESH_32BIT;
    
        // Get the array of materials out of the returned buffer, and allocate a texture array
        d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
        m_pMeshMaterials = new D3DMATERIAL8[m_dwNumMaterials];
        m_pMeshTextures  = new LPDIRECT3DTEXTURE8[m_dwNumMaterials];
    
        for( i=0; i<m_dwNumMaterials; i++ )
        {
            m_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
            m_pMeshMaterials[i].Ambient = m_pMeshMaterials[i].Diffuse;
            m_pMeshTextures[i]  = NULL;
    
            // Get a path to the texture
            TCHAR strPath[512];
            if (d3dxMaterials[i].pTextureFilename != NULL)
            {
                // Load the texture
                D3DXCreateTextureFromFile( m_pd3dDevice, d3dxMaterials[i].pTextureFilename , &m_pMeshTextures[i] );
            }
        }
    

    Ich hab das auch schon mal in eine Klasse gepackt, hat gut funktioniert. Diese komplizierten Aktionen sind eigentlich nur nötig, wenn du animierte Modells mit Bones u.ä. brauchst. Hab aber schon öft gehört, das man dann besser gar keine X-Files nimmt (allerdings noch nie probiert!).

    Zur Frage, wie man aus einem char* einen std::string macht:

    char pcOldBadAndUglyCharArray[]= "some text";
    std::string strNewString( pcOldBadAndUglyCharArray );



  • Und wenn Du Fragen zu Zerbies Code hast dann stell sie in seinem Forum auf http://www.zfx.info !


Anmelden zum Antworten