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

DJSebi

Frischling

  • »DJSebi« ist der Autor dieses Themas

Beiträge: 19

Wohnort: KÖLN!!!!!

Beruf: Musiker, Informatiker, DJ, Moderator

  • Private Nachricht senden

1

03.11.2008, 17:06

Problem 3D Modelle laden in OpenGL

Mahlzeit zusammen,

sitze seit ein paar tagen daran mit lib3ds 3ds-Dateien zu laden. Das Laden ist ja kein Problem, Material und die Vertices werden auch ausgelesen. Das ganze packe ich dann in einen Vertexbuffer und lasse diesen rendern. Nur das Ergebnis ist nicht das gewünschte Ergebnis. Daher hier ein paar Screenshots und der Source. Danke schon mal für eure Hilfe!

Kompletten Sourcecode: http://scua.de/projects/bowling

Laden der Daten:

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
if( !filename->nodes )
        lib3ds_file_create_nodes_for_meshes( filename );
    lib3ds_file_eval( filename, 0 );

    Lib3dsNode* p;

    for( p = filename->nodes; p; p = p->next )
    {
        if( p->type == LIB3DS_NODE_MESH_INSTANCE )
        {
            Lib3dsMeshInstanceNode* node = (Lib3dsMeshInstanceNode*)p;
            Lib3dsMesh* mesh = lib3ds_file_mesh_for_node( filename, (Lib3dsNode*)node );
            facesCount  = mesh->nvertices;

            float (*verts)[3] = (float(*)[3])malloc( sizeof( float ) * 3 * mesh->nvertices );
            memcpy( verts, mesh->vertices, sizeof( float ) * 3 * mesh->nvertices );
            {
                float   inv_matrix[4][4], M[4][4];
                float   tmp[3];
                int     i;

                lib3ds_matrix_copy( M, node->base.matrix );
                lib3ds_matrix_translate( M, -node->pivot[0], -node->pivot[1], -node->pivot[2] );
                lib3ds_matrix_copy( inv_matrix, mesh->matrix );
                lib3ds_matrix_inv( inv_matrix );
                lib3ds_matrix_mult( M, M, inv_matrix );

                for( i = 0; i < mesh->nvertices; ++i )
                {
                    lib3ds_vector_transform( tmp, M, mesh->vertices[i] );
                    lib3ds_vector_copy( mesh->vertices[i], tmp );
                    cout << "Vertex: " << mesh->vertices[i][0] << ", " << mesh->vertices[i][1] << ", " << mesh->vertices[i][2] << endl;
                }
            }

            glGenBuffers( 1, &vertecies );
            glBindBuffer( GL_ARRAY_BUFFER, vertecies );
            glBufferData( GL_ARRAY_BUFFER, sizeof( float ) * 3 * facesCount, mesh->vertices, GL_STATIC_DRAW );

            float (*norms)[3] = (float(*)[3])malloc( sizeof( float ) * 9 * mesh->nfaces );
            lib3ds_mesh_calculate_vertex_normals( mesh, norms );

            glGenBuffers( 1, &normals );
            glBindBuffer( GL_ARRAY_BUFFER, normals );
            glBufferData( GL_ARRAY_BUFFER, sizeof( float ) * 3 * facesCount, norms, GL_STATIC_DRAW );
        }
    }


Rendern:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    NxMat34 pose = shape->getGlobalPose();

    glPushMatrix();
        this->material->bindMaterial();
        calcGLMatrix( pose.t, pose.M );

        glEnableClientState( GL_VERTEX_ARRAY );
        glEnableClientState( GL_NORMAL_ARRAY );

        glBindBuffer( GL_ARRAY_BUFFER, normalVBO );
        glNormalPointer( GL_FLOAT, 0, NULL );

        glBindBuffer( GL_ARRAY_BUFFER, vertexVBO );
        glVertexPointer( 3, GL_FLOAT, 0, NULL );

        glDrawArrays( GL_TRIANGLE_STRIP, 0, totalVertices * 3 );

        glDisableClientState( GL_VERTEX_ARRAY );
        glDisableClientState( GL_NORMAL_ARRAY );
    glPopMatrix();


