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

Nahdar

Frischling

  • »Nahdar« ist der Autor dieses Themas

Beiträge: 36

Wohnort: Köln

Beruf: Student

  • Private Nachricht senden

1

17.04.2012, 23:20

Normalenvektor eines unebenen Terrains!

Hallo Leute,
eure lieblingsnervensäge Nahdar ist wieder da...

Also ich habe nun alles ins Spiel eingebunden, ich vermute nun , dass ich mein Terrain nicht sehe, weil das Licht nicht ordentlich auf das Terrain scheint:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
// Richtungslicht mit der Richtung der Kamera erstellen und aktivieren
    ZeroMemory(&CamLight, sizeof(D3DLIGHT9));
    CamLight.Type = D3DLIGHT_DIRECTIONAL;
    CamLight.Diffuse = tbColor(1.0f, 1.0f, 1.0f);
    CamLight.Specular = tbColor(1.0f, 1.0f, 1.0f);
    CamLight.Direction = vCameraLookAt - vCameraPos;
    D3D->SetLight(0, &CamLight);
    D3D->LightEnable(0, TRUE);

    // Hintergrundbeleuchtung
    D3D.SetRS(D3DRS_AMBIENT, tbColor(1.0f, 1.0f, 1.0f));


Das sind meine Werte für das Licht. Allerdings muss ich für die CamLight.Direction den Normalenvektor meines Terrains angeben , der sich aus folgendem zusammensetzt:

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
// Rückruffunktion für die Vertexposition

    tbVector3 PositionProc(tbVector3 v)
    {
        float fHeight;
        float randomValue = rand()%1+1; //Randomfunktion für die Bestimmung der Höhe!

        fHeight = (sinf(v.x * 0.2f +randomValue * 3.0f) * cosf(v.z * 0.2f + randomValue * 3.0f)) *
                sinf(randomValue + v.x * 0.1f + v.z * 0.1f) * 2.0f +
                sinf(randomValue) * 0.5f;

// Positionsvektor liefern
        return tbVector3(v.x, fHeight, v.z);
    }


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

// Rückruffunktion für den Vertexnormalenvektor
    tbVector3 NormalProc(tbVector3 v)
    {
        tbVector3 m;

        // Steigung berechnen
        m.x = (PositionProc(v + tbVector3(0.01f, 0.0f, 0.0f)).y - PositionProc(v).y) / 0.01f;
        m.z = (PositionProc(v + tbVector3(0.0f, 0.0f, 0.01f)).y - PositionProc(v).y) / 0.01f;

        // In Normalenvektor umwandeln
        return tbVector3Cross(tbVector3Normalize(tbVector3(1.0f, m.x, 0.0f)),
                            tbVector3Normalize(tbVector3(0.0f, m.z, 1.0f)));
    }

// ******************************************************************
// Rückruffunktion für die Texturkoordinaten
    tbVector2 TextureProc(tbVector3 v)
    {
        return tbVector2(v.x * 0.01f + sinf(0 * 0.1f),
                        v.z * 0.01f + cosf(0 * 0.1f));
    }


Der Normalenvektor tbVector3Cross funktioniert hier leider nicht als einfache Parameterübername, ich weiss das ich das ich das Kreuzprodukt der Vektoren der ebene benötige, aber da fehlt mir der Ansatz..
Soll ich im bereits erstellten Terrain einfach noch ein 6x6 großes Feld erzeugen , anhand dessen ich einen Normalenvektor erzeuge oder was schlagt ihr vor?

Mfg

Sp3iky

Treue Seele

Beiträge: 232

Beruf: Entwicklungsingenieur

  • Private Nachricht senden

2

18.04.2012, 10:04

Zunächst mal, schau dir bitte die Grundlagen zum Phong Shading an. Deine Werte für das Licht bzw. die ambiente Beleuchtung lassen darauf schließen, dass du nicht genau weißt, welche Werte da drin stehen müssen. Im Moment wäre bei dir alles komplett weiß, da der ambiente Anteil weiß ist.

Daher vermute ich auch, dass deine Vermutung nicht richtig ist. Selbst bei falschen Normalen solltest du das Terrain sehen können. Die Normale wird eigentlich auch korrekt berechnet, soweit ich das sehen kann. Zumindest ist es korrekt über die lokalen Ableitungen in x- und y-Richtung die Normale zu extrahieren.

