Seite 1 von 1
Assimp Parser für DirectX 9
Verfasst: 06.08.2010, 19:28
von PatrickEgli
Hi
Kann mir jemand sagen wie ich einen Assimp Paser für DirectX 9 programmieren kann? Ich habe im Internet nichts weiterhelfendes gefunden.
Kann mir jemand ein gutes Tutorial oder ein Beispielcode geben?
LG Patrick
Re: Assimp Parser für DirectX 9
Verfasst: 06.08.2010, 20:11
von Aramis
Hallo und herzlich willkommen im Forum :-)
Du meinst vermutlich, wie du die von Assimp angelieferten Daten via Direct3D9 auf den Bildschirm bringen kannst?
Ein Tutorial dazu ist mir nicht direkt bekannt. Beispielcode existiert mit dem Quellcode des AssimpViewers, wobei ich den heute nicht mehr so wirklich als Inspirationsquelle empfehlen kann.
Ich wuerde dir raten, das ganze Stueck fuer Stueck anzusetzen. Guck' als erstes Mal dass du ein Testmodell via Assimp importiert kriegst - dafuer hat es in der Assimp-Doku Beispielcode. Dann wuerde ich als erstes anfangen alle Meshes in DX9-Vertex bzw. -Indexbuffer zu verpacken und diese mal testweise zu rendern (aiMesh::mFaces wird der Indexbuffer, aiMesh::mVertices sind die Vertexpositionen fuer den Vertexbuffer, die restlichen Datenstreams musst du dir aus anderen Arrays in aiMesh zusammensuchen, fuer erste Tests sind sie aber nicht erforderlich).
Damit komplexe Modelle korrekt dargestellt werden, ist etwas mehr Arbeit notwendig (Materialien, Szenengraph) … aber guck erstmal dass du es soweit hast. Bei irgendwelchen Problemen einfach melden :-)
Re: Assimp Parser für DirectX 9
Verfasst: 08.08.2010, 13:11
von PatrickEgli
Ich habe nun ein Objekt auf Blender modelliert und es auf AssimpViewer geladen mit OpenAsset.
Im Assimp Manual habe ich das Unterkapitel Usage gefunden. Da wird gezeigt wie man ein File laden kann, das habe ich nun mal in mein Projekt hinzugefügt. Doch ich weiss nun nicht, wie ich das Mesh erzeugen kann durch diese Daten von aiMesh::Faces und aiMesh::Vertices.
Ich habe keine Ahnung, wie ich das programmieren soll.
Hast du vielleicht noch ein Beispielcode?
LG Patrick
Re: Assimp Parser für DirectX 9
Verfasst: 09.08.2010, 09:07
von Schrompf
Hast Du schonmal ein 3D-Modell dargestellt? Jetzt nicht aus ner Datei oder so, sondern manuell? Z.B. ein Quadrat, eine HeightMap, ein Zylinder... irgendsowas, was man direkt im Code erstellen kann? Es klingt für mich nämlich sehr danach, dass Du komplett neu bist in der 3D-Programmierung. Es müsste in etwa so aussehen:
Code: Alles auswählen
// unsere Vertex-Struktur. Bewusst schlicht gehalten
struct Vertex
{
float posx, posy, posz; // Position
float normx, normy, normz; // Normale
float tx, ty; // Texturkoordinate
};
// Stellt einen Mesh dar - ebenso schlicht gehalten
struct Mesh
{
IDirect3D9VertexBuffer* vertizes;
IDirect3D9IndexBuffer* indizes;
Mesh() { vertizes = NULL; indizes = NULL; }
};
/// Erstellt einen Mesh aus dem gegebenen Assimp-Mesh.
Mesh ErstelleMeshAusAssimp( const aiMesh* quellMesh)
{
Mesh zielMesh;
// VertexBuffer erzeugen. Google die exakten Funktionsaufrufe bitte selbst
zielMesh.vertizes = ErzeugeVertexBuffer( /* Größe in Bytes */ quellMesh->mNumVertices * sizeof( Vertex));
Vertex* vertex = (Vertex *) zielMesh.vertizes->Lock();
for( size_t a = 0; a < quellMesh->mNumVertices; ++a)
{
vertex->posx = quellMesh->mVertices[a].x;
vertex->posy = quellMesh->mVertices[a].y;
vertex->posz = quellMesh->mVertices[a].z;
// Normalen nur, wenn der geladene Mesh sie hat. Assimp kann Dir welche erstellen, wenn Du sie immer brauchst
if( quellMesh->hasNormals())
{
vertex->normx = quellMesh->mVertices[a].x;
vertex->normy = quellMesh->mVertices[a].y;
vertex->normz = quellMesh->mVertices[a].z;
}
// auch Texturkoordinaten sind nicht immer gegeben
if( quellMesh->hasTextureCoords( 0))
{
vertex->tx = quellMesh->mTextureCoords[0][a].x;
vertex->ty = quellMesh->mTextureCoords[0][a].y;
}
vertex++;
}
zielMesh.vertizes->Unlock();
// IndexBuffer erzeugen. Wir verlassen uns hier drauf, dass Assimp trianguliert hat und alle Nicht-Dreiecke rausgeworfen hat - dafür gibt's auch Importflags
zielMesh.indices = ErzeugeIndexBuffer( quellMesh->mNumFaces * 3 * sizeof( unsigned short));
unsigned short* index = zielMesh.indices->Lock();
for( size_t a = 0; a < quellMesh->mNumFaces; ++a)
{
*index++ = quellMesh->mFaces[a].mIndices[0];
*index++ = quellMesh->mFaces[a].mIndices[1];
*index++ = quellMesh->mFaces[a].mIndices[2];
}
zielMesh.indices->Unlock();
// fertig befüllte Buffer an den Aufrufer zurückgeben
return zielMesh;
}
Die exakten Funktionsnamen habe ich jetzt nicht im Kopf, aber die kannst Du ja nachlesen. Wie Du siehst, ist es wirklich nicht mehr als ein Speicher-Umstapeln.
Re: Assimp Parser für DirectX 9
Verfasst: 11.08.2010, 19:20
von PatrickEgli
Hi
Ich habe schon ein paar Würfel, Vierecke und Würfel gerendert, mit dem VertexBuffer und dem IndexBuffer. Ich dachte das sei viel komplizierter, um eine Assimpdatei zu lesen.
Was mir noch nicht so richtig einleuchtet was ich jetzt noch alles brauche um eine Assimpdatei zu lesen und zu rendern. Ich habe jetzt mal den Vertex- und IndexBuffer. Jetzt brauche ich noch eine Renderfunktion. Und dann brauche in noch den Code den ich vom AssimpManual unter dem Unterverzeichnis Usage habe. Was brauche ich noch?
Kann mir da jemand helfen?
Re: Assimp Parser für DirectX 9
Verfasst: 11.08.2010, 20:10
von Aramis
Naja, du musst eben die Daten von der aiScene in Vertex- und Indexbuffer packen. Im Prinzip hat Thomas dafuer ja bereits ziemlich vollstaendigen Code gepostet.
Schlussendlich brauchst du noch einen einfachen Shader (dazu bitte Google fragen) mit dem du das Material deiner Objekte annaeherst. Fuer's erste reicht ein einfacher Einfaerbe-Shader, spaeter wird es noetig sein die von Assimp angelieferten Materialeigenschaften (aiMaterial) zur Parametrisierung deiner Shader zu nutzen.
Dann duerften die Modelle in etwa so aussehen wie sie sollen. Dein Code hat dann allerdings eine Menge Optimierungspotential, aber darum wuerde ich mir aktuell keine Sorgen machen.
Re: Assimp Parser für DirectX 9
Verfasst: 17.09.2010, 12:13
von SunCross
Ist die Index-/Vertexbuffer-Methode prinzipiell schneller oder langsamer als D3DXMESH?
Oder ist das einfach nur ne andere Verpackung?
Re: Assimp Parser für DirectX 9
Verfasst: 17.09.2010, 13:54
von Schrompf
D3DXMesh ist nur eine Helferklasse, die intern Vertex- und IndexBuffer benutzt. Insoweit müsste also exakt die selbe Performance zu erwarten sein. Bzw. ein minimales Bisschen weniger, weil die Befehle an die Grafikkarte durch zwei drei Funktionen mehr durch müssen. Das dürfte nicht messbar sein.
Re: Assimp Parser für DirectX 9
Verfasst: 18.09.2010, 10:53
von SunCross
Cool, dann kann ich meine Mesh-Klasse so umbauen, dass D3DXMESH weggelassen wird und ich alle Models ab jetzt mit Assimp lade. Wollt ich eh machen, man ist als einfacher *.x - Model-Benutzer so einsam.
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 18:27
von PatrickEgli
So ich habe nun versucht ein Teil eines Assimp Parsers zu programmieren. Doch er hat noch ein paar Fehler.
Der VertexBuffer hat ein Rückgabetyp von HRESULT und kann nicht in die vertices geladen werden. Das gleiche auch beim IndexBuffer. Dann findet es den Assimp::Importer nicht, warum?
Hier ist der Code:
Code: Alles auswählen
#include <assimp.h> // C++ importer interface
#include <aiScene.h> // Output data structure
#include <aiPostProcess.h> // Post processing flags
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
const DWORD FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
// Vertex Struktur
struct Vertex
{
float posx, posy, posz; // Position
float normx, normy, normz; // Normal
float tx, ty; // Texturekoordinaten
};
// Struktur für einen Mesh
struct Mesh
{
IDirect3DVertexBuffer9* vertices;
IDirect3DIndexBuffer9* indizes;
Mesh() {vertices = NULL; indizes = NULL;}
};
Mesh CreateMeshFromAssimp(const aiMesh * mesh)
{
Mesh MyMesh;
// Create a vertexbuffer
MyMesh.vertices = d3ddev->CreateVertexBuffer(mesh->mNumVertices * sizeof(Vertex),
D3DUSAGE_WRITEONLY,
FVF,
D3DPOOL_MANAGED,
NULL,
NULL);
VOID * pVoid;
Vertex * vertex = (Vertex *)MyMesh.vertices->Lock(0, 0, (void**)&pVoid, 0);
for(size_t a = 0; a < mesh->mNumVertices; ++a)
{
vertex->posx = mesh->mVertices[a].x;
vertex->posy = mesh->mVertices[a].y;
vertex->posz = mesh->mVertices[a].z;
if(mesh->HasNormals())
{
vertex->normx = mesh->mVertices[a].x;
vertex->normy = mesh->mVertices[a].y;
vertex->normz = mesh->mVertices[a].z;
}
if(mesh->HasTextureCoords(0))
{
vertex->tx = mesh->mTextureCoords[0][a].x;
vertex->ty = mesh->mTextureCoords[0][a].y;
}
vertex++;
}
MyMesh.vertices->Unlock();
MyMesh.indizes = d3ddev->CreateIndexBuffer(mesh->mNumFaces * sizeof(unsigned short),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
NULL,
NULL);
VOID * pIndexVoid;
unsigned short * index = MyMesh.indizes->Lock(0, 0, (void**)&pIndexVoid, 0);
for(size_t a = 0; a < mesh->mNumFaces; ++a)
{
*index++ = mesh->mFaces[a].mIndices[0];
*index++ = mesh->mFaces[a].mIndices[1];
*index++ = mesh->mFaces[a].mIndices[2];
}
MyMesh.indizes->Unlock();
return MyMesh;
}
bool DoTheImportThing( const std::string& pFile)
{
// Create an instance of the Importer class
Assimp::Importer importer;
const aiScene * scene = importer.ReadFile(pFile,
aiProcess_CalcTangentSpace,
aiProcess_Triangulate,
aiProcess_JoinIdenticalVertices,
aiProcess_SortByPType);
// If the import failed, report it
if(!scene)
{
MessageBox(NULL, (LPCSTR)importer.GetErrorString(), TEXT("There was an error"),
MB_OK | MB_ICONEXCLAMATION);
return false;
}
// Now we can access the file's contents.
DoTheSceneProcessing(scene);
// We're done. Everything will be cleaned up by the importer destructor
return true;
}
Die Fehleranzeige:
Code: Alles auswählen
1>------ Erstellen gestartet: Projekt: AsssimpLoader, Konfiguration: Debug Win32 ------
1>Kompilieren...
1>main.cpp
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(43) : error C2440: '=': 'HRESULT' kann nicht in 'IDirect3DVertexBuffer9 *' konvertiert werden
1> Die Konvertierung eines ganzzahligen Typs in einen Zeigertyp erfordert ein reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(77) : error C2440: '=': 'HRESULT' kann nicht in 'IDirect3DIndexBuffer9 *' konvertiert werden
1> Die Konvertierung eines ganzzahligen Typs in einen Zeigertyp erfordert ein reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(81) : error C2440: 'Initialisierung': 'HRESULT' kann nicht in 'unsigned short *' konvertiert werden
1> Die Konvertierung eines ganzzahligen Typs in einen Zeigertyp erfordert ein reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(96) : error C2039: 'Importer': Ist kein Element von 'Assimp'
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(96) : error C2065: 'Importer': nichtdeklarierter Bezeichner
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(96) : error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'importer'
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(96) : error C2065: 'importer': nichtdeklarierter Bezeichner
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(98) : error C2065: 'importer': nichtdeklarierter Bezeichner
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(98) : error C2228: Links von ".ReadFile" muss sich eine Klasse/Struktur/Union befinden.
1> Typ ist ''unknown-type''
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(107) : error C2065: 'importer': nichtdeklarierter Bezeichner
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(107) : error C2228: Links von ".GetErrorString" muss sich eine Klasse/Struktur/Union befinden.
1> Typ ist ''unknown-type''
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(114) : error C3861: "DoTheSceneProcessing": Bezeichner wurde nicht gefunden.
1>Das Buildprotokoll wurde unter "file://c:\Dokumente und Einstellungen\Patrick\Eigene Dateien\Visual Studio 2008\Projects\AsssimpLoader\AsssimpLoader\Debug\BuildLog.htm" gespeichert.
1>AsssimpLoader - 12 Fehler, 0 Warnung(en)
========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
Kann mir jemand dabei helfen?
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 18:30
von Aramis
Assimp::Importer ist in assimp.hpp, probier mal das anstelle von assimp.h (reines C-interface) einzubinden.
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 18:39
von Krishty
PatrickEgli hat geschrieben:Code: Alles auswählen
MyMesh.vertices = d3ddev->CreateVertexBuffer(mesh->mNumVertices * sizeof(Vertex),
D3DUSAGE_WRITEONLY,
FVF,
D3DPOOL_MANAGED,
NULL,
NULL);
Aua. Wenn du in die Dokumentation von
IDirect3DDevice9::CreateVertexBuffer() schaust, steht dort, dass der Rückgabewert nur angibt, ob die Funktion erfolgreich abschloss oder, falls nicht, welcher Fehler auftrat. Das eigentliche Vertex-Buffer-Objekt wird im
ppVertexBuffer-Parameter gespeichert, wo du fälschlicherweise schlicht
NULL übergibst. Analog ist es mit
IDirect3DDevice9::CreateIndexBuffer().
Gruß, Ky
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 19:01
von PatrickEgli
Ich habe nun ein LPDIRECT3DVERTEXBUFFER9 und ein LPDIRECT3DINDEXBUFFER9 Objekt erstellt und diesen beiden Funktionen übergeben. Trotzdem kommen diese Fehlermeldungen immer noch.
Code: Alles auswählen
LPDIRECT3DVERTEXBUFFER9 vertexbuffer;
LPDIRECT3DINDEXBUFFER9 indexbuffer;
MyMesh.vertices = d3ddev->CreateVertexBuffer(mesh->mNumVertices * sizeof(Vertex),
D3DUSAGE_WRITEONLY,
FVF,
D3DPOOL_MANAGED,
&vertexbuffer,
NULL);
MyMesh.indizes = d3ddev->CreateIndexBuffer(mesh->mNumFaces * sizeof(unsigned short),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&indexbuffer,
NULL);
Kann mir jemand sagen, was ich falsch gemacht habe?
Meine zweite Frage wie kann ich nun diesen Loader funktionstüchtig machen? Was muss noch dazu programmiert werden?
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 19:06
von Krishty
Häääääjj Hank Jounghe, sou hab ich nichd bestellt
Wischou weistn du n HRESULT mit Verpackung deym Vertex-Buffer zu
Und das Bounty auch noch
So machd man das nichd!
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 19:16
von PatrickEgli
Aber ich muss doch einen Vertexbuffer erzeugen, wie soll ich dann einen Vertexbuffer erzeugen?
Code: Alles auswählen
zielMesh.vertizes = ErzeugeVertexBuffer( /* Größe in Bytes */ quellMesh->mNumVertices * sizeof( Vertex));
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 21:55
von Krishty
Die Funktion erzeugt doch den Vertex-Buffer und speichert ihn in dem Zeiger, den du ihr gibst. Du versuchst jedoch, den Status, den die Funktion zurückgibt, deinem Vertex-Buffer zuzuweisen.
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 21:58
von PatrickEgli
Ach so, sry. Kannst du mir dabei helfen wie ich das hinkriege? Benötige ich dafür nicht auch noch die Grösse in Bytes?
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 22:28
von PatrickEgli
Ich habe es nun rausgefunden. Ist jetzt eigentlich ganz klar.
Nun gibt es einen ähnlichen Fehler beim unsigned short * index. auch hier ist die Konventierung von HRESULT in unsigned short fehlerhaft.
Code: Alles auswählen
VOID * pIndexVoid;
unsigned short * index = MyMesh.indizes->Lock(0, 0, (void**)&pIndexVoid, 0); // Hier ist der Fehler
for(size_t a = 0; a < mesh->mNumFaces; ++a)
{
*index++ = mesh->mFaces[a].mIndices[0];
*index++ = mesh->mFaces[a].mIndices[1];
*index++ = mesh->mFaces[a].mIndices[2];
}
MyMesh.indizes->Unlock();
Fehlerausgabe:
Code: Alles auswählen
1>------ Erstellen gestartet: Projekt: AsssimpLoader, Konfiguration: Debug Win32 ------
1>Kompilieren...
1>main.cpp
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(88) : error C2440: 'Initialisierung': 'HRESULT' kann nicht in 'unsigned short *' konvertiert werden
1> Die Konvertierung eines ganzzahligen Typs in einen Zeigertyp erfordert ein reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(103) : error C2039: 'Importer': Ist kein Element von 'Assimp'
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(103) : error C2065: 'Importer': nichtdeklarierter Bezeichner
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(103) : error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'importer'
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(103) : error C2065: 'importer': nichtdeklarierter Bezeichner
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(105) : error C2065: 'importer': nichtdeklarierter Bezeichner
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(105) : error C2228: Links von ".ReadFile" muss sich eine Klasse/Struktur/Union befinden.
1> Typ ist ''unknown-type''
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(114) : error C2065: 'importer': nichtdeklarierter Bezeichner
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(114) : error C2228: Links von ".GetErrorString" muss sich eine Klasse/Struktur/Union befinden.
1> Typ ist ''unknown-type''
1>c:\dokumente und einstellungen\patrick\eigene dateien\visual studio 2008\projects\asssimploader\asssimploader\main.cpp(121) : error C3861: "DoTheSceneProcessing": Bezeichner wurde nicht gefunden.
1>Das Buildprotokoll wurde unter "file://c:\Dokumente und Einstellungen\Patrick\Eigene Dateien\Visual Studio 2008\Projects\AsssimpLoader\AsssimpLoader\Debug\BuildLog.htm" gespeichert.
1>AsssimpLoader - 10 Fehler, 0 Warnung(en)
========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
Was habe ich diesmal falsch gemacht?
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 22:34
von Krishty
RTM – weißt ja jetzt, wie es geht:
http://msdn.microsoft.com/en-us/library/bb205917
Tipp: Du brauchst einen
reinterpret_cast<unsigned short *>(…).
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 22:41
von PatrickEgli
So ich habe es wieder geschaft durch deine tolle Hilfe danke.
Code: Alles auswählen
MyMesh.indizes->Lock(0, 0, (void**)&pIndexVoid, 0);
unsigned short * index = (unsigned short*)pIndexVoid;
Nun, warum ist der Assimp::Importer kein Element von Assimp. Ich habe <assimp.h><aiScene.h> und <aiPostProcess.h> alle eingebunden durch #include und habe beim Linker assimp.lib hinzugefügt.
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 22:45
von Aramis
Hab ich dir oben beantwortet :-)
Re: Assimp Parser für DirectX 9
Verfasst: 15.10.2010, 23:05
von PatrickEgli
Ach so sry. Funktioniert nun.
Doch nun weiss ich nicht mehr wie ich diesen Parser weiter schreiben soll. Wie kann ich alles zusammenhängen und was kommt noch alles hinzu, damit ich ein einfaches Mesh reinladen kann.
Mein Code:
Code: Alles auswählen
#include <assimp.hpp> // C++ importer interface
#include <aiScene.h> // Output data structure
#include <aiPostProcess.h> // Post processing flags
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
const DWORD FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
// Vertex Struktur
struct Vertex
{
float posx, posy, posz; // Position
float normx, normy, normz; // Normal
float tx, ty; // Texturekoordinaten
};
// Struktur für einen Mesh
struct Mesh
{
IDirect3DVertexBuffer9* vertices;
IDirect3DIndexBuffer9* indizes;
Mesh() {vertices = NULL; indizes = NULL;}
};
LPDIRECT3DVERTEXBUFFER9 vertexbuffer;
LPDIRECT3DINDEXBUFFER9 indexbuffer;
Mesh CreateMeshFromAssimp(const aiMesh * mesh)
{
Mesh MyMesh;
d3ddev->CreateVertexBuffer(mesh->mNumVertices * sizeof(Vertex),
D3DUSAGE_WRITEONLY,
FVF,
D3DPOOL_MANAGED,
&vertexbuffer,
NULL);
// Create a vertexbuffer
MyMesh.vertices = vertexbuffer;
VOID * pVoid;
Vertex * vertex = (Vertex *)MyMesh.vertices->Lock(0, 0, (void**)&pVoid, 0);
for(size_t a = 0; a < mesh->mNumVertices; ++a)
{
vertex->posx = mesh->mVertices[a].x;
vertex->posy = mesh->mVertices[a].y;
vertex->posz = mesh->mVertices[a].z;
if(mesh->HasNormals())
{
vertex->normx = mesh->mVertices[a].x;
vertex->normy = mesh->mVertices[a].y;
vertex->normz = mesh->mVertices[a].z;
}
if(mesh->HasTextureCoords(0))
{
vertex->tx = mesh->mTextureCoords[0][a].x;
vertex->ty = mesh->mTextureCoords[0][a].y;
}
vertex++;
}
MyMesh.vertices->Unlock();
d3ddev->CreateIndexBuffer(mesh->mNumFaces * sizeof(unsigned short),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&indexbuffer,
NULL);
MyMesh.indizes = indexbuffer;
VOID * pIndexVoid;
MyMesh.indizes->Lock(0, 0, (void**)&pIndexVoid, 0);
unsigned short * index = (unsigned short*)pIndexVoid;
for(size_t a = 0; a < mesh->mNumFaces; ++a)
{
*index++ = mesh->mFaces[a].mIndices[0];
*index++ = mesh->mFaces[a].mIndices[1];
*index++ = mesh->mFaces[a].mIndices[2];
}
MyMesh.indizes->Unlock();
return MyMesh;
}
bool DoTheImportThing( const std::string& pFile)
{
// Create an instance of the Importer class
Assimp::Importer importer;
const aiScene * scene = importer.ReadFile(pFile,
aiProcess_CalcTangentSpace |
aiProcess_Triangulate |
aiProcess_JoinIdenticalVertices |
aiProcess_SortByPType);
// If the import failed, report it
if(!scene)
{
MessageBox(NULL, (LPCSTR)importer.GetErrorString(), TEXT("There was an error"),
MB_OK | MB_ICONEXCLAMATION);
return false;
}
// We're done. Everything will be cleaned up by the importer destructor
return true;
}
Re: Assimp Parser für DirectX 9
Verfasst: 16.10.2010, 00:28
von SunCross
Mit der Funktion HasMeshes kannst du prüfen, ob die Szene überhaupt Meshes enthält. Danach kannst über das Mesh-Array der Szene auf sie zugreifen.
Das sieht bei mir so aus:
Code: Alles auswählen
if (Scene->HasMeshes () == true)
{
Scene->mMeshes[0]->mNumVertices;
}
Im Beispiel soll dargestellt werden, das man z.B. über mMeshes[0] (0 für das erste Mesh) auf die Daten des Meshes zugreifen kann.
Das Array ist vom Typ aiMesh, d.h. kannst du den gewünschten Mesh an deine "CreateMeshFromAssimp"-Funktion übergeben.
Re: Assimp Parser für DirectX 9
Verfasst: 16.10.2010, 09:29
von PatrickEgli
Ich habe das nun mal in meinem Code programmiert. Ich habe es in der Funktion DoImportThing geschrieben. Ist das so richtig?
Code: Alles auswählen
if(scene->HasMeshes() == true)
{
scene->mMeshes[0]->mNumVertices;
CreateMeshFromAssimp((aiMesh*)scene->mMeshes[0]);
}
Was muss ich sonst noch schreiben, um ein einfache Modell darstellen zu können? Sicherlich muss ich noch einen Render schreiben. Muss ich den mithilfe von SetStreamSource schreiben?
Re: Assimp Parser für DirectX 9
Verfasst: 16.10.2010, 12:08
von Krishty
Hier und
hier – beziehungsweise, falls du alles für Anfänger relevante wissen willst, auch generell alles
hier :)
Re: Assimp Parser für DirectX 9
Verfasst: 17.10.2010, 22:45
von SunCross
Die Zeile mit dem
kannst du dir sparen, damit wollt ich nur verdeutlichen, dass es sich bei dem Array "mMeshes" um aiMeshes handelt und du somit auf Variablen, wie z.B. mNumVertices zugreifen kannst, die nun mal Teil eines aiMeshes sind.