Bild Ergebnisse:

(Link)


(Link)


Wie es sein sollte:

(Link)
[/url]

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

03.11.2008, 17:12

Sieht stark nach falsch sortierten Daten aus. Kenn mich mit lib3ds und dem 3ds Format nicht aus, daher: Woher weißt du, dass die Daten als Triangle-Strip angeordnert sind?
@D13_Dreinig

DJSebi

Frischling

  • »DJSebi« ist der Autor dieses Themas

Beiträge: 19

Wohnort: KÖLN!!!!!

Beruf: Musiker, Informatiker, DJ, Moderator

  • Private Nachricht senden

3

03.11.2008, 17:18

Wurde so in einem Beispiel angegeben, aber ich habe auch schon alle anderen Enums ausprobiert. Also GL_QUAD_... etc.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

4

03.11.2008, 17:22

Hm, soso...

Wozu verwendest du eigentlich "verts"? Ich seh den Sinn nicht so ganz! :)
@D13_Dreinig

DJSebi

Frischling

  • »DJSebi« ist der Autor dieses Themas

Beiträge: 19

Wohnort: KÖLN!!!!!

Beruf: Musiker, Informatiker, DJ, Moderator

  • Private Nachricht senden

5

03.11.2008, 17:22

Aber wenn man mit GL_TRIANGLE_STRIP das macht, dann sollte es bei komplexeren Objekten ja auch richtig sein, weil es soll ja nur eine Klasse geben, die einfach jedes 3ds-modell importieren kann.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

03.11.2008, 17:26

Ja, durchaus. Ich würde, an deiner Stelle, den Code nochmal sorgfältig mit dem Beispiel vergleichen. Zum Beispiel:

C-/C++-Quelltext

1
2
3
facesCount    = mesh->nvertices
float (*norms)[3] = (float(*)[3])malloc( sizeof( float ) * 9 * mesh->nfaces );
glBufferData( GL_ARRAY_BUFFER, sizeof( float ) * 3 * facesCount, norms, GL_STATIC_DRAW );


Das riecht irgendwie schon sehr seltsam...
@D13_Dreinig

DJSebi

Frischling

  • »DJSebi« ist der Autor dieses Themas

Beiträge: 19

Wohnort: KÖLN!!!!!

Beruf: Musiker, Informatiker, DJ, Moderator

  • Private Nachricht senden

7

03.11.2008, 17:27

Zitat von »"David_pb"«

Hm, soso...

Wozu verwendest du eigentlich "verts"? Ich seh den Sinn nicht so ganz! :)


Das sollte eigentlich noch mal zurück kopiert werden. Man kann es auch weglassen... ist eher unwichtig. In dem Beispiel sah das für mich aus, als ob man auf Nummer sicher gehen will, dass die Vertices nicht umgeschrieben werden, wenn man sie mit dem Matrix-Daten verrechnet.

DJSebi

Frischling

  • »DJSebi« ist der Autor dieses Themas

Beiträge: 19

Wohnort: KÖLN!!!!!

Beruf: Musiker, Informatiker, DJ, Moderator

  • Private Nachricht senden

8

03.11.2008, 17:30

Zitat von »"David_pb"«

Das riecht irgendwie schon sehr seltsam...


Also ich habe das Beispiel auch schon total abgeändert, weil das anscheind noch für eine ältere Lib3ds-Version zu sein scheint. Ich werd's mal nachher noch mal anschauen, aber ich gleaube es wird daran nicht liegen, mir sieht es eher danach aus, dass die Punkte in der falschen Reihenfolge eingelesen werden.

DJSebi

Frischling

  • »DJSebi« ist der Autor dieses Themas

Beiträge: 19

Wohnort: KÖLN!!!!!

Beruf: Musiker, Informatiker, DJ, Moderator

  • Private Nachricht senden

9

04.11.2008, 13:50