Hast du die Kameraposition verändert? Eine andere Variante wäre, dass die Skalierung des Terrains irgendwie nicht hin haut oder es eben nicht korrekt gezeichnet wird.

Nahdar

Frischling

  • »Nahdar« ist der Autor dieses Themas

Beiträge: 36

Wohnort: Köln

Beruf: Student

  • Private Nachricht senden

3

18.04.2012, 11:10

Zunächst mal, schau dir bitte die Grundlagen zum Phong Shading an. Deine Werte für das Licht bzw. die ambiente Beleuchtung lassen darauf schließen, dass du nicht genau weißt, welche Werte da drin stehen müssen. Im Moment wäre bei dir alles komplett weiß, da der ambiente Anteil weiß ist.

Daher vermute ich auch, dass deine Vermutung nicht richtig ist. Selbst bei falschen Normalen solltest du das Terrain sehen können. Die Normale wird eigentlich auch korrekt berechnet, soweit ich das sehen kann. Zumindest ist es korrekt über die lokalen Ableitungen in x- und y-Richtung die Normale zu extrahieren.

Hast du die Kameraposition verändert? Eine andere Variante wäre, dass die Skalierung des Terrains irgendwie nicht hin haut oder es eben nicht korrekt gezeichnet wird.

Das letztere trifft zu... also das es wohl gar nicht gezeichnet wird. es wird bei der initialisierung einfach übergangen... nun stehe ich da.. sorry, da fehlen mir die basics.. kann mir einer sagen an welcher stelle des spiels breakanoid , ich die initialisierung des Terrains legen soll damit das auch richtig gerendert wird. Auf wunsch poste ich auch den mega langen code dazu ..

Nahdar

Frischling

  • »Nahdar« ist der Autor dieses Themas

Beiträge: 36

Wohnort: Köln

Beruf: Student

  • Private Nachricht senden

4

