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.01.2008, 15:20

Übungsaufgabe 2.9.5 (.1)

Hallo,

Erstmal Glückwunsch an den Herrn Scherfegen für ein doch recht gutes Lehrbuch. Hab schon einige Lehrbücher durch (bisher allerdings nur zum Thema C++ Grundkenntnisse) und dieses ist bisher von der Schreibweise, den Erläuterungen und den lustigen Sprüchen das beste ;)

Jetzt aber zu meinem Problem... die Aufgabe ist ja dem Topic zu entnehmen.

Es geht darum, das Beispielprogramm mit den Würfeln so umzuschreiben, dass sie eine rotierende Spotlichtquelle enthält.

Zu diesem Zweck hab ich die Übungsaufgabe aus dem Kapitel zuvor genommen (Würfel + Nebel) und wollte sie nun um diese Funktion erweitern.

Leider haut das Ganze so nicht wirklich hin, da ich nur schwarz sehe. Entferne ich alles, was mit Licht zu tun hat (also auch LIGHTING und COLORVERTEX "umkehren") funktioniert das Programm ganz normal. Nur eben ohne Licht.

Ich habe jetzt mindestens 1-2 Stunden nach dem Fehler gesucht und auch in den Foren hier geschaut und kann leider nichts finden, das mir weiter hilft. Ich vermute, dass es irgendwie mit den Normalenvektoren der Vertices zu tun hat, aber... keine Ahnung :/

Deren Berechnung hab ich mir etwas vereinfacht, indem ich jeweils den Vektor zwischen dem Würfelmittelpunkt und der Ecke genommen und diesen normalisiert habe (so sollte ich eigentlich die 8 gesuchten Normalenvektoren erhalten).

Hier sind die (hoffentlich) relevanten Codeausschnitte:

C-/C++-Quelltext

1
2
3
4
5
6
7
struct SVertex
{
    tbVector3           vPosition;  // Position des Vertex

    tbVector3           vNormal;    
    tbVector2           vTexture;   // Texturkoordinaten

    static const DWORD  dwFVF;      // Vertexformat

};


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
tbResult Render(float fNumSecsPassed)
{
    HRESULT     hResult;
    float       fAspect;
    tbMatrix    mCamera;
    tbMatrix    mProjection;
    DWORD       dwFogColor;
    float       fFogStart = 1000.0f;
    float       fFogEnd = 15000.0f;
    float       fFogDens = 0.018f;
    D3DMATERIAL9    Material;
    D3DLIGHT9       SpotLight;

    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();


    g_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_FOGCOLOR, dwFogColor);
    g_pD3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP2);
    g_pD3DDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
    g_pD3DDevice->SetRenderState(D3DRS_FOGSTART, *((DWORD*)(&fFogStart)));
    g_pD3DDevice->SetRenderState(D3DRS_FOGEND, *((DWORD*)(&fFogEnd)));
    g_pD3DDevice->SetRenderState(D3DRS_FOGDENSITY, *((DWORD*)(&fFogDens)));

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


    // 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);
    }


    Material.Diffuse = tbColor(1.0f, 0.0f, 0.0f);
    Material.Ambient = tbColor(0.1f, 0.0f, 0.0f);
    Material.Specular = tbColor(0.5f, 0.5f, 0.5f);
    Material.Emissive = tbColor(0.0f, 0.0f, 0.0f);
    Material.Power = 10.f;

    g_pD3DDevice->SetMaterial(&Material);

    ZeroMemory(&SpotLight, sizeof(D3DLIGHT9));
    SpotLight.Type          = D3DLIGHT_SPOT;                                
    SpotLight.Diffuse       = tbColor(1.0f, 1.0f, 1.0f);                    
    SpotLight.Ambient       = tbColor(1.0f, 1.0f, 1.0f);                    
    SpotLight.Specular      = tbColor(1.0f, 1.0f, 1.0f);                    
    SpotLight.Position      = tbVector3(0.0f, 100.0f , 100.0f);
    SpotLight.Direction     = g_vSpotDir;
    SpotLight.Range         = 10000.0f;                                     
    SpotLight.Attenuation0  = 0.0f;                                         
    SpotLight.Attenuation1  = 0.025f;                                       
    SpotLight.Attenuation2  = 0.0f; 
    SpotLight.Falloff       = 1.0f;
    SpotLight.Theta         = TB_DEG_TO_RAD(30.0f);
    SpotLight.Phi           = TB_DEG_TO_RAD(90.0f);

    g_pD3DDevice->SetLight(0, &SpotLight);
    g_pD3DDevice->LightEnable(0, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_AMBIENT, tbColor(0.15f, 0.15f, 0.15f));

    // 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
