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

31

05.02.2011, 02:59

Das ist eine gute Idee, sicher sehr viel effizienter. Wie soll ich dann die ganzen Vertices abspeichern? Kann ich da noch mit Vectoren arbeiten? Wie kann man den ganzen Inhalt eines Vectores der memcpy-Funktion übergeben? Die IndexBuffer mache ich genau so, wie ich bisher die VertexBuffer erzeugt habe.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Patrick Egli« (05.02.2011, 03:05)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

32

05.02.2011, 11:05

Naja bei einem allgemeinen 3D Mesh hat man normalerweise den Fall dass viele Dreiecke sich Vertices teilen. Man legt diese Vertices dann nur einmal in einem VertexBuffer ab und verwendet dann Indices um zu definieren welche Vertices wie zu Dreiecken verbunden werden. Im Allgemeinen ist das die performanteste Art um Modelle zu rendern, nicht nur weil es am wenigsten Speicher und Bandbreite verbraucht sondern vor allem auch weil es der Grafikkarte erlaubt einen Vertex Cache zu benutzen. Man geht oft sogar soweit die Indices mit aufwändigen Verfahren so zu sortieren dass der Vertex Cache möglichst optimal genutzt wird was, wenn man sehr viele Dreiecke rendern muss, die Performance signifikant erhöhen kann. Ich würde auch nur einen IndexBuffer für alle SubMeshes des Modells verwenden. Du packst einfach nacheinander die Indizes für jedes Submesh in einen Buffer und merkst dir wo sie anfangen und aufhören. Also ein VertexBuffer und ein IndexBuffer für das ganze Modell. Wobei das alles natürlich nur Sinn macht wenn du nicht einfach die 3 Vertices von jedem Dreieck nacheinander in der VertexBuffer stopfst und dann den indexBuffer mit 1, 2, 3, 4, ... füllst. Damit das alles was bringt musst du natürlich die Möglichkeit nutzen Vertices mehrfach zu verwenden.

Einen Pointer auf den Beginn eines std::vector bekommst du mit &vector[0].

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »dot« (05.02.2011, 11:17)


Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

33

05.02.2011, 15:47

Nun habe ich die Vertexdaten vom Vector in einen Zeiger gespeichert. Doch ich weiss nicht genau wie ich den ganzen Vector dem Zeiger übergeben kann. Ich habe nur die Adresse des ersten Eintrages des Vector übergeben. Zugleich habe ich auch noch die Anzahl der Vertices in einen Zeiger abgespeichert, dort ist es ebenfalls genau das gleiche, es wird nur die Adresse des ersten Eintrages des Vecotors übergeben.

Hier ist ein Codeausschnitt:

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
::veSModel * Model;
    Model = &m_ModelData[0];
    unsigned int * pNumber = &m_Model.NumVertices[0];
    m_NumAllVertices = (*pNumber);

    for(unsigned int i = 0; i < m_NumMeshes; ++i)
    {
        if(FAILED(hResult = d3ddev->CreateVertexBuffer(*pNumber * sizeof(veModelVertex),
                                                       D3DUSAGE_WRITEONLY,
                                                       ModelVertexFVF,
                                                       D3DPOOL_MANAGED,
                                                       &m_pVertexBuffer,
                                                       NULL)))
        {
            MessageBox(NULL, "Fehler beim Erzeugen des VertexBuffers", "Fehler aufgetreten",
                       MB_OK | MB_ICONEXCLAMATION);

            return false;
        }

        void * pData;
        m_pVertexBuffer->Lock(0, 0, (VOID**)&pData, 0);
        memcpy(pData, Model->Vertices, sizeof(veModelVertex) * (*pNumber));
        m_pVertexBuffer->Unlock();
    }


Wie kann ich den ganzen Vector dem Zeiger übergeben, habe bereits im Internet gesucht aber nichts gefunden.

Zur Zeit wird nur das erste Mesh gerendert, da jeweils nur die ersten Einträge in den Zeigern übergeben werden.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

34

05.02.2011, 15:49

Ich versteh nicht ganz, was meinst du mit "den ganzen Vector dem Zeiger übergeben"!? &vector[0] ist ein Zeiger auf das erste Element des vectors und damit, da ein vector nichts als ein lineares Array ist, ein Zeiger auf das erste Element eines Arrays. Mehr brauchst du nicht, den Zeiger kannst du direkt so an memcpy() übergeben. Alternativ verwend std::copy() oder schreib einfach eine Schleife die alle Elemente kopiert, daran sollte es eigentlich nicht scheitern!?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (05.02.2011, 15:55)


Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

35

05.02.2011, 16:02

