Du bist nicht angemeldet.

Werbeanzeige

Korowai

unregistriert

1

20.01.2017, 20:23

Vector an DirectX9 Draw Funktion übergeben

Hallo,

ich mal wieder im Garten des Unverstands.
Mein Problem: Wie übergebe ich die Directx9 D3DXVECTOR3 Funktion einer Spriteposition, die in einem vector gelagert ist an die Direcx9 Draw Funktion.
Ich dachte zunächst, dass ich das mit einer Referenz machen muss, aber das haut nicht hin. Wäre toll, jemand erklärt mir, wie ich in vector stl Klassen definierte DirectX Variablen und Funktionen übergebe.

Hier der Code, um den es geht:

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
void render_Mobil(float &Worldposx, float &Worldposy, float &Zoomfaktor, bool &Vorzeichen, float &Skalx, float &Skaly, float &Bildschirmbreite, float &Bildschirmhoehe)
{
    Bildgesamtx=Texturbreite*Skalx;
    Bildgesamty=Texturhoehe*Skaly;
    Skalx=Skalx+Zoomfaktor;
    Skaly=Skaly+Zoomfaktor;
    if (Skalx>=3.00||Skaly>=3.00)
               {
                   Skalx=3.00;
                   Skaly=3.00;
               }
    if (Skalx<=0.80||Skaly<=0.80)
                {
                    Skalx=0.80;
                    Skaly=0.80;
                }
    if (Zoomfaktor>0.2)
    {
        Zoomfaktor=0.2;
    }
    for ( std::vector<Mobilsprite>::iterator its = Mobile.begin(); its !=Mobile.end();++its)
{
    if (its->Mobilaktiv==true)
           {
    its->Mobilcenter= D3DXVECTOR3 (0.0f,0.0f,0.0f);



    D3DXVECTOR2 Scaling(Skalx,Skaly);
    D3DXMatrixTransformation2D(&Spritematrix,NULL,NULL,&Scaling,NULL,NULL,NULL);


    its->Bildschirmx=its->posx-(Worldposx*Skalx);
    its->Bildschirmy=its->posy-(Worldposy*Skaly);

    if (its->Bildschirmx<=0)
    {
        its->Bildschirmx=0;
    }
    if (its->Bildschirmy<=0)
    {
        its->Bildschirmy==0;
    }

     its->Mobilpos= D3DXVECTOR3(its->Bildschirmx,its->Bildschirmy,0.0f);

     d3ddev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 1.0f, 0);

    d3ddev->BeginScene();

    mSprite->Begin(D3DXSPRITE_ALPHABLEND);

    mSprite->Draw(Spielertextur,NULL,NULL,its->Mobilpos,0xFFFFFFFF); 

    mSprite->End();

    d3ddev->EndScene();
    d3ddev->Present(NULL,NULL,NULL,NULL);

           }
    else if (its->Mobilaktiv==false)
    {
        // Vergleich Vector mit Mobilarrays
        // Mobilarrayelement inaktiv schalten

        its=Mobile.erase(its);
    }
    else if (its->Landung==true)
    {
        // Vergleich Vector mit Mobilarray
        // Mobilarray in Landungsdauer und neuen Ort zuordnen

        its=Mobile.erase(its);
    }
    else
           {

               ++its;
           }



}

}


mSprite->Draw(Spielertextur,NULL,NULL,its->Mobilpos,0xFFFFFFFF)== Diese Zeile macht mir die Probleme. Wie erkläre ich der DRaw Funktion den Wert its->Mobilpos.

So? &its->Mobilpos?

Korowai

unregistriert

2

20.01.2017, 20:26

Edit

So initialisiere ich den vector der Klasse:

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
for (int x=0;x<3;x++)
    {
        Mobile.push_back(Mobilsprite());
    }
    for (int y=0;y<3;y++)
    {
        int a;
        int b;
        a= rand()%499+1;
        b= rand()%399+1;
        Mobile[y].posx=a;
        Mobile[y].posy=b;
        Mobile[y].Mobilaktiv=true;
        Mobile[y].Mobilvernichtet=false;


    Mobile[y].Landung=false;
    Mobile[y].Feuergefecht=false;
    Mobile[y].Reichweite=50;
    Mobile[y].Mobilart=0;
    Mobile[y].Bildschirmx=a;
    Mobile[y].Bildschirmy=b;


    }

Korowai

unregistriert

3

21.01.2017, 07:14

Update

Hi,

ich habe es jetzt einfach mal probiert. Leider rendert er jetzt in schneller Bildfolge unendlich viele Sprites, der Bildausschnitt flackert und die SPrites flirren herum.

Ich habe den DEbugger aktiviert. Er zeigt mir für den iterator leider keine weiteren Werte an.