18.04.2012, 11:33

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
// Lädt den Spielzustand
tbResult CGame::Load()
{
// Terrain laden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //m_terrain = new CTerrain;
    //m_terrain->CreateTerrain();
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


in diesem Teilabschnitt sollte das Ganze stattfinden.
allerdings bin ich gerade zu blöd, mich für den Variablentyp zu entscheiden.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

5

18.04.2012, 12:09

Wie du kannst dich nicht für den Variablentyp entscheiden? Was soll in der Variable denn gespeichert werden? Das sollte dir den Typ doch schon vorgeben. Vermutlich hast du das Buch bis zum Spiel zu schnell durchgearbeitet oder vielleicht sogar nur gelesen. Dabei lernt man nicht viel und bekommt solche Probleme. Wenn dich der Bereich wirklich interessiert, dann solltest du dir das Buch noch mal greifen und noch mal ordentlich durcharbeiten. Die Sachen auch ausprobieren und anwenden. Viele fangen jedoch an wie du und beschäftigen sich mit DirectX oder OpenGL und möchten eigentlich einfach Spiele machen. Da ist es oft einfacher eine fertige Engine zu benutzen. Ich habe selbst so angefangen, wobei ich sagen muss, dass mir Davids Buch einige Grundlagen beigebracht hat und ein tieferes Verständnis für dass, was da eigentlich passiert gegeben hat.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Nahdar

Frischling

  • »Nahdar« ist der Autor dieses Themas

Beiträge: 36

Wohnort: Köln

Beruf: Student

  • Private Nachricht senden

6

18.04.2012, 12:18

Ich habe echt leider keine Zeit mehr dazu..
Ich schicke einfach mal den Code: Tut mir Leid.

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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
/*
**  BREAKANOID
**  ==========
**
**  Game.cpp
**  --------
**  Das Spiel
*/
// math um PI nutzen zu können. Wichtig für die Default-Kameraeinstellungen.
#define _USE_MATH_DEFINES
#include <math.h>
#include "Breakanoid.h"




// ******************************************************************
//
//tbResult CTerrain::CreateTerrain(void) {

//return TB_OK;
//}
// Vektor aus dem Terrain generiert wird
// __________________________________________________________________
struct STerrainVertex
{
    tbVector3           vPosition;  // Position
    tbVector3           vNormal;    // Normalenvektor
    tbVector2           vTexture;   // 2D-Texturkoordinaten
    static const DWORD  dwFVF;      // Vertexformat
};
const DWORD STerrainVertex::dwFVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

tbResult CTerrain::CreateTerrain(void) 
{
    //tbWriteToLog("%s","Enter  CTerrain::CreateTerrain");
    m_pTerrainVB = NULL;
    m_pTerrainIB = NULL;

    // g_Config;                    // Konfigurationsstruktur
    g_pWaterTexture = NULL;     // Wassertextur
    g_pWaterEffect = NULL;      // Wassereffekt
    g_pWaterVB = NULL;          // Wasser-Vertex-Buffer
    g_pWaterIB = NULL;          // Wasser-Index-Buffer
    g_iResolution = 64;         // Die Auflösung der Wasseroberfläche
    g_fTime = 0.0f;             // Globaler Zeitzähler


    InitTerrain();
    UpdateWater();
    int vvvv = 0;
    return TB_OK;
}

// ******************************************************************
// Die Move-Funktion
tbResult CTerrain::MoveProc(float fNumSecsPassed)
{
    return TB_OK;
}

// ******************************************************************
// Diese Funktion liefert den Index eines Vertex zurück, der durch
// seine Position im Gitter angegeben wird.
WORD CTerrain::GetVertexIndex(WORD x,
                    WORD y)
{
    return y * g_iResolution + x;
}

// ******************************************************************
// Rückruffunktion für die Vertexposition
tbVector3 CTerrain::PositionProc(tbVector3 v)
{
    float fHeight;

    // Die Höhe berechnet sich mit verschiedenen Sinusfunktionen,
    // die abhängig von der Position des Vertex und abhängig von der Zeit sind.
    
    
    fHeight = (sinf(v.x * 0.2f + g_fTime * 3.0f) * cosf(v.z * 0.2f + g_fTime * 3.0f)) *
            sinf(g_fTime + v.x * 0.1f + v.z * 0.1f) * 2.0f +
              sinf(g_fTime) * 0.5f;
    
    // Positionsvektor liefern
    return tbVector3(v.x, fHeight, v.z);
}

// ******************************************************************
// Rückruffunktion für den Vertexnormalenvektor
tbVector3 CTerrain::NormalProc(tbVector3 v)
{
    tbVector3 m;

    // Steigung berechnen
    m.x = (PositionProc(v + tbVector3(0.01f, 0.0f, 0.0f)).y - PositionProc(v).y) / 0.01f;
    m.z = (PositionProc(v + tbVector3(0.0f, 0.0f, 0.01f)).y - PositionProc(v).y) / 0.01f;

    // In Normalenvektor umwandeln
    return tbVector3Cross(tbVector3Normalize(tbVector3(1.0f, m.x, 0.0f)),
                          tbVector3Normalize(tbVector3(0.0f, m.z, 1.0f)));
}

// ******************************************************************
// Rückruffunktion für die Texturkoordinaten
tbVector2 CTerrain::TextureProc(tbVector3 v)
{
    return tbVector2(v.x * 0.01f + sinf(g_fTime * 0.1f),
                    v.z * 0.01f + cosf(g_fTime * 0.1f));
}

// ******************************************************************
// Diese Funktion aktualisiert die Wasseroberfläche.
tbResult CTerrain::UpdateWater()
{
    // tbWriteToLog("%s","Enter   CTerrain::UpdateWater");
    STerrainVertex  Vertex;
    tbVector3       vPosition;

    // tbWriteToLog("%s","=========Start===========");
    // Jeden Vertex durchgehen
    for(WORD x = 0; x < g_iResolution; x++)
    {
        // tbWriteToLog("%s","=========Start y===========");
        for(WORD y = 0; y < g_iResolution; y++)
        {
            // Den Vertex generieren. Dazu wird die Position des Vertex berechnet
            // und dann als Parameter für die verschiedenen Rückruffunktionen verwendet.
            vPosition.x = ((float)(x) / (float)(g_iResolution - 1) - 0.5f) * 200.0f;
            vPosition.y = 0.0f;
            vPosition.z = ((float)(-y) / (float)(g_iResolution - 1) + 0.5f) * 200.0f;

            // Rückruffunktionen aufrufen
            Vertex.vPosition = PositionProc(vPosition);
            Vertex.vNormal = NormalProc(vPosition);
            Vertex.vTexture = TextureProc(vPosition);

            // Den Vertex setzen
            g_pWaterVB->SetVertex(GetVertexIndex(x, y), &Vertex);
        }
        // tbWriteToLog("%s","=========End y===========");
    }
    // tbWriteToLog("%s","=========End===========");

    // Den Vertex-Buffer aktualisieren
    if(g_pWaterVB->Update()) return TB_ERROR;

    // tbWriteToLog("%s","Exit   CTerrain::UpdateWater");
    return TB_OK;
}
// ******************************************************************
// Die Render-Funktion
tbResult CTerrain::RenderProc()
{
    // tbWriteToLog("%s","Enter   CTerrain::RenderProc");
    tbMatrix    mProjection;
    tbMatrix    mCamera;
    tbMatrix    mWorld;
    tbVector3   vCamera;
    D3DLIGHT9   CamLight;
    int         iNumPasses;
    
    // Die Szene beginnen
    tbDirect3D& D3D = tbDirect3D::Instance();
    //D3D->BeginScene();
    // ------------------------------------------------------------------
    
    
    // tbMatrixProjection(sichtfeld, bildseitenverhältnis, nahe clippingebene, entfernte clippingebene)
    D3D.SetTransform(D3DTS_PROJECTION, tbMatrixProjection(TB_DEG_TO_RAD(90.0f), D3D.GetAspect(), 0.1f, 100.0f));

    // kameramatrix
    D3D.SetTransform(D3DTS_VIEW, tbMatrixCamera(tbVector3(0.0f, 10.0f, -10.0f), tbVector3(0.0f, 0.0f, 0.0f), tbVector3(0.0f, 1.0f, 0.0f)));
    
    // Richtungslicht mit der Richtung der Kamera erstellen und aktivieren
    ZeroMemory(&CamLight, sizeof(D3DLIGHT9));
    CamLight.Type = D3DLIGHT_DIRECTIONAL;
    CamLight.Diffuse = tbColor(1.0f, 1.0f, 1.0f);
    CamLight.Specular = tbColor(1.0f, 1.0f, 1.0f);
    CamLight.Direction = tbVector3(0.0f, 0.0f, 0.0f) - tbVector3(0.0f, 10.0f, -10.0f);
    D3D->SetLight(0, &CamLight);
    D3D->LightEnable(0, TRUE);
    
    // ------------------------------------------------------------------

    // Weltmatrix zurücksetzen
    D3D.SetTransform(D3DTS_WORLD, tbMatrixIdentity());

    // Texturen setzen
    D3D.SetTexture(0, g_pWaterTexture);
    // D3D.SetTexture(1, g_pEnvMap);

    // Datenquellen und Vertexformat setzen
    D3D->SetStreamSource(0, g_pWaterVB->GetVB(), 0, sizeof(STerrainVertex));
    D3D->SetIndices(g_pWaterIB->GetIB());
    D3D.SetFVF(STerrainVertex::dwFVF);

    // Zeichnen!    
    iNumPasses = g_pWaterEffect->Begin();
    for(int iPass = 0; iPass < iNumPasses; iPass++)
    {
        g_pWaterEffect->Pass(iPass);
        D3D->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0,
                                g_iResolution * g_iResolution, 0,
                                  (g_iResolution - 1) * (g_iResolution - 1) * 2);
    }

    g_pWaterEffect->End();
    
    // ------------------------------------------------------------------

    return TB_OK;
}

