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

03.03.2011, 20:04

Übung 2.9.5 - Spotlicht nicht sichtbar

Hallo Leute,
ich hänge gerade an dieser Aufgabe. :/

Was ich gemacht habe:
Spotlight und Material in der Renderfunktion erzeugt, wobei ich nicht weiß ob das Material hier wirklich notwendig ist
Vertexformat geändert
Normalenvektoren ergänzt für den Würfel (keine scharfen Kanten)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
struct SVertex
{
    tbVector3           vPosition;  // Position des Vertex
    tbVector3           vNormal; // Vertexnormalenvektor
    tbVector2           vTexture;   // Texturkoordinaten
    static const DWORD  dwFVF;      // Vertexformat
};

const DWORD SVertex::dwFVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;


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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
tbResult Render(float fNumSecsPassed)
{
    HRESULT     hResult;
    float       fAspect;
    tbMatrix    mCamera;
    tbMatrix    mProjection;
    D3DLIGHT9       SpotLight;
    D3DMATERIAL9    Material;
    DWORD       dwFogColor;
    
    // Die Nebelfarbe aus dem BGR- ins RGB-System umwandeln
    dwFogColor = D3DCOLOR_XRGB(GetRValue(g_dwFogColor),
                            GetGValue(g_dwFogColor),
                               GetBValue(g_dwFogColor));

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

    // Szene beginnen
    g_pD3DDevice->BeginScene();

    // Nebeleinstellungen
    g_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_FOGCOLOR, dwFogColor);
    g_pD3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, true);
    
    g_pD3DDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP);
    g_pD3DDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
    g_pD3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, true);

    g_pD3DDevice->SetRenderState(D3DRS_FOGSTART, 25);
    g_pD3DDevice->SetRenderState(D3DRS_FOGEND, 50);
    g_pD3DDevice->SetRenderState(D3DRS_FOGDENSITY,*((DWORD*)(&g_fFogValue)));

    // Beleuchtung
    // Das Spotlicht wird nun erstellt.
    ZeroMemory(&SpotLight, sizeof(D3DLIGHT9));
    SpotLight.Type          = D3DLIGHT_SPOT;                                // Spotlicht
    SpotLight.Diffuse       = tbColor(1.0f, 1.0f, 1.0f);                    // Weiße Streufarbe
    SpotLight.Ambient       = tbColor(1.0f, 1.0f, 1.0f);                    // Weiße Hintergrundfarbe
    SpotLight.Specular      = tbColor(1.0f, 1.0f, 1.0f);                    // Weiße Glanzfarbe
    SpotLight.Position      = tbVector3(0.0f, 0.0f, 0.0f);  // Variierende Position
    SpotLight.Direction = tbVector3(cos(g_fTime), 0.0f , sin(g_fTime));
    SpotLight.Falloff = 1.0f;
    SpotLight.Range     = 1000.0f;                                      // 1000 Einheiten Reichweite
    SpotLight.Attenuation0  = 0.0f;                                         // Lichtabschwächung
    SpotLight.Attenuation1  = 0.0025f;                                      // ...
    SpotLight.Attenuation2  = 0.0f;                                         // ...
    SpotLight.Phi = 2.0f;
    SpotLight.Theta = 1.0f;

    
    // Globales schwaches rotes Hintergrundlicht einstellen
    g_pD3DDevice->SetRenderState(D3DRS_AMBIENT, tbColor(0.25f, 0.0f, 0.0f));

    // Material
    Material.Diffuse    = tbColor(0.75f, 0.75f, 0.75f); // Hellgraue Streufarbe
    Material.Ambient    = tbColor(0.25f, 0.25f, 0.25f); // Dunkelgraue Hintergrundfarbe
    Material.Emissive   = tbColor(0.0f, 0.0f, 0.0f);    // Keine Eigenfarbe
    Material.Specular   = tbColor(0.25f, 0.25f, 0.25f); // 25% hellere Glanzfarbe als Streufarbe
    Material.Power      = 1.0f;     // Glanzfaktor variiert
        
    // Das Material einsetzen
    g_pD3DDevice->SetMaterial(&Material);

    // Licht einsetzen und aktivieren
    g_pD3DDevice->SetLight(0, &SpotLight);
    g_pD3DDevice->LightEnable(0, TRUE);

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

    // Die Kameramatrix erzeugen und einsetzen.
    // Dafür benötigen wir die Kameraposition, den Blickpunkt der Kamera und
    // die lokale y-Achse der Kamera, die normalerweise (0, 1, 0) ist (es sei denn,
    // die Kamera "rollt").
    mCamera = tbMatrixCamera(g_vCameraPosition,
                            g_vCameraPosition + tbVector3(sinf(g_fCameraAngle),
                                                        0.0f,
                                                           cosf(g_fCameraAngle)),
                            tbVector3(0.0f, 1.0f, 0.0f));
    g_pD3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)(&mCamera));

    // Das Bildseitenverhältnis berechnen
    fAspect =   (float)(g_Direct3DParameters.VideoMode.Width)
            / (float)(g_Direct3DParameters.VideoMode.Height);

    // Die Projektionsmatrix erzeugen und einsetzen.
    // Das geschieht hier einmal pro Bild, weil das Sichtfeld variabel ist.
    mProjection = tbMatrixProjection(g_fFOV,    // Sichtfeld
                                    fAspect,    // Bildseitenverhältnis
                                    0.1f,       // Nahe Clipping-Ebene
                                    250.0f);    // Ferne Clipping-Ebene
    g_pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)(&mProjection));

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

    // Alle Würfel auf einmal zeichnen.
    // Zuerst den Vertex- und den Index-Buffer als Datenquelle aktivieren.
    g_pD3DDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(SVertex));
    g_pD3DDevice->SetIndices(g_pIndexBuffer);

    // Zeichnen!
    hResult = g_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,    // Dreiecksliste
                                                0,                      // Basisvertexindex
                                                 0,                     // Der kleinste Index
                                                 g_iNumCubes * 8,       // Diff. zw. größtem u. kleinstem Index
                                                 0,                     // Von Anfang an zeichnen
                                                 g_iNumCubes * 12);     // 12 Dreiecke pro Würfel
    if(FAILED(hResult))
    {
        // Fehler beim Zeichnen!
        TB_ERROR_DIRECTX("g_pD3DDevice->DrawIndexedPrimitive", hResult, TB_STOP);
    }

    // Szene beenden
    g_pD3DDevice->EndScene();

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

    return TB_OK;
}


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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
tbResult InitScene()
{
    HRESULT         hResult;
    SVertex*        pVertices;
    unsigned short* pusIndices;
    tbVector3       vCubePosition;
    int             iStartVertex;
    int             iStartIndex;


    // Vertexformat setzen
    if(FAILED(hResult = g_pD3DDevice->SetFVF(SVertex::dwFVF)))
    {
        // Fehler beim Setzen des Vertexformats!
        TB_ERROR_DIRECTX("g_pD3DDevice->SetFVF", hResult, TB_ERROR);
    }

    // Beleuchtung und Culling ausschalten, Dithering aktivieren
    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    g_pD3DDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE);

    // Bilineare Texturfilter mit linearem MIP-Mapping
    g_pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    g_pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    g_pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

    // Die Textur laden
    if(FAILED(hResult = D3DXCreateTextureFromFileEx(g_pD3DDevice,       // Device
                                                    "Texture.bmp",      // Dateiname
                                                    D3DX_DEFAULT,       // Breite
                                                    D3DX_DEFAULT,       // Höhe
                                                    D3DX_DEFAULT,       // MIP-Maps
                                                    0,                  // Verwendungszweck
                                                    D3DFMT_UNKNOWN,     // Format
                                                    D3DPOOL_MANAGED,    // Speicherklasse
                                                    D3DX_FILTER_NONE,   // Filter
                                                    D3DX_DEFAULT,       // MIP-Map-Filter
                                                    0,                  // Color-Key
                                                    NULL,               // Unwichtig
                                                    NULL,               // Unwichtig
                                                    &g_pTexture)))      // Die Textur
    {
        // Fehler!
        TB_ERROR_DIRECTX("D3DXCreateTextureFromFileEx", hResult, TB_ERROR);
    }

    // Und nun die Textur einsetzen
    g_pD3DDevice->SetTexture(0, g_pTexture);

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

    // Den Vertex-Buffer erstellen. Jeder Würfel benötigt 8 Vertizes.
    // Daher ist die Vertex-Buffer-Größe gleich Anzahl der Würfel mal 8 mal Vertexgröße.
    if(FAILED(hResult = g_pD3DDevice->CreateVertexBuffer(g_iNumCubes * 8 * sizeof(SVertex),
                                                        0,
                                                         SVertex::dwFVF,
                                                         D3DPOOL_MANAGED,
                                                         &g_pVertexBuffer,
                                                         NULL)))
    {
        // Fehler beim Erstellen des Vertex-Buffers!
        TB_ERROR_DIRECTX("g_pD3DDevice->CreateVertexBuffer", hResult, TB_ERROR);
    }

    // Nun generieren wir den Index-Buffer. Jeder Würfel braucht 36 Indizes.
    // Es wird ein 16-Bit-Index-Buffer verwendet.
    if(FAILED(hResult = g_pD3DDevice->CreateIndexBuffer(g_iNumCubes * 36 * 2,
                                                        0,
                                                        D3DFMT_INDEX16,
                                                        D3DPOOL_MANAGED,
                                                        &g_pIndexBuffer,
                                                        NULL)))
    {
        // Fehler beim Erstellen des Index-Buffers!
        TB_ERROR_DIRECTX("g_pD3DDevice->CreateIndexBuffer", hResult, TB_ERROR);
    }

    // Vertex- und Index-Buffer komplett sperren
    g_pVertexBuffer->Lock(0, 0, (void**)(&pVertices), D3DLOCK_NOSYSLOCK);
    g_pIndexBuffer->Lock(0, 0, (void**)(&pusIndices), D3DLOCK_NOSYSLOCK);

    // Nun gehen wir jeden einzelnen Würfel durch.
    for(int iCube = 0; iCube < g_iNumCubes; iCube++)
    {
        // Zufällige Position für diesen Würfel erzeugen
        vCubePosition = tbVector3Random() * tbFloatRandom(10.0f, 40.0f);

        // Startvertex und Startindex für diesen Würfel berechnen.
        // Diese Werte beschreiben, an welcher Stelle im Vertex- und Index-Buffer
        // die Daten des aktuellen Würfels beginnen.
        iStartVertex = iCube * 8;
        iStartIndex = iCube * 36;

        // Vertizes für diesen Würfel generieren. Erst die Positionsangaben.
        pVertices[iStartVertex + 0].vPosition = vCubePosition + tbVector3(-1.0f,  1.0f, -1.0f);
        pVertices[iStartVertex + 1].vPosition = vCubePosition + tbVector3(-1.0f,  1.0f,  1.0f);
        pVertices[iStartVertex + 2].vPosition = vCubePosition + tbVector3( 1.0f,  1.0f,  1.0f);
        pVertices[iStartVertex + 3].vPosition = vCubePosition + tbVector3( 1.0f,  1.0f, -1.0f);
        pVertices[iStartVertex + 4].vPosition = vCubePosition + tbVector3(-1.0f, -1.0f, -1.0f);
        pVertices[iStartVertex + 5].vPosition = vCubePosition + tbVector3(-1.0f, -1.0f,  1.0f);
        pVertices[iStartVertex + 6].vPosition = vCubePosition + tbVector3( 1.0f, -1.0f,  1.0f);
        pVertices[iStartVertex + 7].vPosition = vCubePosition + tbVector3( 1.0f, -1.0f, -1.0f);

        // Normalenvektor für die Vertizes erzeugen
        pVertices[iStartVertex + 0].vNormal = tbVector3Normalize( tbVector3(-1.0f,  1.0f, -1.0f));
        pVertices[iStartVertex + 1].vNormal = tbVector3Normalize(tbVector3(-1.0f,  1.0f,  1.0f));
        pVertices[iStartVertex + 2].vNormal = tbVector3Normalize(tbVector3( 1.0f,  1.0f,  1.0f));
        pVertices[iStartVertex + 3].vNormal = tbVector3Normalize(tbVector3( 1.0f,  1.0f, -1.0f));
        pVertices[iStartVertex + 4].vNormal = tbVector3Normalize(tbVector3(-1.0f, -1.0f, -1.0f));
        pVertices[iStartVertex + 5].vNormal = tbVector3Normalize(tbVector3(-1.0f, -1.0f,  1.0f));
        pVertices[iStartVertex + 6].vNormal = tbVector3Normalize(tbVector3( 1.0f, -1.0f,  1.0f));
        pVertices[iStartVertex + 7].vNormal = tbVector3Normalize(tbVector3( 1.0f, -1.0f, -1.0f));

        for(int iVertex = iStartVertex; iVertex < iStartVertex + 8; iVertex++)
        {
            // Texturkoordinaten generieren
            pVertices[iVertex].vTexture = tbVector2Random();
        }

        // Nun die Indizes eintragen. Jeweils drei von ihnen ergeben ein Dreieck.
        int aiIndex[36] = {0, 3, 7,   0, 7, 4,  // Vorderseite
                        2, 1, 5,   2, 5, 6, // Hinterseite
                           1, 0, 4,   1, 4, 5,  // Linke Seite
                           3, 2, 6,   3, 6, 7,  // Rechte Seite
                           0, 1, 2,   0, 2, 3,  // Oberseite
                           6, 5, 4,   6, 4, 7}; // Unterseite

        // Die 36 Indizes in den Index-Buffer übertragen.
        // Zu jedem Indexwert muss noch der Startvertexwert addiert werden.
        for(int iIndex = 0; iIndex < 36; iIndex++)
        {
            // Index eintragen
            pusIndices[iStartIndex + iIndex] = aiIndex[iIndex] + iStartVertex;
        }
    }

    // Vertex- und Index-Buffer wieder entsperren
    g_pVertexBuffer->Unlock();
    g_pIndexBuffer->Unlock();

    return TB_OK;


Leider sehe ich kein Licht und das Bild ist jetzt SW, weil ich die Farbe der Würfel entfernt habe im Vertexformat (wie im anderen Thread zu der Übung empfohlen wurde).
Natürlich könnte man den ganze RenderState-Kram in die InitScene()-Funktion packen, was auch mehr Sinn macht, aber es sollte ja so auch gehen.

GR-PA

Treue Seele

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

2

03.03.2011, 20:09

Der Fehler liegt in diesem Codeausschnitt:

C-/C++-Quelltext

1
2
// Beleuchtung und Culling ausschalten, Dithering aktivieren
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

Die Lösung sollte offensichtlich sein...
Signaturen werden überbewertet

3

04.03.2011, 11:06

Merci.
Das Licht ist endlich sichtbar und die rote Farbe auf meiner Stirn aufgrund einer schmetternden Handfläche nimmt auch langsam ab.

Werbeanzeige