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

28.10.2010, 00:35

Ränder einer Fläche werden beim Drehen abwechselnd dick und dünn gezeichnet! Warum?

Hallo!
Meine Frage bezieht sich auf Beispiel 3 "Das erste Dreieck" des 2. Kapitels (3.Auflage).

Also, wenn ich mit D3DFILL_WIREFRAME um die Fläche des sich drehenden Dreiecks zusätzlich einen Rand zeichne, wird der dem Betrachter abgewandte Rand immer mit einer dünnen und der zugewandte Rand mit einer dicken Linie gezeichnet.

Ich habe schon verschiedene Einstellungen ausprobiert aber es bleibt so. Auch eine orthogonale Projektionsmatrix ändert daran nichts.

Unten steht die Render-Funktion, durch die man die alte ersetzen kann, um es zu testen (sonst habe ich am Programm nichts verändert).
Zwei Bilder habe ich auch angehängt

Weiß jemand wie ich die Ränder immer dick zeichnen kann?

Vielen Dank schon mal im Voraus!

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
// Render-Funktion
tbResult Render(float fNumSecsPassed)
{
    HRESULT     hResult;
    tbMatrix    mRotation;      // Rotationsmatrix
    tbMatrix    mTranslation;   // Translationsmatrix
    tbMatrix    mWorld;         // Vereinende Weltmatrix


    // Rotations- und Translationsmatrix des Dreiecks erzeugen
    mRotation = tbMatrixRotationY(TB_DEG_TO_RAD(g_fTime * 90.0f));
    mTranslation = tbMatrixTranslation(tbVector3(0.0f, 0.0f, 2.0f)); 

    // Beide Matrizen kombinieren und als Weltmatrix einsetzen
    mWorld = mRotation * mTranslation;
    g_pD3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)(&mWorld));

    // -------------------------------------------------------------

    // Den Bildpuffer und den Z-Buffer leeren
    if(FAILED(hResult = g_pD3DDevice->Clear(0,
        NULL,
        D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
        D3DCOLOR_XRGB(234, 234, 234),
        1.0f,
        0)))
    {
        // Fehler beim Leeren!
        MessageBox(g_hWindow, "Fehler beim Leeren der Puffer!",
            "Fehler", MB_OK | MB_ICONEXCLAMATION);
        TB_ERROR_DIRECTX("g_pD3DDevice->Clear", hResult, TB_STOP);
    }

    // Szene beginnen
    g_pD3DDevice->BeginScene();

    g_aTriangleVertex[0].dwColor    = tbColor(.7f, .7f, .7f);  
    g_aTriangleVertex[1].dwColor    = tbColor(.7f, .7f, .7f);
    g_aTriangleVertex[2].dwColor    = tbColor(.7f, .7f, .7f);

    g_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);

    // Nun das Dreieck zeichnen
    if(FAILED(hResult = g_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST,   // Dreiecksliste
        1,                  // 1 Dreieck
        g_aTriangleVertex,  // Vertexdaten
        sizeof(SVertex))))  // Vertexgröße
    {
        // Fehler beim Zeichnen!
        MessageBox(g_hWindow, "Fehler beim Zeichnen des Dreiecks!",
            "Fehler", MB_OK | MB_ICONEXCLAMATION);
        TB_ERROR_DIRECTX("g_pD3DDevice->DrawPrimitiveUP", hResult, TB_STOP);
    }



    g_aTriangleVertex[0].dwColor    = tbColor(0.0f, 0.0f, 0.0f);
    g_aTriangleVertex[1].dwColor    = tbColor(0.0f, 0.0f, 0.0f);
    g_aTriangleVertex[2].dwColor    = tbColor(0.0f, 0.0f, 0.0f);


    //g_pD3DDevice->SetRenderState( D3DRS_DEPTHBIAS, 10 );  
    //g_pD3DDevice->SetRenderState( D3DRS_SLOPESCALEDEPTHBIAS, 10 );


    g_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
    g_pD3DDevice->DrawPrimitiveUP(D3DPT_LINESTRIP,  
        2,                  
        g_aTriangleVertex,  
        sizeof(SVertex));

    // Szene beenden
    g_pD3DDevice->EndScene();

    // Der große Moment: den Bildpuffer sichtbar machen
    g_pD3DDevice->Present(NULL, NULL, NULL, NULL);

    return TB_OK;
}
»stoic« hat folgende Dateien angehängt:
  • dick.bmp (71,98 kB - 88 mal heruntergeladen - zuletzt: 20.04.2024, 14:47)
  • duenn.bmp (65,57 kB - 85 mal heruntergeladen - zuletzt: 26.04.2024, 05:47)

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

2

28.10.2010, 05:56

Scharfe, dünne Linien die nicht horizontal oder vertikal verlaufen auf einem Bildschirm aus rechteckigen Pixeln zu rendern ist nicht ganz so einfach, bzw nur näherungsweise möglich.

Ich würde es mal mit Anti Aliasing versuchen, das könnte den Effekt verringern. Unter dem Stichwort MSAA+DirectX lassen sich bei google Beispiele finden wie man das aktiviert.

3

28.10.2010, 07:52

Neben den von xardias genannten möglichen Ursachen:
Beim zweiten Rendern statt D3DPT_LINESTRIP nochmals D3DPT_TRIANGLELIST verwenden.
Ggf. das Wireframe-Dreieck leicht verschieben und nochmals zeichnen.
Renderstate CullMode auf None setzen.
Eine höhere Bildschirmauflösung verwenden.

Ansonsten willkommen im Forum! ;)

Und bitte keine Bitmaps (BMP) fürs Web verwenden.
fka tm

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

4

28.10.2010, 09:43

Das ergibt sich so aus den Rasterisierungsregeln von DirectX. Siehe Doku.

