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

Anonymous

unregistriert

1

03.01.2005, 19:56

wie bekomme ich "Nebel"?

Hallo... habe mir jetzt das relativ kurze Kapitel über Nebel durchgelesen und wollte es gleich mal testen.

Allerdings:

C-/C++-Quelltext

1
2
3
4
5
6
g_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_FOGVERTEXMODE,D3DFOG_EXP);
g_pD3DDevice->SetRenderState(D3DRS_FOGCOLOR, g_pVertices[0].dwColor);
g_pD3DDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
g_pD3DDevice->SetRenderState(D3DRS_FOGDENSITY,0.9f);
g_pD3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, TRUE);


selbst bei einer Dichte von 0.9f sehe ich ÜBERHAUPT garkeinen Nebel... ich habe schon alle möglichen Farben eingesetzt (hier im Code eine Farbe aus einem Vertex (Zufallsfarben)) und sie als DWORD, float oder sogar int-Wert übergeben. Gleiches gilt für die Dichte.
Was mache ich falsch? Muß ich außer die RenderStates setzen noch irgend etwas machen? oder kann es an meiner GraKa / Hardware liegen? (GiForce4 Ti 4200)

Das Beispielprogramm ist leider mit den vielen Knöpfen etc etwas unübersichtlich...

Anonymous

unregistriert

2

03.01.2005, 22:49

habe jetzt erstmal weitergelesen und bin schon wieder auf etwas gestoßen, was mir nicht ganz gelingen will:

Direkt im nächsten Abschnitt werden Lichtquellen + Materiallien erklärt.

Allerdings arbeitet das Beispiel schon mit einer X-Datei und daher mangelt es leider an einem Beispiel für den korrekten Umgang mit NormalVektoren und mit den Indizen für harte / weiche Kanten, was bei mir so endet das meine "Lichtquelle" (wohl wegen falschen oder nicht vorhandenen NormalVectoren) alles dunkel macht.

Wäre über ein Codebeispiel sehr erfreut, danke :)

3

04.01.2005, 15:27

so, hab mich jetzt auch nochmal angemeldet :)

ich poste hier einmal den Code meiner Render-Funktion und der InitSzene-Funktion... und noch mein Vertex-Struct und die public Variablen... evtl findet wer den Fehler:
(ich wette es sind 5-10 total dumme Sachen, die ich wieder mal net seh :D)

//edit: die Kommentare sind nicht immer aktuell
//edit2: untem im Code steht "g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);" ... das steht nur auf FALSE, damit ich noch etwas sehe... zum Testen ob das Licht klappt stelle ich es logischer Weise immer wieder auf TRUE

der ganze public Teil:

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
struct SVertex
{
    tbVector3           vPosition;  // Position des Vertex

    tbVector3           vNormal;    // Normalvector

    tbVector2           vTexture;   // Texturkoordinaten

    static const DWORD  dwFVF;      // Vertexformat

};

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

// ******************************************************************

// Globale Variablen

const int               g_iNumCubes = 2048;             // Anzahl der Würfel

tbVector3               g_vCubeSpeed[g_iNumCubes];      // Geschwindigkeit des Würfels

float                   g_fTime = 0.0f;                 // Zeitzähler

SDirect3DParameters     g_Direct3DParameters;           // Direct3D-Parameter

PDIRECT3DTEXTURE9       g_pTexture = NULL;              // Die Textur

PDIRECT3DVERTEXBUFFER9  g_pVertexBuffer = NULL;         // Vertex-Buffer

PDIRECT3DINDEXBUFFER9   g_pIndexBuffer = NULL;          // Index-Buffer

tbVector3               g_vCameraPosition;              // Die Kameraposition

float                   g_fCameraAngle = 0.0f;          // Drehwinkel der Kamera

float                   g_fFOV = TB_DEG_TO_RAD(90.0f);  // Sichtfeld

SVertex*                g_pVertices;
DWORD                   g_dwFogColor = D3DCOLOR_XRGB(0, 0, 0);  // Die Nebelfarbe

float                   g_FogDensity = 0.05f;
float                   g_fCameraSpeed = 0.0f;


Render-Funktion:

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

    ZeroMemory(&Light, sizeof(D3DLIGHT9));

    Light.Type = D3DLIGHT_SPOT;
    Light.Diffuse = tbColor(1.0f, 1.0f, 1.0f);
    Light.Ambient = tbColor(1.0f, 1.0f, 1.0f);
    Light.Specular = tbColor(1.0f, 1.0f, 1.0f);
    Light.Position = tbVector3(0.0f, 0.0f, 20.0f);
    Light.Direction = tbVector3(sinf(fNumSecsPassed * 10), 0.0f, cosf(fNumSecsPassed * 10));
    Light.Range = 999.0f;
    Light.Attenuation0 = 1.0f;
    Light.Attenuation1 = 0.0f;
    Light.Attenuation2 = 0.0f;
    Light.Theta = 30.0f;
    Light.Phi = 40.0f;
    Light.Falloff = 1.0f;

    g_pD3DDevice->SetLight(0, &Light);
    g_pD3DDevice->LightEnable(0, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_AMBIENT, tbColor(0.25f, 0.0f, 0.0f));

    // Den Bildpuffer und den Z-Buffer leeren

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

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

    // Szene beginnen

    g_pD3DDevice->BeginScene();
    
    g_pD3DDevice->SetRenderState(D3DRS_FOGCOLOR, g_dwFogColor); 
    g_pD3DDevice->SetRenderState(D3DRS_FOGDENSITY,0.1f);
    

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


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


