Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

1

29.12.2010, 14:18

Fehler beim Assimp Loader

Hi

Ich habe einen Assimp Loader programmiert. Doch leider hat es noch einen Fehler, denn das Mesh wird nicht angezeigt.

Hier ist der Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
bool CLoader::CreateScene(string & Filename)
{
    Assimp::Importer importer;

    m_pModel = importer.ReadFile( Filename, 
        aiProcess_CalcTangentSpace  |
        aiProcess_Triangulate |
        aiProcess_MakeLeftHanded |
        aiProcess_JoinIdenticalVertices |
        aiProcess_SortByPType |
        aiProcess_CalcTangentSpace |
        aiProcess_JoinIdenticalVertices |
        aiProcess_GenSmoothNormals |
        aiProcess_LimitBoneWeights |
        aiProcess_RemoveRedundantMaterials |
        aiProcess_OptimizeMeshes);

    if(m_pModel->HasMeshes())
    {
        CreateAssimpMesh(m_pModel);
    }

    return true;
}

bool CLoader::CreateAssimpMesh(const aiScene * Scene)
{
    aiMesh ** rawMeshes = Scene->mMeshes;
    aiMaterial ** materials = Scene->mMaterials;

    UINT * meshID;
    UINT * materialID;

    aiNode * sceneroot = Scene->mRootNode;
    aiNode ** children = sceneroot->mChildren;
    aiNode * child;

    Vertex * vertex;
    unsigned int * index;

    UINT i = 0;
    bool rootnode = true;

    do
    {
        if(rootnode)
        {
            child = sceneroot;
            rootnode = false;
        }
        else
        {
            child = children[i];
            ++i;
        }
        if(child->mNumMeshes > 1)
        {
            MessageBoxA(NULL, "Error: a node in the scene graph consist of multiple meshes.\nLoading will continue, but with possible errors!", "Error parsing file!", 
                        MB_ICONHAND | MB_OK);
        }
        if(!(child->mNumMeshes > 0))
        {
            continue;
        }

        meshID = child->mMeshes;

        vertex = new Vertex[rawMeshes[meshID[0]]->mNumVertices];

        for(UINT j = 0; j < rawMeshes[meshID[0]]->mNumVertices; ++j)
        {
            vertex[j].posx = rawMeshes[meshID[0]]->mVertices[j].x;
            vertex[j].posy = rawMeshes[meshID[0]]->mVertices[j].y;
            vertex[j].posz = rawMeshes[meshID[0]]->mVertices[j].z;

            if(rawMeshes[meshID[0]]->HasNormals())
            {
                vertex[j].normalx = rawMeshes[meshID[0]]->mNormals[j].x;
                vertex[j].normaly = rawMeshes[meshID[0]]->mNormals[j].y;
                vertex[j].normalz = rawMeshes[meshID[0]]->mNormals[j].z;
            }

            if(rawMeshes[meshID[0]]->HasTextureCoords(0))
            {
                vertex[j].tu = rawMeshes[meshID[0]]->mTextureCoords[0][j].x;
                vertex[j].tv = rawMeshes[meshID[0]]->mTextureCoords[0][j].y;
            }
        }

        index = new unsigned int[rawMeshes[meshID[0]]->mNumFaces * 3];

        for(UINT j = 0; j < rawMeshes[meshID[0]]->mNumFaces; ++j)
        {
            if(rawMeshes[meshID[0]]->mFaces[j].mNumIndices != 3)
            {
                MessageBoxA(NULL, "Error: not all faces are triangulated!", "Triangulation error", 
                            MB_ICONHAND | MB_OK);
                                                            
                return false;
            }

            index[j*3+0] = rawMeshes[meshID[0]]->mFaces[j].mIndices[0];
            index[j*3+1] = rawMeshes[meshID[0]]->mFaces[j].mIndices[1];
            index[j*3+2] = rawMeshes[meshID[0]]->mFaces[j].mIndices[2];
        }
    } while(i < sceneroot->mNumChildren);

    HRESULT hResult;

    // VerexBuffer erzeugen
    if(FAILED(hResult = g_pD3DDevice->CreateVertexBuffer((rawMeshes[meshID[0]]->mNumVertices * sizeof(Vertex)),
                                                         D3DUSAGE_WRITEONLY,
                                                         VertexFVF,
                                                         D3DPOOL_MANAGED,
                                                         &vertices,
                                                         NULL)))
    {
        MessageBox(NULL, "Fehler beim erzeugen des VertexBuffers vom Mesh", "Fehler aufgetreten",
                   MB_OK | MB_ICONEXCLAMATION);
    }

    VOID * pVoid;

    vertices->Lock(0, 0, (VOID**)&pVoid, 0);
    memcpy(pVoid, vertex, sizeof(Vertex));
    vertices->Unlock();

    // IndexBuffer erzeugen
    if(FAILED(hResult = g_pD3DDevice->CreateIndexBuffer((rawMeshes[meshID[0]]->mNumFaces * 3 * sizeof(unsigned int)),
                                                        D3DUSAGE_WRITEONLY,
                                                        D3DFMT_INDEX32,
                                                        D3DPOOL_MANAGED,
                                                        &indices,
                                                        NULL)))
    {
        MessageBox(NULL, "Fehler beim Erzeugen des IndexBuffers", "Fehler aufgetreten",
                   MB_OK | MB_ICONEXCLAMATION);
    }

    indices->Lock(0, 0, (VOID**)&pVoid, 0);
    memcpy(pVoid, index, sizeof(unsigned int));
    indices->Unlock();

    m_NumVertices = rawMeshes[meshID[0]]->mNumVertices;
    m_NumFaces = rawMeshes[meshID[0]]->mNumFaces;

    return true;
}