// ******************************************************************
// Initialisierung der Terrainfläche
tbResult CTerrain::InitTerrain()
{
    int     iNumVertices;
    int     iNumIndices;
    WORD    wIndex;


    // Vertex- und Index-Buffer erstellen. 8 Vertizes, 36 Indizes.
    // Der Vertex-Buffer soll dynamisch sein.
    // Die Anzahl der benötigten Vertizes ist die Auflösung zum Quadrat.
    iNumVertices = g_iResolution * g_iResolution;

    // Dynamischen Vertex-Buffer erstellen
    g_pWaterVB = new tbVertexBuffer;
    if(g_pWaterVB->Init(iNumVertices * sizeof(STerrainVertex), sizeof(STerrainVertex), STerrainVertex::dwFVF,
                        D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DPOOL_DEFAULT))
    {
        // Fehler!
        return TB_ERROR;
    }

    // Index-Buffer erstellen.
    // Die Anzahl der Vierecke ist g_iNumVertices minus 1 zum Quadrat.
    // Wir brauchen 6 Indizes pro Viereck.
    iNumIndices = (g_iResolution - 1) * (g_iResolution - 1) * 6;

    // Puffer erstellen mit 16 Bits pro Index (WORD)
    g_pWaterIB = new tbIndexBuffer;
    if(g_pWaterIB->Init(iNumIndices * sizeof(WORD), sizeof(WORD), D3DFMT_INDEX16))
    {
        // Fehler!
        return TB_ERROR;
    }

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

    // Den Index-Buffer können wir jetzt schon initialisieren, denn er ist
    // ja statisch. Dazu gehen wir alle Vertizes (außer denen, die am Rand liegen)
    // durch und erstellen ein Viereck, bei denen der Vertex links oben liegt.
    for(int x = 0; x < g_iResolution - 1; x++)
    {
        for(int y = 0; y < g_iResolution - 1; y++)
        {
            // Erstes Dreieck erzeugen, bei dem der Vertex (x, y) links oben ist
            // (x,y) _______ (x+1,y)
            //   1   |  /   2
            //      |   /
            //      |   /
            //      |  /
            //      | /
            //      |/
            //  (x,y+1)
            //  3
            wIndex = GetVertexIndex(x, y);      g_pWaterIB->AddIndex(&wIndex);
            wIndex = GetVertexIndex(x + 1, y);  g_pWaterIB->AddIndex(&wIndex);
            wIndex = GetVertexIndex(x, y + 1);  g_pWaterIB->AddIndex(&wIndex);

            // Zweites Dreieck
            wIndex = GetVertexIndex(x, y + 1);      g_pWaterIB->AddIndex(&wIndex);
            wIndex = GetVertexIndex(x + 1, y);      g_pWaterIB->AddIndex(&wIndex);
            wIndex = GetVertexIndex(x + 1, y + 1);  g_pWaterIB->AddIndex(&wIndex);
        }
    }

    // Den Index-Buffer aktualisieren
    if(g_pWaterIB->Update()) return TB_ERROR;

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

    // Die Textur der Wasseroberfläche laden
    
    g_pWaterTexture = tbTextureManager::Instance().GetTexture("Terrain0.jpg");
    if(g_pWaterTexture == NULL) return TB_ERROR;

    // Effekt laden
    
    g_pWaterEffect = new tbEffect;
    if(g_pWaterEffect == NULL) return TB_ERROR;
    if(g_pWaterEffect->Init("Water.fx")) return TB_ERROR;
    

    return TB_OK;
}


