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

12.09.2006, 20:51

2 Skyboxes blenden

Hi, ich bin ein totaler Anfänger in Sachen DirectX, und versuche mich gerade an dem Buch "3d-Spieleprogrammierung mit DirectX 9 und C++".
Ich wollte jetzt mal ein winziges Projekt machen, wo 2 Skyboxen (rot und blau) in wechselndem Verhältnis geblendet werden, um darauf aufbauend vielleicht einen Himmel zu erstellen, der sich den Tageszeiten anpasst.
Dazu wollte ich auf dem Projekt "EnvMapping" aufbauen.
Mein Problem ist, dass irgendwie nur die zweite Sky-Box angezeigt wird, also alles ist nur rot. Ich hab auch einfach mal probiert, die rote Skybox mit Multitexturing in die zweite Schicht der ersten Skybox zu packen, aber dann weiß ich nicht, wie man das Verhältnis der beiden Texturen zueinander ändert....
Übrigens hab ich das Alphablending bei den Kugeln im selben Projekt ausprobiert, da klappt es. Hier ist jedenfalls mal der 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
    g_pD3DDevice->SetFVF(SVertex::dwFVF);


    // Die Beleuchtung und Z-Buffering schalten wir ab.

    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
    g_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);

    // Das Alpha-Blending aktivieren

    g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,    TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND,            D3DBLEND_SRCALPHA);
    g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND,           D3DBLEND_INVSRCALPHA);

    // In die erste Texturschicht setzen wir die Umgebungstextur. Die zweite Schicht ist leer.

    g_pD3DDevice->SetTexture(0, g_pEnvMap);
    g_pD3DDevice->SetTexture(1, NULL);

    // Nun erstellen wir eine Translationsmatrix, die dafür sorgt, dass sich die Kamera immer

    // genau in der Mitte der Sky-Box befindet.

    mWorld = tbMatrixTranslation(g_vCameraPosition);
    g_pD3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)(&mWorld));

    Material.Diffuse    = tbColor(0.0f, 0.0f, 0.0f, 0.5);
    g_pD3DDevice->SetMaterial(&Material);
    // Jetzt zeichnen wir die Sky-Box mit DrawIndexedPrimitiveUP.

    g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
    if(FAILED(hResult = g_pD3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,    // Dreiecksliste

                                                             0,                     // Beginn bei 0

                                                             8,                     // Größter Index

                                                             12,                    // Anz. Dreiecke

                                                             g_ausSkyBoxIndex,      // Indizes

                                                             D3DFMT_INDEX16,        // 16 Bits

                                                             g_aSkyBoxVertex,       // Vertizes

                                                             sizeof(SVertex))))     // Vertexgröße

    {
        // Fehler beim Zeichnen!

        TB_ERROR_DIRECTX("g_pD3DDevice->DrawIndexedPrimitiveUP", hResult, TB_ERROR);
    }
    g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
    if(FAILED(hResult = g_pD3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,    // Dreiecksliste

                                                             0,                     // Beginn bei 0

                                                             8,                     // Größter Index

                                                             12,                    // Anz. Dreiecke

                                                             g_ausSkyBoxIndex,      // Indizes

                                                             D3DFMT_INDEX16,        // 16 Bits

                                                             g_aSkyBoxVertex,       // Vertizes

                                                             sizeof(SVertex))))     // Vertexgröße

    {
        // Fehler beim Zeichnen!

        TB_ERROR_DIRECTX("g_pD3DDevice->DrawIndexedPrimitiveUP", hResult, TB_ERROR);
    }

    Material.Diffuse    = tbColor(0.0f, 0.0f, 0.0f, 0.5);
    g_pD3DDevice->SetMaterial(&Material);

    // In die erste Texturschicht setzen wir die Umgebungstextur. Die zweite Schicht ist leer.

    g_pD3DDevice->SetTexture(0, g_pEnvMap2);
    g_pD3DDevice->SetTexture(1, NULL);
    //g_pD3DDevice->SetTexture(1, NULL);



    // Nun erstellen wir eine Translationsmatrix, die dafür sorgt, dass sich die Kamera immer

    // genau in der Mitte der Sky-Box befindet.

    mWorld = tbMatrixTranslation(g_vCameraPosition);
    g_pD3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)(&mWorld));

    // Jetzt zeichnen wir die Sky-Box mit DrawIndexedPrimitiveUP.

    g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
    if(FAILED(hResult = g_pD3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,    // Dreiecksliste

                                                             0,                     // Beginn bei 0

                                                             8,                     // Größter Index

                                                             12,                    // Anz. Dreiecke

                                                             g_ausSkyBoxIndex,      // Indizes

                                                             D3DFMT_INDEX16,        // 16 Bits

                                                             g_aSkyBoxVertex,       // Vertizes

                                                             sizeof(SVertex))))     // Vertexgröße

    {
        // Fehler beim Zeichnen!

        TB_ERROR_DIRECTX("g_pD3DDevice->DrawIndexedPrimitiveUP", hResult, TB_ERROR);
    }
    g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
    if(FAILED(hResult = g_pD3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,    // Dreiecksliste

                                                             0,                     // Beginn bei 0

                                                             8,                     // Größter Index

                                                             12,                    // Anz. Dreiecke

                                                             g_ausSkyBoxIndex,      // Indizes

                                                             D3DFMT_INDEX16,        // 16 Bits

                                                             g_aSkyBoxVertex,       // Vertizes

                                                             sizeof(SVertex))))     // Vertexgröße

    {
        // Fehler beim Zeichnen!

        TB_ERROR_DIRECTX("g_pD3DDevice->DrawIndexedPrimitiveUP", hResult, TB_ERROR);
    }

    // Die Einstellungen wieder zurücksetzen

    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);