bool CLoader::Render()
{
    HRESULT hResult;

    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE);

    g_pD3DDevice->SetFVF(VertexFVF);
    g_pD3DDevice->SetStreamSource(0, vertices, 0, sizeof(Vertex));
    g_pD3DDevice->SetIndices(indices);

    // Rendern des Meshes
    if(FAILED(hResult = g_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
                                                        0,
                                                        0,
                                                        m_NumVertices,
                                                        0,
                                                        m_NumFaces / 3)))
    {
        MessageBox(NULL, "Fehler beim Rendern", "Fehler aufgetreten",
                   MB_OK | MB_ICONEXCLAMATION);

        return false;
    }

    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);

    return true;
}


Der Aufruf der CreateScene-Funktion

C-/C++-Quelltext

1
2
3
string FileName ("Sphere.x");

    m_pLoader->CreateScene(FileName);


Und der Aufruf der Render-Funktion

C-/C++-Quelltext

1
m_pLoader->Render();



Ich habe keinen Fehler nach längerem Suchen gefunden. Kann mir jemand sagen, wo das Problem liegt?

LG Patrick

2

29.12.2010, 15:31

Was ist mit Material, Texturen, ColorOp's usw.? Wird irgendwo was gesetzt?
Wenn du schon das Licht ausmachst? ;)
fka tm

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

3

29.12.2010, 15:36

Das habe ich noch nicht im Loader eingebaut, ich wollte den Loader möglichst einfach halten und danach weiter aufbauen, oder muss ich die Materials hinzufügen, damit das Mesh angezeigt wird?

4

29.12.2010, 16:01

Irgendwas braucht DX ja, um was darzustellen.

Wie schauts mit Transformationen aus?
fka tm

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

5

29.12.2010, 16:05

Ich habe zur Zeit nur eine eigene Transformation gemacht, auf den Punkt (0.0f, 0.0f, 0.0f). Sonst habe ich noch keine Transformationen mit dem Assimploader geschrieben.

Ist der Code sonst in Ordnung, also werden die Vertizen und Indizen richtig übernommen?

6

29.12.2010, 16:13

Zum Code kann ich nicht viel sagen, weil ich mit Assimp noch nichts gemacht habe.
Ich würde mal ein Material erstellen und setzen. Ggf. mal Wireframe-Mode einschalten und das Teil rotieren lassen.
fka tm

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