Ich poste mal:

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
void render_Mobil(float &Worldposx, float &Worldposy, float &Zoomfaktor, bool &Vorzeichen, float &Skalx, float &Skaly, float &Bildschirmbreite, float &Bildschirmhoehe)
{
    Bildgesamtx=Texturbreite*Skalx;
    Bildgesamty=Texturhoehe*Skaly;
    Skalx=Skalx+Zoomfaktor;
    Skaly=Skaly+Zoomfaktor;
    if (Skalx>=3.00||Skaly>=3.00)
               {
                   Skalx=3.00;
                   Skaly=3.00;
               }
    if (Skalx<=0.80||Skaly<=0.80)
                {
                    Skalx=0.80;
                    Skaly=0.80;
                }
    if (Zoomfaktor>0.2)
    {
        Zoomfaktor=0.2;
    }
    for ( std::vector<Mobilsprite>::iterator its = Mobile.begin(); its !=Mobile.end();++its)
{
    if (its->Mobilaktiv==true)
           {
    its->Mobilcenter= D3DXVECTOR3 (0.0f,0.0f,0.0f);



    D3DXVECTOR2 Scaling(Skalx,Skaly);
    D3DXMatrixTransformation2D(&Spritematrix,NULL,NULL,&Scaling,NULL,NULL,NULL);


    its->Bildschirmx=its->posx-(Worldposx*Skalx);
    its->Bildschirmy=its->posy-(Worldposy*Skaly);

    if (its->Bildschirmx<=0)
    {
        its->Bildschirmx=0;
    }
    if (its->Bildschirmy<=0)
    {
        its->Bildschirmy==0;
    }

     its->Mobilpos= D3DXVECTOR3(its->Bildschirmx,its->Bildschirmy,0.0f);

     d3ddev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 1.0f, 0);

    d3ddev->BeginScene();

    mSprite->Begin(D3DXSPRITE_ALPHABLEND);

    mSprite->Draw(its->Mobiltextur,NULL,NULL,&its->Mobilpos,0xFFFFFFFF);

    mSprite->End();

    d3ddev->EndScene();
    d3ddev->Present(NULL,NULL,NULL,NULL);

           }
    else if (its->Mobilaktiv==false)
    {
        // Vergleich Vector mit Mobilarrays
        // Mobilarrayelement inaktiv schalten
        if( its->Mobiltextur != NULL )
        its->Mobiltextur->Release();

        its=Mobile.erase(its);
    }
    else if (its->Landung==true)
    {
        // Vergleich Vector mit Mobilarray
        // Mobilarray in Landungsdauer und neuen Ort zuordnen
        if( its->Mobiltextur != NULL )
        its->Mobiltextur->Release();

        its=Mobile.erase(its);
    }
    else
           {

               ++its;
           }



}

}


Hat jemand einen Vorschlag, warum es nicht klappt?

David Scherfgen

Administrator

Beiträge: 10 199

Wohnort: Bonn

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

21.01.2017, 08:58

Zeile 42 hat einen Fehler.
Außerdem leerst du für jedes Sprite den Bildschirm und zeigst das Bild an. Ich glaube nicht, dass du das willst.
Und du solltest unbedingt an deinem Stil arbeiten, dieser Code ist absolut grausig anzusehen.

Korowai

unregistriert

5

21.01.2017, 09:23

Hi David,

danke fürs Reinschauen.

Zeile 42 korrigiere ich.

Der Holzhackerstil bekommt noch Feinschnitt. Aber das ist ein Testcode, der aufgrund mehrmaligem Umstellen jetzt durchaus grausig ist.
Generell werde ich meinen Stil mit Sicherheit auch weiter entwickeln, wenn die Zeit gekommen ist, sich vom Anfänger zum Geübten zu entwickeln.

Die clear() und present() werde ich gleich mal umstellen und rauslöschen. Danke.

Mein Problem hat eher was mit dem vector zu tun...(?)

Aber ich schaue erstmal, was passiert, wenn man klaren Blick bekommt.

David Scherfgen

Administrator

Beiträge: 10 199

Wohnort: Bonn

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

6

21.01.2017, 11:04

Noch ein Fehler: In Zeile 21 steht ++its, und in Zeile 82 nochmal. So wie ich das sehe, sollte das aus Zeile 21 weg! Sonst überspringst du jeden zweiten Eintrag.

Korowai

unregistriert

7

24.01.2017, 22:32

Hallo,

der Zwischenstand:

Das Problem der Sprites ist gelöst. Aus irgendeinem Grund lassen sich die Elemente des vector nicht im Dialog erstellen. Habe sie in der winmain erstellt. Jetzt geht es.