Also, bin dahinter gekommen. Das war mir nämlich noch nicht klar, dass ich für jedes Face (Dreieck) ja die Punkte brauche, d.h. das alle Punkte mehr mals vorkommen müssen. Dann muss man aber bei glDrawArrays auf GL_TRIANGLES stellen. Wenn man die Punkte (Vertecies) ausliest, dann muss man das nFaces mal machen, die dann drei Indexe haben, die sagen, welche Punkte. Ich poste einfach mal auch den SourceCode, damit andere, die mal was mit der Lib3ds machen möchten das auch machen können. Es kommen ja eh noch ein paar Tutorials auf der Seite http://3d.strohmy.de von mir zu diesem Thema. Danke für die Hilfe.

Einlesen:

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
    if( !filename->nodes )
        lib3ds_file_create_nodes_for_meshes( filename );
    lib3ds_file_eval( filename, 0 );

    Lib3dsNode* p;

    for( p = filename->nodes; p; p = p->next )
    {
        if( p->type == LIB3DS_NODE_MESH_INSTANCE )
        {
            Lib3dsMeshInstanceNode* node = (Lib3dsMeshInstanceNode*)p;
            Lib3dsMesh* mesh = lib3ds_file_mesh_for_node( filename, (Lib3dsNode*)node );

            float* verts = new float[mesh->nfaces * 9]; // 3 * 3 Punkte ((x, y, z) * 3)

            vertCount = 0;

            for( int i = 0; i < mesh->nfaces; ++i )
            {
                Lib3dsFace face = mesh->faces[i];

                for( int j = 0; j < 3; ++j )
                {
                    // Immer die richtige Vertex für das aktuelle Dreieck holen

                    verts[vertCount++]  =   mesh->vertices[face.index[j]][0];
                    verts[vertCount++]  =   mesh->vertices[face.index[j]][1];
                    verts[vertCount++]  =   mesh->vertices[face.index[j]][2];
                }
            }

            // Jetzt das ganze in den Vertex Buffer schreiben und fertig

            glGenBuffers( 1, &vertices );
            glBindBuffer( GL_ARRAY_BUFFER, vertices );
            glBufferData( GL_ARRAY_BUFFER, sizeof( float ) * 9 * mesh->nfaces, verts, GL_STATIC_DRAW );

            float (*norms)[3] = (float(*)[3])malloc( sizeof( float ) * 9 * mesh->nfaces );
            lib3ds_mesh_calculate_vertex_normals( mesh, norms );

            glGenBuffers( 1, &normals );
            glBindBuffer( GL_ARRAY_BUFFER, normals );
            glBufferData( GL_ARRAY_BUFFER, sizeof( float ) * 9 * mesh->nfaces, norms, GL_STATIC_DRAW );
        }
    }


Rendern:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    NxMat34 pose = shape->getGlobalPose(); // Von PhysX, braucht man nur, wenn man die PhysX-Engine nutzt


    glPushMatrix();
        this->material->bindMaterial();
        calcGLMatrix( pose.t, pose.M ); // Auch nur nötig für die PhysX-Engine


        glEnableClientState( GL_VERTEX_ARRAY );
        glEnableClientState( GL_NORMAL_ARRAY );

        glBindBuffer( GL_ARRAY_BUFFER, normalVBO );
        glNormalPointer( GL_FLOAT, 0, NULL );

        glBindBuffer( GL_ARRAY_BUFFER, vertexVBO );
        glVertexPointer( 3, GL_FLOAT, 0, NULL );

        glDrawArrays( GL_TRIANGLES, 0, totalVertices );

        glDisableClientState( GL_NORMAL_ARRAY );
        glDisableClientState( GL_VERTEX_ARRAY );
    glPopMatrix();

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

10

04.11.2008, 14:27

Nimm doch den Indexpuffer, den dir dein Lib3dsMesh-Objekt doch ohnehin anbietet, zum Rendern. Dann brauchst du auch keine Duplikate deiner Vertices mehr.
@D13_Dreinig

Werbeanzeige