InitSzene:

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

    // Culling ausschalten, Dithering aktivieren

    g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    g_pD3DDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
    g_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP2);
    g_pD3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, 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),
                                                         D3DUSAGE_DYNAMIC,
                                                         SVertex::dwFVF,
                                                         D3DPOOL_DEFAULT,
                                                         &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**)(&g_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(20.0f, 250.0f);

        // Zufälliger Bewegungs-Vector des Würfels

        g_vCubeSpeed[iCube] = tbVector3Random();

        // 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.

        g_pVertices[iStartVertex + 0].vPosition = vCubePosition + tbVector3(-1.0f,  1.0f, -1.0f);
        g_pVertices[iStartVertex + 1].vPosition = vCubePosition + tbVector3(-1.0f,  1.0f,  1.0f);
        g_pVertices[iStartVertex + 2].vPosition = vCubePosition + tbVector3( 1.0f,  1.0f,  1.0f);
        g_pVertices[iStartVertex + 3].vPosition = vCubePosition + tbVector3( 1.0f,  1.0f, -1.0f);
        g_pVertices[iStartVertex + 4].vPosition = vCubePosition + tbVector3(-1.0f, -1.0f, -1.0f);
        g_pVertices[iStartVertex + 5].vPosition = vCubePosition + tbVector3(-1.0f, -1.0f,  1.0f);
        g_pVertices[iStartVertex + 6].vPosition = vCubePosition + tbVector3( 1.0f, -1.0f,  1.0f);
        g_pVertices[iStartVertex + 7].vPosition = vCubePosition + tbVector3( 1.0f, -1.0f, -1.0f);

        for(int iVertex = iStartVertex; iVertex < iStartVertex + 8; iVertex++)
        {
            // Texturkoordinaten generieren

            g_pVertices[iVertex].vTexture = tbVector2Random();
            g_pVertices[iVertex].vNormal = tbVector3Normalize(g_pVertices[iVertex].vPosition - vCubePosition);
        }

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

4

04.01.2005, 19:06

keiner ne Idee wos dran liegen könnte?

ich find den dummen Fehler einfach net :(

5

04.01.2005, 19:14

Hast du das neue oder das alte Buch? Kann ja mal Leherer spielen und dir deine Fehler sagen ;p

6

04.01.2005, 19:31

das wäre nett :)

habe die 2. Auflage

wenn der Zweck irgendeiner Variable ungeklärt ist, einfach nachfragen...

und die Normalvektoren werden glaube ich im meinem Beispiel so gesetzt, wie es für weiche Kanten sein müsste (sollten sie zumindest^^)

7

04.01.2005, 19:43

Re: wie bekomme ich "Nebel"?

C-/C++-Quelltext

1
2
3
4
5
6
g_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_FOGVERTEXMODE,D3DFOG_EXP);
g_pD3DDevice->SetRenderState(D3DRS_FOGCOLOR, g_pVertices[0].dwColor);
g_pD3DDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
g_pD3DDevice->SetRenderState(D3DRS_FOGDENSITY,0.9f);
g_pD3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, TRUE);

Zitat


g_pD3DDevice->SetRenderState(D3DRS_FOGCOLOR, g_pVertices[0].dwColor);

Versuch da mal

C-/C++-Quelltext

1
g_pD3DDevice->SetRenderState(D3DRS_FOGCOLOR, dwFogColor);

Oder hast de da nen besonderen Grundfür?

8

04.01.2005, 20:00

Zitat von »"CoB-Twister"«


C-/C++-Quelltext

1
2
3
4
5
DWORD   g_dwFogColor = D3DCOLOR_XRGB(0, 0, 0);  // Die Nebelfarbe


//***************************


g_pD3DDevice->SetRenderState(D3DRS_FOGCOLOR, g_dwFogColor);


der 1. Post ist ein bißchen veraltet... habe atm ne globale Variable für die Nebelfarbe (global, weil ich sie in der Move-Funktion später ändern muß)

(die Vertex-Farbe habe ich nur zum testen mal eingesetzt um zu testen ob meine Quelle defekt ist)

9

04.01.2005, 20:18

Ich muss zugeben das ich gerade denn Fehler nicht sofort finde, aber ich hab ne Idee: Du hast FOGENABLE in InitScene() geschrieben, schreib das mal stadt dessen in rendedr. Ich hab zwar nur die 1. Aulage des Buches aber da ist FOGENABLE in der Render Funktion. Was auch so richtig sein sollte, da du den Nebel ja sehen willst und der daher mit gerendertwerden muss. Bin mir aber nicht sicher. :o

10

04.01.2005, 20:33

habe jetzt folgende Sachen mit in die Render-Funktion gepackt:

g_pD3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_FOGTABLEMODE,3DFOG_NONE);
g_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_FOGVERTEXMODE,D3DFOG_EXP2);

(vor die Stelle, an der ich die Nebel-Farbe setze)

sieht aber immernoch alles gleich aus -> kein Nebel.

Werbeanzeige