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

1

27.02.2005, 01:14

Uebungsaufgabe 3, Kapitel 2.7.6 Seite 185

Hi,


Zitat

[...]Schreiben Sie eine Funktion namens TransformVertexPositions, die einen Vertex-Buffer und eine Matrix als Parameter erwartet und dann alle Vertizes im Vertex-Buffer mit dieser Matrix transformiert![...]


also ich habe mir vorgenommen diese Aufgabe zu lösen, (weil da stand dass ich dann sehr sehr gut bin :-D ;) ) und habe diese aufgabe wie folgt gelöst:


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
tbResult TransformVertexPositions(PDIRECT3DVERTEXBUFFER9 VertexBuffer,tbMatrix TransfMatrix)
{
    D3DVERTEXBUFFER_DESC Desc;

    VertexBuffer->GetDesc(&Desc);
    
    if (Desc.FVF != SVertex::dwFVF) // wie frage ich einzelne Flags ab???

    {
        TB_ERROR("Der VertexBuffer hat nicht das D3DFVF_XYZ Flag!",TB_ERROR);
    }

    UINT FVFSize = D3DXGetFVFVertexSize(Desc.FVF);

    int VerticesInBuffer = Desc.Size / FVFSize;

    SVertex* pvVertex = NULL;

    VertexBuffer->Lock(0,0,(void**) (&pvVertex),D3DLOCK_NOSYSLOCK);
    
    for (int i = 0; i < VerticesInBuffer; i++)
    {   
        
        pvVertex[i].vPosition = tbVector3TransformCoords(pvVertex[i].vPosition,TransfMatrix,NULL);
    }
        
    VertexBuffer->Unlock();

    return TB_OK;
}



jo, wie ihr seht ist mein einzigstes problem noch das überprüfen, ob das D3DFVF_XYZ flag gesetzt ist, zur zeit lass ich noch das vorgegebene überprüfen, was ja nicht sinn des ganzen ist...

also meine frage: wie löse ich dieses problem, und ist das was ich da gemacht habe so überhaupt richtig? (bei mir hats jedenfalls funktioniert)

Steven77

Alter Hase

Beiträge: 515

Wohnort: Münster - Gievenbeach

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

27.02.2005, 10:11

Re: Uebungsaufgabe 3, Kapitel 2.7.6 Seite 185

Zitat von »"Zipfeklatscher"«

C-/C++-Quelltext

1
if (Desc.FVF != SVertex::dwFVF) // wie frage ich einzelne Flags ab???


Mach es doch so:

C-/C++-Quelltext

1
2
3
4
if (!(Desc.FVF & D3DFVF_XYZ))
{
        // D3DFVF_XYZ nicht gesetzt!

}

Stichwort "bitweise Undverknüpfung"... ;)

3

27.02.2005, 17:51

genau das wollte ich wissen, danke dir ;)


(ja ich hab in den hilfen geschaut habs aber nicht gefunden, oder einfach nur nich verstanden)

Anonymous

unregistriert

4

27.02.2005, 19:50

die funktion ist soweit richtig und wird wohl auch funktionieren. das einzige, was mir nicht gefaellt, ist, dass du davon ausgehst, dass du es mit SVertex zu tun hast. ich glaube, die aufgabe war so gemeint, dass jeder beliebige vertextyp benutzt werden kann. ich habe es so geloest:

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
void transform_vertex_positions ( IDirect3DVertexBuffer9* const vertex_buffer,
                              const tbMatrix& transform_matrix )  {
  D3DVERTEXBUFFER_DESC buffer_description;

    if ( !vertex_buffer -> GetDesc ( &buffer_description ) )
        return;

    if ( buffer_description.FVF ^ D3DFVF_XYZ )
        return;

    void* vertex;

    if ( vertex_buffer -> Lock ( 0, buffer_description.Size, &vertex, D3DLOCK_NOSYSLOCK ) )
        return;

    const std::size_t vertex_size =  D3DXGetFVFVertexSize ( buffer_description.FVF );

    for ( std::size_t number_of_vertices = buffer_description.Size / vertex_size; number_of_vertices; --number_of_vertices )  {
        *static_cast < tbVector3* > ( vertex ) = tbVector3TransformCoords ( *static_cast < tbVector3* > ( vertex ),
                                                                            transform_matrix );

        vertex = reinterpret_cast < void* > ( reinterpret_cast < unsigned long > ( vertex ) + vertex_size );
    }

    vertex_buffer -> Unlock ();
};


mfg,
google.com

5

27.02.2005, 21:37

hi, ja das stimmt, ich bin leider noch recht neu, auch in c++. ich werd mir das mal anschauen wie du das gelöst hast und werd versuchen es zu verstehen ;)

6

22.01.2009, 15:18

Servus,

ich besitze das Buch nun seit ein paar Tagen und bin gerade dabei es durchzuarbeiten...

Eigentlich wollte ich nicht unbedingt einen 4 Jahre alten Thread ausgraben, aber da die Suchfunktion mir keinen Neueren zum Thema angeboten hat (sry, fals ich doch was übersehen hab) und sich meine Frage auf ebend diese Aufgabe bezieht, post ich mein Anliegen nun doch hier - schließlich besteht die Aufgabe ja auch noch in der aktuellen Auflage. :)

Zitat