tbResult Move(float fNumSecsPassed)
{
    tbVector3 vCameraDirection;
    g_fTime += fNumSecsPassed;

//hier wird rotiert

    tbMatrix mRotation(tbMatrixRotationY(TB_DEG_TO_RAD(g_fTime * 90.0f)));
    g_vSpotDir = tbVector3TransformCoords(g_vSpotDir, mRotation);

    if(GetAsyncKeyState(VK_LEFT)) g_fCameraAngle -= TB_DEG_TO_RAD(45.0f) * fNumSecsPassed;
    if(GetAsyncKeyState(VK_RIGHT)) g_fCameraAngle += TB_DEG_TO_RAD(45.0f) * fNumSecsPassed;

    vCameraDirection = tbVector3(sinf(g_fCameraAngle), 0.0f, cosf(g_fCameraAngle));

    if(GetAsyncKeyState(VK_UP)) 
    {
        g_vCameraPosition += vCameraDirection * g_CamSpeed * fNumSecsPassed;
        g_CamSpeed += 0.005;
    }
    else if(GetAsyncKeyState(VK_DOWN))
    {
        g_vCameraPosition -= vCameraDirection * g_CamSpeed * fNumSecsPassed;
        g_CamSpeed -= 0.005;
    }

    if(GetAsyncKeyState(VK_PRIOR)) g_fFOV -= TB_DEG_TO_RAD(15.0f) * fNumSecsPassed;
    if(GetAsyncKeyState(VK_NEXT)) g_fFOV += TB_DEG_TO_RAD(15.0f) * fNumSecsPassed;

    if(g_fFOV >= TB_DEG_TO_RAD(180.0f)) g_fFOV = TB_DEG_TO_RAD(179.9f);
    else if(g_fFOV <= TB_DEG_TO_RAD(0.0f)) g_fFOV = TB_DEG_TO_RAD(0.1f);


    return TB_OK;
}


Die beiden folgenden sind im InitScene() anzutreffen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE);
    g_pD3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);
    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);


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
// 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++)
    {

        vCubePosition = tbVector3Random() * tbFloatRandom(20.0f, 250.0f);

        iStartVertex = iCube * 8;
        iStartIndex = iCube * 36;

        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);

        pVertices[iStartVertex + 0].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 0].vPosition);
        pVertices[iStartVertex + 1].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 1].vPosition);
        pVertices[iStartVertex + 2].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 2].vPosition);
        pVertices[iStartVertex + 3].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 3].vPosition);
        pVertices[iStartVertex + 4].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 4].vPosition);
        pVertices[iStartVertex + 5].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 5].vPosition);
        pVertices[iStartVertex + 6].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 6].vPosition);
        pVertices[iStartVertex + 7].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 7].vPosition);


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

        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


        for(int iIndex = 0; iIndex < 36; iIndex++)
        {
            // Index eintragen

            pusIndices[iStartIndex + iIndex] = aiIndex[iIndex] + iStartVertex;
        }
    }

    g_pVertexBuffer->Unlock();
    g_pIndexBuffer->Unlock();


Ich dachte zunächst, der Fehler könnte im Rotieren liegen, aber auch als ich das Licht zum Punktlicht gemacht hatte, war noch immer alles schwarz. Ich bin grad sehr ratlos....

2

28.01.2008, 16:11

Sieht so aus, daß du erst renderst, und dann das Licht erstellst...
Ich würde das Ganze (Licht initialisieren etc.) in die Init-Routine packen.

3

28.01.2008, 18:38