// ******************************************************************
// Aufräumen
tbResult CTerrain::CleanUp()
{
    // Alles löschen
// **   tbDirect3D::Instance().Exit();
// **   tbTextureManager::Instance().Exit();
    TB_SAFE_DELETE(g_pWaterEffect);
    TB_SAFE_DELETE(g_pWaterVB);
    TB_SAFE_DELETE(g_pWaterIB);

    // Die TriBase-Engine herunterfahren
// **   tbExit();

    return TB_OK;
}


// __________________________________________________________________
// Initialisiert den Spielzustand
tbResult CGame::Init()
{
    // Laden...
    if(Load()) TB_ERROR("Fehler beim Laden des Spielzustands!", TB_ERROR);

    // Ersten Level initialisieren
    InitLevel();

    // Default Kameraposition, PI um die Kamera einmal um 180° zu drehen und "hinter" der Kugel zu starten:
    relativeCamera = tbVector3((float)M_PI, 10.0f, (float)M_PI);

    return TB_OK;
}

// __________________________________________________________________
// Fährt den Spielzustand herunter
tbResult CGame::Exit()
{
    // Entladen...
    Unload();

    return TB_OK;
}

// __________________________________________________________________
// Lädt den Spielzustand
tbResult CGame::Load()
{
// Terrain laden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
    m_terrain = new CTerrain;
    m_terrain->CreateTerrain();
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


// Ballmodell laden
    m_pBallModel = new tbModel;
    if(m_pBallModel->Init("Data\\Ball.tbm", "Data\\")) TB_ERROR("Fehler beim Laden des Ballmodells!", TB_ERROR);

    return TB_OK;
}

// __________________________________________________________________
// Entlädt den Spielzustand
tbResult CGame::Unload()
{
    // Alle Modelle freigeben
    TB_SAFE_DELETE(m_pLevelModel);
    TB_SAFE_DELETE(m_pBallModel);
    //TB_SAFE_DELETE(m_terrain);
    return TB_OK;
}

