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

Gotbread

Alter Hase

  • »Gotbread« ist der Autor dieses Themas

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

1

06.04.2009, 20:21

BSP Datei laden - Indices falsch

Hallo

Ich versuche grade eine quake2 map im bsp format einzulesen.
dabei gibt es ein problem, das entstandene modell besteht aus lauter,
scheinbar zufällig angeordneten dreiecken. sieht so aus, als ob die indices
falsch wären.

die .bsp infos habe ich von http://www.flipcode.com/archives/Quake_2_BSP_File_Format.shtml

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
struct bsp_lump
{

    uint32    offset;     // offset (in bytes) of the data from the beginning of the file

    uint32    length;     // length (in bytes) of the data


};
struct bsp_header
{

    uint32    magic;      // magic number ("IBSP")

    uint32    version;    // version of the BSP format (38)


    bsp_lump  lump[19];   // directory of the lumps


};
struct vertex
{
    float x, y, z;
    DWORD color;
};
struct bsp_face
{
    uint16   plane;             // index of the plane the face is parallel to

    uint16   plane_side;        // set if the normal is parallel to the plane normal


    uint32   first_edge;        // index of the first edge (in the face edge array)

    uint16   num_edges;         // number of consecutive edges (in the face edge array)

    
    uint16   texture_info;      // index of the texture info structure  

   
    uint8    lightmap_syles[4]; // styles (bit flags) for the lightmaps

    uint32   lightmap_offset;   // offset of the lightmap (in bytes) in the lightmap lump


};
struct bsp_edge
{
    short e1, e2;
};
//////////////////////////////////////////////////////

// "file" ist eine gültige datei


    char *filebuffer = file.GetBufferPointer();
    unsigned filesize = file.GetBufferSize();

    assert(filesize > sizeof(bsp_header));

    const bsp_header *header = reinterpret_cast<const bsp_header *>(filebuffer);

    assert(header->magic == *reinterpret_cast<unsigned long *>("IBSP"));

    bsp_lump vertex_lump = header->lump[2];
    bsp_lump face_lump = header->lump[6];
    bsp_lump edge_lump = header->lump[11];
    bsp_lump faceedge_lump = header->lump[12];

    std::vector<Vector3> vertices(vertex_lump.length / sizeof(Vector3));
    std::vector<unsigned short> indices;
    
    // Z-Achse zeigt nach oben

    {
        unsigned size = vertices.size();
        Vector3 *v = &vertices[0];
        const float *rawdata = reinterpret_cast<const float *>(filebuffer + vertex_lump.offset);

        for (unsigned i = 0; i < size; ++i)
        {
            v->x = *rawdata++;
            v->z = *rawdata++;
            v->y = *rawdata++;
            ++v;
        }
    }

    bsp_face *faces = reinterpret_cast<bsp_face *>(filebuffer + face_lump.offset);
    int *faceedges = reinterpret_cast<int *>(filebuffer + faceedge_lump.offset);
    bsp_edge *edges = reinterpret_cast<bsp_edge *>(filebuffer + edge_lump.offset);

    unsigned indicescount = 0;

    bsp_face *pfaces = faces;
    for (unsigned i = 0; i < face_lump.length / sizeof(bsp_face); ++i)
    {
        if (pfaces->num_edges == 3)
            indicescount += 3;
        else if (pfaces->num_edges == 4)
            indicescount += 6;
        else
            assert(!"Polygon nicht unterstützt!");

        ++pfaces;
    }

    indices.reserve(indicescount);

    pfaces = faces;
    for (unsigned i = 0; i < face_lump.length / sizeof(bsp_face); ++i)
    {
        unsigned index = abs(faceedges[pfaces->first_edge]);
        bsp_edge *edge = edges + index;

        if (pfaces->num_edges == 3)
        {
            indices.push_back(edge[0].e1);
            indices.push_back(edge[1].e1);
            indices.push_back(edge[2].e1);
        }
        if (pfaces->num_edges == 4)
        {
            indices.push_back(edge[0].e1);
            indices.push_back(edge[1].e1);
            indices.push_back(edge[2].e1);
            indices.push_back(edge[0].e1);
            indices.push_back(edge[2].e1);
            indices.push_back(edge[3].e1);
        }
        ++pfaces;
    }


das modell speichere ich mit der D3DX-funktion, da kann der fehler nicht
liegen.
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

Anonymous

unregistriert

2

07.04.2009, 18:58

Hallo,

Zitat

das entstandene modell besteht aus lauter,
scheinbar zufällig angeordneten dreiecken. sieht so aus, als ob die indices
falsch wären.

Was genau meinst du mit "zufällig" angeordnet? Sind die Werte überdimensional oder zu klein, zu groß? Falls du Hilfe erwartest, solltest du dein Problem besser beschreiben.

BTW:
Leg eine Lump-Enumeration an, ist schöner. Ich habe damals diese Spezifikation genommen: http://graphics.stanford.edu/~kekoa/q3/

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

3

12.04.2009, 15:58

Du hast beim einlesen der Polygonedge-Daten ein paar Fehler. Die "Face" Struktur referenziert Edgedaten nur über die Edgelookup Tabelle. D.h. first_edge zeigt auf den ersten Index in faceedges und num_edges gibt an wieviele darauffolgende Einträge (von faceedges) zu beachten sind, also z.B.:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int edge_index = 0;
short e1, e2;

for ( int i = 0; i < pfaces->num_edges; ++i )
{
    edge_index = faceedges[pfaces->first_edge+i];

    if ( edge_index < 0 )
    {
        edge_index = -edge_index;
        e1 = edge[edge_index].e2;
        e2 = edge[edge_index].e1;
    }
    else
    {
        e1 = edge[edge_index].e1;
        e2 = edge[edge_index].e2;
    }

    edgelist.add( e1, e2 ); 
}


Man beachte auch, dass die Kanten keine Richtung haben (weil sie ja von verschiedenen Polygonen geteilt genutzt werden). Die Richtung gibt das Vorzeichen von edge_index an.

Die Edge-Daten kannst du natürlich noch reduzieren und in ein Format bringen das zum rendern gängiger ist.

Werbeanzeige