In der InitScene Funktion habe ich unter anderem stehen:

C-/C++-Quelltext

1
2
3
4
    // Direct3D soll den Alphakanal der Texturen und den Alphawert der Streufarbe verwenden.

    g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE);
    g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
    g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);


PS: Ich gehe mal davon aus, dass ich einen ganz blöden Fehler gemacht habe...
Ich hoffe, das wird hier nicht als "Missbrauch" des Forums angesehen, ich weiß mir eben keinen Rat mehr! :(

Chase

Alter Hase

Beiträge: 753

Wohnort: Nagaoka / Darmstadt / Düsseldorf

Beruf: fauler Studi

  • Private Nachricht senden

2

12.09.2006, 23:31

Also ich finde David hat das Multi-texturing recht gut erklaert (Kapitel 2.11)..
Das "Mischen" der Texturen geschieht bei dir ueber den Alpha-Wert der Texutur:

C-/C++-Quelltext

1
g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,    D3DTOP_MODULATE);

=> Du multiplizierst beide Argumente

C-/C++-Quelltext

1
g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1,    D3DTA_CURRENT);

=> Das erste Argument ist das Standartregister, sprich der 'bisherige' Wert

C-/C++-Quelltext

1
g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2,    D3DTA_TEXTURE);

=> Das zweite Argument kommt aus dem Alpha-wert der Textur (!)
Und eben diesen Alpha-wert kann man schlecht dynamisch veraendern. Ich wuerde zu diesem Zweck einfach einen Alpha-wert aus der Vertexfarbe nehmen und diesen nach belieben veraendern.
(D3DTA_DIFFUSE)
"Have you tried turning it off and on again?"

3

13.09.2006, 15:25

Hm, das hat irgendwie noch nicht ganz hingehauen.
Ich habe jetzt g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); statt g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);, habe der Vertextstruktur für die Skyboxen eine Variable dwColor vom Typ DWORD gegeben und das Vertexformat geändert (D3DFVF_DIFFUSE hinzugefügt). Dann habe ich die Alphawerte der beiden Vertex-Arrays in der InitScene funktion initialisiert, doch egal auf was ich sie initialisiere, es wird immer im selben Verhältnis geblendet, es kommt eine Art sehr dunkles rot heraus. Was habe ich falsch gemacht/vergessen?
Oder sollte ich es gleich nochmal mit Multitexturing versuchen?

Beiträge: 774

Beruf: Student

  • Private Nachricht senden

4

16.09.2006, 19:40

ich hab sowas erst neulich implementiert ... allerdings überblende ich 4 skyboxes

An sich gibts nur eine und die hat 2 Texturkoordinaten (3D versteht sich)

Je nach Tageszeit, werden die 2 richtigen Texturen eingesetzt. Die Übergänge mach ich mit dem Coloroperator BlendFactorAlpha.

5

16.09.2006, 22:04

Vielen Dank, es geht!
Keine Ahnung, warum ich es nicht schon vorher hingekriegt habe - Die Lösung stand ja quasi schon im Multitexturing Beispiel. :)

Werbeanzeige