5

29.10.2010, 01:46

Vielen Dank für eure Antworten!

Das was ich verstanden habe, habe ich bis auf einen Vorschlag ausprobiert, es hat das Problem noch nicht gelöst. Eine unten beschriebene Beobachtung deuten aber darauf hin, dass es eine einfache Lösung geben müsste.

Hier mein Bericht und anschließend die Beobachtung, die vielleicht jemand auf eine Lösung des Problems bringen könnte:

@xardias: Also wenn ich Antialiasing einschalte (Referenz-Rasterizer mit 9 Samples: Dies kann man direkt in dem Direct3D-Einstellungs-Dialog des Beispiels machen) werden die Ränder natürlich schöner, aber es ändert nichts daran, dass der hinten liegende Rand immer dünner ist als der vordere Rand.

@TrikkieMikkie: D3DPT_TRIANGELLIST hatte ich schon probiert, dadurch wird das Dreieck vollständig umrandet und man kann den beschriebenen Unterschied ständig sehen.
Auch bei der höchsten Bildschirmauflösung das gleiche Bild. Der Cullmode ist in dem Programm in InitScene() schon auf NONE gesetzt.

Das mit der Verschiebung habe ich jetzt noch nicht probiert. Das funktioniert wahrscheinlich, aber ich fände es schön, wenn es eine einfachere Lösung gäbe, denn dies ist nur ein vereinfachtes Beispiel. Letztlich möchte ich gleich dicke Linien auch bei komplexen Objekten zeichnen und dann wird diese Methode wohl recht kompliziert und man könnte evtl. sehen, dass sich die Ränder über der Fläche befinden.

@TGGC: Was du mit Rasterisierungsregeln meinst, habe ich nicht verstanden. Bezieht sich das auf die Antialiasing Thematik die xardias oben schon beschrieben hat?

//-----------------------------------------------------------

Weitere Beobachtungen, die vielleicht zu einer Lösungsidee führen könnten:

Wenn man nur die Ränder ohne die Fläche des Dreiecks zeichnet, sind die Ränder alle gleich dick,
also so wie es sein sollten. Es scheint als würde die Fläche die Ränder teilweise verdecken, wenn der Rand hinten ist.

Deshalb hatte ich oben in der Renderfunktion (dort auskommentiert) versucht einen Bias für den Z-Buffer zu verwenden:

g_pD3DDevice->SetRenderState( D3DRS_DEPTHBIAS, 10 );
g_pD3DDevice->SetRenderState( D3DRS_SLOPESCALEDEPTHBIAS, 10 );

Dies sollte eigentlich dazu führen, dass ein Pixel des Randes über ein bereits gemaltes Pixel der Fläche gemalt wird, auch wenn sie sich beide in der gleichen Tiefe befinden oder der Rand sogar durch Rundungsfehler im Z-Buffer als tiefer angesehen wird.

Leider funktioniert das in meinem Beispiel nicht. Es müsste aber eigentlich irgendwie so gehen, oder? Was könnte ich da falsch gemacht haben?

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

6

29.10.2010, 08:42

@TGGC: Was du mit Rasterisierungsregeln meinst, habe ich nicht verstanden. Bezieht sich das auf die Antialiasing Thematik die xardias oben schon beschrieben hat?
Ja, dann hast du das Problems nicht verstanden. Der Rest hat damit nichts zu tun. Ich beziehe mich auch auf nichts anderes. Lies doch bitte einfach die Doku, bevor wir hier Abhandlungeden darueber schreiben muessen.

7

29.10.2010, 11:35

@TGGC: Was du mit Rasterisierungsregeln meinst, habe ich nicht verstanden. Bezieht sich das auf die Antialiasing Thematik die xardias oben schon beschrieben hat?
Ja, dann hast du das Problems nicht verstanden. Der Rest hat damit nichts zu tun. Ich beziehe mich auch auf nichts anderes. Lies doch bitte einfach die Doku, bevor wir hier Abhandlungeden darueber schreiben muessen.
Ich weiß, dass ich das Problem und das was du in deinem Beitrag angedeutet hast, nicht verstanden habe. Was meinst du jetzt mit "Rest" und du beziehst dich "auf nichts anderes"? Am Antialiasing liegt es, wie ich beschrieben habe nicht. Wenn du weißt ob oder wie das Problem zu lösen ist, wäre ich dir für einen konkreten inhaltlichen Satz dankbar. Wenn du es nicht weißt oder es mir nicht sagen möchtest, ist es aber auch ok.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »stoic« (29.10.2010, 11:43)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

29.10.2010, 11:49

Lies doch einfach die Doku. Dann hast Du das Problem zumindest einmal vollständig durchgearbeitet und nicht nur halbwegs lavede hingebogen.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

9

29.10.2010, 12:10

Lies doch einfach die Doku. Dann hast Du das Problem zumindest einmal vollständig durchgearbeitet und nicht nur halbwegs lavede hingebogen.
Hm, bin ich mit dem DEPTHBIAS auf der falschen Fährte? Welche Doku meint ihr eigentlich? Ich habe nur das "DirectX Software Development Kit". Hast du einen Link zu einer besseren Doku die ich dazu durcharbeiten kann? Ich würde allerdings lieber das Buch von David weiter durcharbeiten. Werde ich die Lösung dort auch finden? Anscheinend wollt ihr ein Quiz mit mir spielen. ;)

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

10

29.10.2010, 12:31

Wenn du weißt ob oder wie das Problem zu lösen ist, wäre ich dir für einen konkreten inhaltlichen Satz dankbar.
Indem du einen eigenen Rasterizer schreibst, der nach Regeln arbeitet, die zu dem von dir gewuenschten Ergebnis fuehren.

Werbeanzeige