// __________________________________________________________________
// Bewegt den Spielzustand
tbResult CGame::Move(float fTime)
{
    // P oder Pause hält das Spiel an oder setzt es fort.
    if(g_pbButtons[TB_KEY_P] || g_pbButtons[TB_KEY_PAUSE])
    {
        m_bPaused = !m_bPaused;
        tbDelay(100);
    }

    // Wenn das Spiel pausiert, gibt es nichts mehr zu tun.
    if(m_bPaused) return TB_OK;


    // Das "Kleben" abschalten - wir haben keinen Schläger mehr, also haben wir auch keine klebenden Bälle mehr.
    Ball.m_bGrabbed = FALSE;

    Ball.m_vVelocity.x += g_pfButtons[TB_KEY_RIGHT] * 20.0f * fTime;
    Ball.m_vVelocity.x -= g_pfButtons[TB_KEY_LEFT] * 20.0f * fTime;
    Ball.m_vVelocity.z += g_pfButtons[TB_KEY_UP] * 20.0f * fTime;
    Ball.m_vVelocity.z -= g_pfButtons[TB_KEY_DOWN] * 20.0f * fTime;
    
    
    /* Die Bewegung abschwächen (80% Verlust pro Sekunde)
     Grund: Die Kontrolle über den Ball ist stark erschwert, da der Bewegungsvektor durch die normalen Funktionen der Klasse CBall sehr stark beeinflusst wird.
     Deswegen schwächen wir die Bewegung einfach insgesamt ab.
     Dies ermöglicht zugleich auch bessere Kontrolle wenn viele Bälle gleichzeitig auf dem Feld sind. */

    Ball.m_vVelocity.x *= powf(0.2f, fTime);
    Ball.m_vVelocity.z *= powf(0.2f, fTime);
    Ball.m_vVelocity.y *= powf(0.2f, fTime);

    Ball.Move(fTime);



    // Kameraposition auf Wunsch verändern.
    // Drehen um die Kugel
    relativeCamera.x += g_pfButtons[TB_KEY_D] * 1.0f * fTime;
    relativeCamera.z += g_pfButtons[TB_KEY_D] * 1.0f * fTime;

    relativeCamera.x -= g_pfButtons[TB_KEY_A] * 1.0f * fTime;
    relativeCamera.z -= g_pfButtons[TB_KEY_A] * 1.0f * fTime;

    // Höhe Verändern
    relativeCamera.y += g_pfButtons[TB_KEY_S] * 10.0f * fTime;
    relativeCamera.y -= g_pfButtons[TB_KEY_W] * 10.0f * fTime;

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

    // Wenn die Escape-Taste gedrückt wird, geht's zurück ins Hauptmenü.
    if(g_pbButtons[TB_KEY_ESCAPE]) g_pBreakanoid->SetGameState(GS_INTRO);

    return TB_OK;
}