Hier nochmal die Aufgabe:
Schreiben Sie eine Funktion TransformVertexPositions, die einen Vertex-Buffer und eine Matrix als Parameter erwartet und dann alle Vertizes im Vertex-Buffer mit dieser Matrix transformiert! Es müssen nur die Positionsvektoren der Vertizes verändert werden. Beachten Sie, dass das Vertexformat beliebig sein kann!


Es hat 'ne ganze Weile gedauert, aber ich konnte die Aufgabe lösen (die Lösung von google.com war mir leider zu kryptisch und deshalb keine große Hilfe ;/).

Meine Lösung schaut nun also wie folgt aus:

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
// TransformVertexPositions

//

// Aufgabe: Positionsvektoren aller Vertizes im übergebenen Buffer mit

// der übergebenen Matrix Transformieren

//

tbResult TransformVertexPositions(PDIRECT3DVERTEXBUFFER9 pVertexBuffer,
                                  const tbMatrix &mMatrix)
{
    // Buffer-Description

    D3DVERTEXBUFFER_DESC Desc;  

    // Beschreibung holen

    pVertexBuffer->GetDesc(&Desc);

    // Ungültiges Vertex-Format

    if(!(Desc.FVF & D3DFVF_XYZ))
        return TB_ERROR;

    // Vertex-Größe

    int iVertexSize = D3DXGetFVFVertexSize(Desc.FVF);
    
    // Anzahl Vertizes berechnen

    int iNumVertices = Desc.Size / iVertexSize;

    // Buffer sperren

    char *pVertices;
    pVertexBuffer->Lock(0, 0, (void**)&pVertices, D3DLOCK_NOSYSLOCK);

    // Zeiger auf Positionsvektor

    void *pPosition;

    // Vertex-Positionen transformieren

    for(int iVertex = 0; iVertex < iNumVertices; iVertex++)
    {
        // Adresses des Positionsvektors des aktuellen Vertex berechnen

        pPosition = (void*)&pVertices[iVertex * iVertexSize];
        // Vektor transformieren

        *((tbVector3*)pPosition) = tbVector3TransformCoords(*((tbVector3*)pPosition), 
                                                            mMatrix, NULL);
    }

    // Buffer entsperren

    pVertexBuffer->Unlock();

    return TB_OK;
}



Nun zu meiner Frage: Geht das Schreiben von Daten an eine bestimmte Adresse in einem Speicherbereich (auf den ein void-Pointer zeigt) auch einfacher?


Zum Beispiel durch eine mir nicht bekannte Methode der man als[list]1. Parameter: einen Zeiger auf den Speicher in den geschieben werden soll
2. Parameter: Größe der zu schreibenden Daten in (z. B. Byte)
3. Parameter: die zu schreibenden Daten
[/list]übergibt?

Google war mir leider keine Hilfe, aber vllt hab' waren meine Suchwörter nicht gerade optimal (i. d. R. find' ich aber was ich suche).


Danke schonmal im Vorraus! (edit: Vor-raus (wieso auch immer...)

Gruß,
Kalle

Faule Socke

Community-Fossil

Beiträge: 1 915

Wohnort: Schreibtischstuhl

  • Private Nachricht senden

7

22.01.2009, 16:58

Es heißt "voraus", nicht "vor-raus".

Naja es geht schon ein bisschen einfacher, du brauchst die Adresse ja sowieso immer als tbVector3 Zeiger, mir würde folgendes einfallen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// TransformVertexPositions

tbResult TransformVertexPositions(PDIRECT3DVERTEXBUFFER9 pVertexBuffer,
                                  const tbMatrix &mMatrix)
{
// ...

    // Zeiger auf Positionsvektor

    tbVector3 *pPosition; //!!!


    // Vertex-Positionen transformieren

    for(int iVertex = 0; iVertex < iNumVertices; iVertex++)
    {
        // Adresses des Positionsvektors des aktuellen Vertex berechnen

        pPosition = reinterpret_cast<tbVector3*>(&pVertices[iVertex * iVertexSize]);
        // Vektor transformieren

        *pPosition = tbVector3TransformCoords(*pPosition), mMatrix, 0);
    }
// ...

}


Die Funktion die du suchst nennt sich memcpy. Du kannst an eine Adresse n bytes einer anderen Adresse kopieren. In deinem Fall macht das allerdings wenig sinn würde ich sagen...

Hoffe, ich konnte dir helfen,

Socke

8

22.01.2009, 18:51

Zitat von »"Faule Socke"«

Es heißt "voraus", nicht "vor-raus".

DOH! Natürlich... Naja immerhin weiß ich nun was es damit auf sich hat, wenn die Forensoftware Wörter maskiert :lol:


Den "Positionsvektor-Pointer" direkt als tbVector3* zu deklarieren hatte ich zunächst auch versucht, das führte dann aber zu 'ner Access-Violation. Was an meinem Cast lag (ich weiß leider nimmer genau was ich da geschrieben hatte - war gestern Abend...). Deswegen der Umweg über den void-Pointer. Mit dem reinterpret_cast klappts aber wunderbar.

Merci :)


Ja memcpy hilft hier nicht weiter.
Allerdings sollte der 2. Parameter meiner "Wunschfunktion" auch nicht die "Größe der zu Schreibenden Daten", sondern die "Position (Byte) im Zielspeicher sein". Also
Funktion(pZielspeicher, PositionImZielspeicher, pQuellspeicher)

(Denken -> Posten... ;/)

Auf diese weise hätt ich mir gerne das Zerlegen des VertexBuffer in Character gespart :roll:


Aber danke nochmal für deine fixe Antwort!

Gruß, Kalle

Werbeanzeige