7

29.12.2010, 16:31

Habe ich nun auch gemacht, leider passiert auch hier nichts, es wird kein Mesh angezeigt.

Materialcode:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
m_pMaterial = new SMaterial*[m_pModel->mNumMaterials];

for(int i = 0; i < Scene->mNumMaterials; i++)
{
m_pMaterial[i] = new SMaterial();

aiColor3D color(0.0f, 0.0f, 0.0f);
Scene->mMaterials[i]->Get(AI_MATKEY_COLOR_DIFFUSE, color);
m_pMaterial[i]->Material.Diffuse = AiToD3DColor(color);

color.r = 0.0f; color.g = 0.0f; color.b = 0.0f;
Scene->mMaterials[i]->Get(AI_MATKEY_COLOR_SPECULAR, color);
m_pMaterial[i]->Material.Specular = AiToD3DColor(color);

color.r = 0.0f; color.g = 0.0f; color.b = 0.0f;
Scene->mMaterials[i]->Get(AI_MATKEY_COLOR_EMISSIVE, color);
m_pMaterial[i]->Material.Emissive = AiToD3DColor(color);

color.r = 0.0f; color.g = 0.0f; color.b = 0.0f;
Scene->mMaterials[i]->Get(AI_MATKEY_COLOR_AMBIENT, color);
m_pMaterial[i]->Material.Ambient = AiToD3DColor(color);

float fPower = 0.0f;
Scene->mMaterials[i]->Get(AI_MATKEY_SHININESS, fPower);
m_pMaterial[i]->Material.Power = fPower;
}

m_MaterialIndex = rawMeshes[meshID[0]]->mMaterialIndex;


Setzen des Materials

C-/C++-Quelltext

1
g_pD3DDevice->SetMaterial(&m_pMaterial[m_MaterialIndex]->Material);


Wiremodus einschalten und das eine Welttransformation

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
g_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);

D3DXMatrixTranslation(&Translation, 0.0f, 0.0f, -20.0f);
    static float fAngle = 0.0f;
    fAngle += 0.03f;
    D3DXMatrixRotationY(&Rotation, fAngle);
    D3DXMATRIX World;
    World = Translation * Rotation;
    g_pD3DDevice->SetTransform(D3DTS_WORLD, &World);


Ich nehme an, dass etwas mit den Vertizen und den Indizen nicht stimmt.

8

29.12.2010, 16:55

Hast du mal probiert, das Modell mit DX-Hausmitteln (LoadMesh...) zu laden?
Dann siehst du definitiv, ob deine Vermutung bezüglich Vertizes und Indizes stimmt. ;)
fka tm

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

9

29.12.2010, 17:26

So, dass habe ich nun auch gemacht, leider wird immer noch kein Mesh angezeigt.

Der Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
m_NumVertices = rawMeshes[meshID[0]]->mNumVertices;
    m_NumFaces = rawMeshes[meshID[0]]->mNumFaces;

    D3DVERTEXELEMENT9 simple_decl[] =
    {
      {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
      {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
      {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
      D3DDECL_END()
    };


    D3DXCreateMesh(m_NumFaces, m_NumVertices, D3DUSAGE_WRITEONLY, simple_decl, g_pD3DDevice, &m_pMesh);

    VOID * pVoid;

    m_pMesh->LockVertexBuffer(0, (VOID**)&pVoid);
    memcpy(pVoid, vertex, sizeof(Vertex));
    m_pMesh->UnlockVertexBuffer();

    m_pMesh->LockIndexBuffer(0, (VOID**)&pVoid);
    memcpy(pVoid, index, sizeof(unsigned int));
    m_pMesh->UnlockIndexBuffer();


Mesh rendern

C-/C++-Quelltext

1
m_pMesh->DrawSubset(0);

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Patrick Egli« (29.12.2010, 17:44)


BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

10

29.12.2010, 18:46

Kann es sein, dass BeginScene() und EndScene() in der Renderfunktion fehlen oder habe ich die übersehen?

Werbeanzeige