So, habs in die InitScene() gepackt, aber es sieht immer noch aus wie der Krieg der Finsternis im dunklen Tunnel bei Nacht :(

Ich hab auch mal das Licht wieder in ein Punktlicht verwandelt, zu Testzwecken.

Hier die "neuen" Codeausschnitte (wobei ich ja eigentlich nur ein paar Dinge verschoben und die Sache, die zum Spotlicht gehören, ausgeklammert hab).

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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
tbResult InitScene()
{
    HRESULT         hResult;
    SVertex*        pVertices;
    unsigned short* pusIndices;
    tbVector3       vCubePosition;
    int             iStartVertex;
    int             iStartIndex;
    DWORD       dwFogColor;
    float       fFogStart = 1000.0f;
    float       fFogEnd = 15000.0f;
    float       fFogDens = 0.018f;
    D3DMATERIAL9    Material;
    D3DLIGHT9       SpotLight;

    dwFogColor = D3DCOLOR_XRGB(GetRValue(g_dwFogColor),
                               GetGValue(g_dwFogColor),
                               GetBValue(g_dwFogColor));


    // 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, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE);
    g_pD3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);
    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);
    }

    Material.Diffuse = tbColor(1.0f, 0.0f, 0.0f);
    Material.Ambient = tbColor(0.1f, 0.0f, 0.0f);
    Material.Specular = tbColor(0.5f, 0.5f, 0.5f);
    Material.Emissive = tbColor(0.0f, 0.0f, 0.0f);
    Material.Power = 10.f;

    g_pD3DDevice->SetMaterial(&Material);

    ZeroMemory(&SpotLight, sizeof(D3DLIGHT9));
    SpotLight.Type          = D3DLIGHT_POINT;                               
    SpotLight.Diffuse       = tbColor(1.0f, 1.0f, 1.0f);                    
    SpotLight.Ambient       = tbColor(1.0f, 1.0f, 1.0f);                    
    SpotLight.Specular      = tbColor(1.0f, 1.0f, 1.0f);                    
    SpotLight.Position      = tbVector3(0.0f, 100.0f , 100.0f);
    //SpotLight.Direction     = g_vSpotDir;

    SpotLight.Range         = 10000.0f;                                     
    SpotLight.Attenuation0  = 0.0f;                                         
    SpotLight.Attenuation1  = 0.025f;                                       
    SpotLight.Attenuation2  = 0.0f; 
    /*SpotLight.Falloff     = 1.0f;
    SpotLight.Theta         = TB_DEG_TO_RAD(30.0f);
    SpotLight.Phi           = TB_DEG_TO_RAD(90.0f);*/

    g_pD3DDevice->SetLight(0, &SpotLight);
    g_pD3DDevice->LightEnable(0, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_AMBIENT, tbColor(0.15f, 0.15f, 0.15f));

    g_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_FOGCOLOR, dwFogColor);
    g_pD3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP2);
    g_pD3DDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
    g_pD3DDevice->SetRenderState(D3DRS_FOGSTART, *((DWORD*)(&fFogStart)));
    g_pD3DDevice->SetRenderState(D3DRS_FOGEND, *((DWORD*)(&fFogEnd)));
    g_pD3DDevice->SetRenderState(D3DRS_FOGDENSITY, *((DWORD*)(&fFogDens)));

    // 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++)
    {

        vCubePosition = tbVector3Random() * tbFloatRandom(20.0f, 250.0f);

        iStartVertex = iCube * 8;
        iStartIndex = iCube * 36;

        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);

        pVertices[iStartVertex + 0].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 0].vPosition);
        pVertices[iStartVertex + 1].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 1].vPosition);
        pVertices[iStartVertex + 2].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 2].vPosition);
        pVertices[iStartVertex + 3].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 3].vPosition);
        pVertices[iStartVertex + 4].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 4].vPosition);
        pVertices[iStartVertex + 5].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 5].vPosition);
        pVertices[iStartVertex + 6].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 6].vPosition);
        pVertices[iStartVertex + 7].vNormal = tbVector3Normalize(vCubePosition 
                                                - pVertices[iStartVertex + 7].vPosition);


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

        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


        for(int iIndex = 0; iIndex < 36; iIndex++)
        {
            // Index eintragen

            pusIndices[iStartIndex + iIndex] = aiIndex[iIndex] + iStartVertex;
        }
    }

    g_pVertexBuffer->Unlock();
    g_pIndexBuffer->Unlock();

    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
tbResult Render(float fNumSecsPassed)
{
    HRESULT     hResult;
    float       fAspect;
    tbMatrix    mCamera;
    tbMatrix    mProjection;

    // Den Bildpuffer und den Z-Buffer leeren

    if(FAILED(hResult = g_pD3DDevice->Clear(0,
                                            NULL,
                                            D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
                                            g_dwFogColor,
                                            1.0f,
                                            0)))
    {
        // Fehler beim Leeren!

        TB_ERROR_DIRECTX("g_pD3DDevice->Clear", hResult, TB_STOP);
    }

    // Szene beginnen

    g_pD3DDevice->BeginScene();

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


    // 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;
}

4

28.01.2008, 19:50

Möglicherweise liegt es am Vertexformat. Das Beispiel mit dem Nebel verwendet folgendes Format:

C-/C++-Quelltext

1
const DWORD SVertex::dwFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;


So sollte es aussehen:

C-/C++-Quelltext

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

Die Normalenkomponente käme noch dazu, Diffuse-Anteil raus.

EDIT:
Ich hab deinen Code mal mit folgenden Änderungen ausprobiert:
- Vertexformat wie oben
- Sichtweite der Kamera auf 5000.0f gesetzt
- Zufallige Verteilung der Würfel auf 10.0f, 40.0f gesetzt
- Abschwächung des Lichts (Attenuation1) auf 0.0025f gesetzt

Dann funktionierts mit Licht (leidlich...) :)

5

29.01.2008, 10:06

Ja, so funktioniert es.
Hat wohl hauptsächlich an dem verqueren Vertexformat gelegen.

Tja, dann, danke ^^

Werbeanzeige