Ich meine damit, dass alle Vertexdaten, welche im Vector gespeichert sind, dem Zeiger übergeben werden sollten. Doch leider funktioniert das nicht mit:

C-/C++-Quelltext

1
2
::veSModel * Model;
    Model = &m_ModelData[0];


Mit &m_ModelData[0] wird doch lediglich die Adresse des ersten Eintraesg des Vectors dem Zeiger übergeben.

Meine Frage ist jetzt wie kann ich alle Einträge des Vectors dem Zeiger übergeben?

Die For-Schleife könnte dann wie folgt ausssehen oder?

C-/C++-Quelltext

1
2
3
4
5
6
7
for(unsigned int i = 0; i < m_NumMeshes; ++i)
        {
            void * pData;
            m_pVertexBuffer->Lock(0, 0, (VOID**)&pData, 0);
            memcpy(pData, m_ModelData[i].Vertices, sizeof(veModelVertex) * m_Model.NumVertices[i]);
            m_pVertexBuffer->Unlock();
        }

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

36

05.02.2011, 16:05

Ich versteh dein Problem nicht, klingt für mich irgendwie als wär dir der Zusammenhang zwischen Zeigern und Arrays nicht so ganz klar!?
Was ist denn m_ModelData[ i].Vertices!?

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

37

05.02.2011, 16:17

m_ModelData ist ein Vector auf die Struktur veSModel, diese ist wie folgt aufgebaut:

C-/C++-Quelltext

1
2
3
4
struct veSModel
{
veModelVertex * Vertices;
};


Und Vertices ist ein Zeiger auf die Vertexstruktur veModelVertex, diese sieht folgendermassen aus:

C-/C++-Quelltext

1
2
3
4
5
6
struct veModelVertex
{
float posx, posy, posz;
float normalx, normaly, normalz;
float tu, tv;
};


Wenn ich das nun mit der for-Schleife mache, dann werden schon mehere Meshes angezeigt, aber immer noch nicht alle.

C-/C++-Quelltext

1
2
3
4
5
6
7
for(unsigned int i = 0; i < m_NumMeshes; ++i)
        {
            void * pData;
            m_pVertexBuffer->Lock(0, 0, (VOID**)&pData, 0);
            memcpy(pData, m_ModelData[i].Vertices, sizeof(veModelVertex) * m_Model.NumVertices[i]);
            m_pVertexBuffer->Unlock();
        }


Die Anzahl der Vertices aller Meshes habe ich ebenfalls durch eine for-Schleife herausgefunden:

C-/C++-Quelltext

1
2
3
4
for(unsigned int i = 0; i < m_NumMeshes; ++i)
{
m_NumAllVertices += m_Model.NumVertices[i];
}

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

38

05.02.2011, 16:23

Na dann hast du aber doch in m_ModelData schon Zeiger auf deine Vertices!? Ich versteh jetzt wirklich nicht wo genau das Problem liegt oder wo du da einen vector an memcpy() übergeben müsstest!? Wenn du außerdem vorhast Indizes zu nutzen find ich es komisch dass offenbar jedes Mesh ein unabhängiges Vertex Array hat.

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

39

05.02.2011, 16:26

Ich muss den Vector übergeben, da ich die Vertexdaten im Vector abgespeichert habe. Dann muss ich doch iregenwie die Vertexdaten der memcpy Funktion übergeben.

Gibt es eine andere Möglichkeit?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

40

05.02.2011, 16:30

So wie ich das jetzt verstanden hab enthält dein vector lediglich structs die wiederum Zeiger enthalten die dann auf die Vertexdaten zeigen und nicht die Vertexdaten an sich. Was du also brauchst sind diese Zeiger und nicht der vector, und die hast du doch!?
Ich denke du verbeißt dich gerade zu sehr in die Idee dass du mit einem einzigen memcpy() den ganzen Buffer füllen musst. Wenn deine Vertexdaten (warum auch immer) über mehrere Arrays verteilt liegen geht das natürlich nicht. Das ist ja aber auch kein Problem, musst du halt jedes Array einzeln an die richtige Stelle kopieren!?
memcpy() tut einfach nur genau das, nämlich Speicherblöcke kopieren. VertexBuffer->Lock() gibt dir einfach nur einen Zeiger auf einen Speicherbereich der dem Inhalt des VertexBuffer entspricht. Wie du dort dann reinschreibst ist vollkommen dir überlassen. Niemand sagt dass du dafür überhaupt memcpy() verwenden musst, es bietet sich halt einfach nur an, du kannst aber genausogut selber eine Schleife schreiben die einfach jeden Vertex kopiert oder was auch immer.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »dot« (05.02.2011, 16:37)


Werbeanzeige