Ich habe noch nicht herausgefunden, wie ich die directx9 Befehle von Present() und Clear() anpassen muss, damit die beiden render Funktionen sich nicht gegenseitig löschen. Der Luna schreibt dazu nix. Hat jemand einen Tipp für mich?

David Scherfgen

Administrator

Beiträge: 10 199

Wohnort: Bonn

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

24.01.2017, 23:42

Ich habe noch nicht herausgefunden, wie ich die directx9 Befehle von Present() und Clear() anpassen muss, damit die beiden render Funktionen sich nicht gegenseitig löschen. Der Luna schreibt dazu nix. Hat jemand einen Tipp für mich?

Für jedes Frame gilt: Clear rufst du einmal ganz am Anfang auf, bevor du irgendwas zeichnest. Present rufst du ganz am Ende auf, nachdem du alles gezeichnet hast.

Korowai

unregistriert

9

27.01.2017, 08:31

Hi,

leider hänge ich noch an einer anscheinend rein mathematischen Problematik.

Ich erkläre erstmal die Variablen und die Funktion der Bildbewegungs- Zoomfunktion:

Wenn der Hintergrund in einer Skalierung (Skalx, Skaly; zunächst 1.00) bewegt wird (Worldposx, Worldposy),
werden die Spritepositionen (posx, posy) auf (Bildschirmx, Bildschirmy) geändert.

Beispiel:
Bild wird nach rechts bewegt: (Sprites wandern also nach links==bleiben auf der selben Stelle des Hintergrunds, während Bild nach rechts bewegt)

Worldposx=Worldposx-2.00;

Berechnen des Rects des Hintergrundes:
rect.left=(0+Worldposx)*Skalx;
rect.right=((Bildschirmbreite)+Worldposx)*Skalx;
rect.top=(0+Worldposy)*Skaly;
rect.bottom=(Bildschirmhoehe+Worldposy)*Skaly;

Rendering Hintergrund:
mSprite->Draw(Hintergrundtextur, &rect,NULL,&Hintergrundposition, 0xFFFFFFFF);

Die Sprites:
Berechnung der Position:
its->Bildschirmx=its->posx-(Worldposx*Skalx);
its->Bildschirmy=its->posy-(Worldposy*Skaly);
its->Mobilpos= D3DXVECTOR3(its->Bildschirmx,its->Bildschirmy,0.0f);
Darstellung der Sprites:
mSprite->Draw(Mobiltextur,NULL,NULL,&its->Mobilpos,0xFFFFFFFF);

Das Problem ist, dass die Sprites, wenn der Hintergrund bspw. auf den linken Bildschirmrand trifft, natürlichwerweise ab diesem Zeitpunkt nach rechts wandern, da Worldposx sich weiter ändert, auch wenn der Hintergrund nicht mehr weiter nach rechts verschoben werden kann, weil er bereits den linken Bildschirmrand erreicht hat.

Ich habe jetzt Schwierigkeiten, den Sprites mitzuteilen: "Du darfst nicht anfangen, nach rechts zu wandern, wenn das Hintergrundbild sich nicht mehr bewegt"

Diverse Dinge habe ich probiert, aber es scheitert, glaube ich, am reinen mathematischen Formulieren dieser Anweisung.

An sich müsste es in diese Richtung gehen:

if (i->Bildschirmx-(Worldposx*Skalx)<=rect.left+i->Bildschirmx)
{
Worldposx=Worldposx+2.00; // also, Worldposx bleibt 0
}

Erklärung: Wenn die Bildschirmposx des Sprites zuzüglich der Verschiebung (Worldposx*Skalx) <= dem linken Bildrand (0) + der Bildschirmposx des Sprites ist, dann muss Worldposx (Verschiebung x) = 0 sein.

Auf nachfrage poste ich auch gerne den code, aber der ist aus den vorangegangenen posts an sich ersichtlich. Hat jemand eine Idee?
Was mache ich falsch?

Korowai

unregistriert

10

28.01.2017, 07:25

Hallo,

ich bekomme es leider nicht hin. Ist zufällig jemand bereit, sich mal den kompletten Code anzusehen?

Habe jetzt probiert:
- Die Pos des Sprites gegen Null zu prüfen um dann die Verschiebung gegenläufig zu machen
- Die screenrect in ihrer Lage in den relativen Bildschirmkoordinaten zu prüfen um dann die Verschiebung gegenläufig zu machen

Ich glaube, dass vielleicht mein Konzept hinsichtlich der gesamten Scroll Thematik kein guter Anwendungsfall ist. Wahrscheinlich gibt es einfacherer und effizientere Lösungen. Hat da jemand ein ähnliches Projekt gehabt, aus dem ich abkupfern darf?

Danke im Voraus für jeden Tipp.

Werbeanzeige