// __________________________________________________________________


    // Rendert den Spielzustand
    tbResult CGame::Render(float fTime)
    {
    tbMatrix    mCamera;
    tbMatrix    mProjection;
    tbVector3   vCameraPos;
    tbVector3   vCameraLookAt;
    D3DLIGHT9   CamLight;
    tbVector3   vPosition;
    float       y;

    // Puffer leeren und Szene beginnen
    tbDirect3D& D3D = tbDirect3D::Instance();
    D3D->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, tbColor(0.0f, 0.0f, 0.0f), 1.0f, 0);
    D3D->BeginScene();

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

    // Die Kameraposition:
    vCameraPos.x = Ball.GetAbsPosition().x + 10.0f*sinf(relativeCamera.x);
    vCameraPos.y = Ball.GetAbsPosition().y + relativeCamera.y;
    vCameraPos.z = Ball.GetAbsPosition().z + 10.0f*cosf(relativeCamera.z);

    // Fokus der Kamera auf den Ball
    vCameraLookAt = Ball.GetAbsPosition();

    // Kameramatrix erstellen und aktivieren
    mCamera = tbMatrixCamera(vCameraPos, vCameraLookAt);
    D3D.SetTransform(D3DTS_VIEW, mCamera);

    // Projektionsmatrix erstellen und aktivieren
    mProjection = tbMatrixProjection(TB_DEG_TO_RAD(70.0f),
                                    D3D.GetAspect(),
                                     0.1f, 500.0f);
    D3D.SetTransform(D3DTS_PROJECTION, mProjection);

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

    // Richtungslicht mit der Richtung der Kamera erstellen und aktivieren
    ZeroMemory(&CamLight, sizeof(D3DLIGHT9));
    CamLight.Type = D3DLIGHT_DIRECTIONAL;
    CamLight.Diffuse = tbColor(1.0f, 1.0f, 1.0f);
    CamLight.Specular = tbColor(1.0f, 1.0f, 1.0f);
    CamLight.Direction = vCameraLookAt - vCameraPos;
    D3D->SetLight(0, &CamLight);
    D3D->LightEnable(0, TRUE);

    // Hintergrundbeleuchtung
    D3D.SetRS(D3DRS_AMBIENT, tbColor(1.0f, 1.0f, 1.0f));

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

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

    // Höhe des Balls im Terrain ausrechnen
    //y = getHeightAtPosition(Ball.GetAbsPosition().x, Ball.GetAbsPosition().z);
    //Ball.m_vPosition.y = y;

    // Ball rendern
    Ball.Render(fTime);

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

    // Wenn das Spiel pausiert, wird "Pause" in der Bildmitte angezeigt.
    if(m_bPaused)
    {
        g_pBreakanoid->m_pFont1->Begin();
        g_pBreakanoid->m_pFont1->DrawText(tbVector2(0.5f, 0.5f), "Pause",
                                        TB_FF_ALIGN_HCENTER | TB_FF_ALIGN_VCENTER | TB_FF_RELATIVE | TB_FF_RELATIVESCALING);
        g_pBreakanoid->m_pFont1->End();
    }

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

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

    // Szene beenden
    D3D->EndScene();

    return TB_OK;
}

// __________________________________________________________________
// Initialisiert einen Level
tbResult CGame::InitLevel()
{
        
    // Sound für neuen Level abspielen
    //g_pBreakanoid->m_apSound[2]->PlayNextBuffer();

    // Neuen Level setzen
    m_bPaused = FALSE;
    m_bGameOver = FALSE;

    // Einen Ball erstellen
    CreateBall(tbVector3(200.0f, 10.0f, 200.0f), tbVector3(0.0f), FALSE);

    return TB_OK;
}

// __________________________________________________________________
// Erstellt einen neuen Ball
int CGame::CreateBall(tbVector3 vPosition,
                      tbVector3 vVelocity,
                      BOOL bGrabbed)
{


    Ball.m_bExists = TRUE;
    Ball.m_pGame = this;
    Ball.m_bGrabbed = bGrabbed;
    Ball.m_vPosition = vPosition;
    Ball.m_vVelocity = vVelocity;

    return 0;
}

// __________________________________________________________________


und zwar soll mit mit dem Ausdruck m_terrain = new CreateTerrain usw.. das Terrain ins Spiel eingelesen werden.. allerdings will es das nicht.
Und es tut mir Leid.. ich habe eine Abgabefrist.. ich würde mir gerne DANACH noch das Buch durchschauen und durcharbeiten aber aktuell geht es nicht anders...
347-357 ist meine baustelle und von 1-300 ist die initialisierung..
MFG

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

7

18.04.2012, 12:43

Auch wenn du eine Abgabefrist hast werde ich dir sicherlich nicht die Aufgabe lösen;) Ich bestimmt 3 oder 4 Jahre nicht mehr ins Buch geguckt und weiß das auch nicht mehr Auswendig. Wenn es nur darum geht dich auf einem Terrain zu bewegen, dann nimm Unity. Damit solltest du das innerhalb von nem Tag fertig haben(Ist nur geschätzt). Ansonsten hilft dir vielleicht auch Irrlicht weiter. Da sollte es direkt möglich sein ein Terrain zu laden und Kollision müsste dafür soweit ich weiß auch schon direkt fertig sein.
Ob du das Buch jemals richtig lesen wirst ist mir relativ egal;) Ob du was lernen möchtest und wie sehr es dich interessiert ist ja deine Sache. Wenn das Terrain nicht geladen wird gebe ich dir den Tipp einen Breakpoint vorher zu setzen und das Programm zu debuggen. Einfach Schritt für Schritt die durchgehen und gucken wo es fehlschlägt. Wenn es bei der Funktion zum laden passiert, sollte etwas im Logfile stehen. Was du mit der Variable meinst weiß ich jetzt immer noch nicht. Wenn es dir darum geht, dass Model zu speichern, dann sollte es eine Model-Klasse geben. tbModel heisst die glaube ich in dem Fall. Habe aber auch nicht mehr im Kopf wie das Spiel aufgebaut war und habe selbst nicht die Zeit und vor allem nicht die Lust das alles zu lesen und durchzuarbeiten.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Sp3iky

Treue Seele

Beiträge: 232

Beruf: Entwicklungsingenieur

  • Private Nachricht senden

8

18.04.2012, 13:05

Ich glaube mit der Einstellung wirst du hier nicht weiter kommen. Ich habe auch Abgabefristen und wenig Lust auf so manches, was ich erledigen muss. Ich mach es trotzdem. Du wirst hier niemanden finden, der dir fertigen Code gibt, außer du bietest vielleicht eine Bezahlung an. Dann würde ich aber auch nicht dafür garantieren.

Das Leben ist hart, ich weiß...aber manchmal muss man sich eben durchkämpfen oder sich eingestehen, dass man es halt nicht immer schafft. Andere die Arbeit machen lassen ist auf jeden Fall der falsche Weg.

Nahdar

Frischling

  • »Nahdar« ist der Autor dieses Themas

Beiträge: 36

Wohnort: Köln

Beruf: Student

  • Private Nachricht senden

9

18.04.2012, 13:13

Ich sitze hier seit mehreren Tagen mit 2 Büchern , darunter ein Basic-Buch und das von dem Herrn Scherfgen. Ich habe die letzten Tage mehr als 35 Stunden nur mit dem Code verbracht.. so wie letzte Nacht auch z.B. bis 5 und heute um 9 raus.. es ist nicht so , dass ich mich hier hinsetze und sage.. "so macht mal für mich" sorry wenn es so rüber kommt. Ich seh einfach nicht den Fehler..
ich weiss, das mein Spiel nicht initialisiert wird.. und ich wollte das über die Methode CreateTerrain aufrufen.. allerdings braucht er dafür die Variable für m_terrain.. ich bin alle Variablen durchgangen zum Teil mit Trial and Error... und dennoch .. nichts.. ich sitze seit Stunden davor.. und ihr behauptet ich habe keine Lust?
Ich suche und suche und suche und finde NICHTS... sorry..
Ich wollte nicht das ihr meinen Code überarbeitet, eher wie:
Teil mal das Terrain beispiel in die jeweiligen Stellen des Breakanoid spiels ein .. oder : Lagere das mal in eine eigene Cpp und h , was ich übrigens schon hatte... war dann aber nicht in der lage die iniitialisierung aufzurufen.. ich habe einiges gemacht und scheitere einfachgerade an banalen dingen und hoffte (!!!) das ihr mir helfen könnt..

Korrektur: Ich sitze seit mehreren Tagen nur an dem Terrain...

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Nahdar« (18.04.2012, 13:21)


Sp3iky

Treue Seele

Beiträge: 232

Beruf: Entwicklungsingenieur

  • Private Nachricht senden

10

18.04.2012, 13:49

Naja ich sitze auch seit 2 Wochen täglich an einem Projekt bei dem Morgen Abgabe ist und ich werde noch die ganze Nacht dran sitzen. Ich sag ja das Leben ist hart.

Ich weiß ja nicht, wie du zu dieser Aufgabe gekommen bist, aber für mich klingt es einfach so, als würdest du gerade angefangen haben zu programmieren und versuchst jetzt mal so schnell nebenbei Crysis nachzubauen (etwas überspitzt dargestellt).

Es scheint einfach, als fehlten dir ein Großteil der Grundlagen. Sonst würdest du nicht per Trail and Error versuchen irgendwelche Variablentypen in irgend eine Funktion zu stecken. Hier fehlt es an Grundverständnis und das können wir dir auch nicht per Ferndiagnose mal schnell vermitteln. Jeden nützlichen Tipp, den wir dir geben, kannst du zum Großteil gar nicht verstehen (siehe Debugger nutzen).

So hart wie es klingt, aber entweder hast du mit der Aufgabe zu spät angefangen und den Aufwand unterschätzt, oder man hat von dir mehr Vorwissen erwartet und du hast nichts dagegen gesagt.

Werbeanzeige