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

01.04.2010, 17:35

Einfaches Würfelprogramm mit der TriBase-Engine

Hallo Leute,

Ich bin jetzt im Buch an den Punkt gekommen, wo Direct3D abgeschlossen ist und die TriBase-Engine "erweitert" wurde. Da dachte ich mir, da es keine Übungsaufgaben in Kapitel 3 gibt, stell ich mir selbst eine á la:
" Lassen Sie einen einfachen Würfel auf dem Bildschirm anzeigen mit den neuen Klassen der TriBase-Engine!"

Doch ganz so leicht stellte sich das ganze dann doch nicht heraus, der Bildschirm bleibt bei mir schwarz und es gibt (leider) keine Fehlermeldungen dafür.

Vielleicht findet ihr ja ein paar offensichtliche Fehler in meinem Amateur-Code(ja,leider ist es so):

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
// ******************************************************************
// tbWürfel - Ein Würfel mit Hilfe der TriBase-Engine

// ******************************************************************
// Header-Dateien
#include <TriBase.h>
#include "Resource.h"

// ******************************************************************
// Würfel-Vertex
struct SCubeVertex
{
    tbVector3           vPosition;  // Position
    tbVector3           vNormal;    // Normalenvektor
    tbVector2           vTexture;   // 2D-Texturkoordinaten
    static const DWORD  dwFVF;      // Vertexformat
};

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

// ******************************************************************
// Globale Variablen
tbConfig                g_Config;                   // Konfigurationsstruktur
PDIRECT3DTEXTURE9       g_pCubeTexture = NULL;      // Würfeltextur
tbEffect*               g_pCubeEffect = NULL;       // Würfeleffekt
tbVertexBuffer*         g_pCubeVB = NULL;           // Würfel-Vertex-Buffer
tbIndexBuffer*          g_pCubeIB = NULL;           // Würfel-Index-Buffer
float                   g_fTime = 0.0f;             // Globaler Zeitzähler

// ******************************************************************
// Die Move-Funktion
tbResult MoveProc(float fNumSecsPassed)
{
    // Den Zeitzähler aktualisieren
    g_fTime += fNumSecsPassed;

    return TB_OK;
}
// ******************************************************************
// Die Render-Funktion
tbResult RenderProc(float fNumSecsPassed)
{
    tbMatrix    mProjection;
    tbMatrix    mCamera;
    tbMatrix    mWorld;
    tbVector3   vCamera;
    int         iNumPasses;


    // Die Szene beginnen
    tbDirect3D& D3D = tbDirect3D::Instance();
    D3D->BeginScene();

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

    // Projektionsmatrix erstellen und einsetzen
    mProjection = tbMatrixProjection(TB_DEG_TO_RAD(90.0f), D3D.GetAspect(), 0.1f, 100.0f);
    D3D.SetTransform(D3DTS_PROJECTION, mProjection);

    // Kameramatrix erstellen und einsetzen.
    vCamera = tbVector3(0.0f,5.0f,5.0f);
    mCamera = tbMatrixCamera(vCamera, tbVector3(0.0f, 0.0f, 0.0f));
    D3D.SetTransform(D3DTS_VIEW, mCamera);

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

    // Textur setzen
    D3D.SetTexture(0, g_pCubeTexture);

    // Datenquellen und Vertexformat setzen
    D3D->SetStreamSource(0, g_pCubeVB->GetVB(), 0, sizeof(SCubeVertex));
    D3D->SetIndices(g_pCubeIB->GetIB());
    D3D.SetFVF(SCubeVertex::dwFVF);

    // Zeichnen!
    iNumPasses = g_pCubeEffect->Begin();
    for(int iPass = 0; iPass < iNumPasses; iPass++)
    {
        g_pCubeEffect->Pass(iPass);
        D3D->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0,
                                8, 0,
                                  12);
    }

    g_pCubeEffect->End();

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

    // Szene beenden
    D3D->EndScene();

    return TB_OK;
}

// ******************************************************************
// Initialisierung der Würfeloberfläche
tbResult InitCube()
{
    int         iNumVertices;
    int         iNumIndices;
    SCubeVertex aVertex[8];


    // Vertex- und Index-Buffer erstellen. 8 Vertizes, 36 Indizes.
    // Der Vertex-Buffer soll dynamisch sein.
    iNumVertices = 8;

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

    // Index-Buffer erstellen.
    iNumIndices = 36;

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

    // ------------------------------------------------------------------
    
    // Die Vertizes erstellen
    aVertex[0].vPosition = tbVector3(-1.0f,  1.0f,  1.0f);
    aVertex[1].vPosition = tbVector3( 1.0f,  1.0f,  1.0f);
    aVertex[2].vPosition = tbVector3( 1.0f,  1.0f, -1.0f);
    aVertex[3].vPosition = tbVector3(-1.0f,  1.0f, -1.0f);

    aVertex[4].vPosition = tbVector3(-1.0f, -1.0f,  1.0f);
    aVertex[5].vPosition = tbVector3( 1.0f, -1.0f,  1.0f);
    aVertex[6].vPosition = tbVector3( 1.0f, -1.0f, -1.0f);
    aVertex[7].vPosition = tbVector3(-1.0f, -1.0f, -1.0f);

    aVertex[0].vTexture = tbVector2(0.0f,0.0f);
    aVertex[1].vTexture = tbVector2(1.0f,0.0f);
    aVertex[2].vTexture = tbVector2(1.0f,0.0f);
    aVertex[3].vTexture = tbVector2(0.0f,0.0f);

    aVertex[4].vTexture = tbVector2(0.0f,1.0f);
    aVertex[5].vTexture = tbVector2(1.0f,1.0f);
    aVertex[6].vTexture = tbVector2(1.0f,1.0f);
    aVertex[7].vTexture = tbVector2(0.0f,1.0f);

    // Alle Vertizes eintragen und den Vertex-Buffer aktualisieren
    g_pCubeVB->AddVertices(8, aVertex);
    if(g_pCubeVB->Update()) return TB_ERROR;

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

    // Den Index-Buffer ausfüllen
    WORD awIndex[36] = {7, 3, 0,   4, 7, 0,     // Vorderseite
                        5, 1, 2,   6, 5, 2,     // Hinterseite
                        4, 0, 1,   5, 4, 1,     // Linke Seite
                        6, 2, 3,   7, 6, 3,     // Rechte Seite
                        2, 1, 0,   3, 2, 0,     // Oberseite
                        4, 5, 6,   7, 4, 6};    // Unterseite
    g_pCubeIB->AddIndices(36, awIndex);
    if(g_pCubeIB->Update()) return TB_ERROR;

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

    // Die Textur der Würfeloberfläche laden
    g_pCubeTexture = tbTextureManager::Instance().GetTexture("planks05.jpg");
    if(g_pCubeTexture == NULL) return TB_ERROR;

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

    return TB_OK;
}
// ******************************************************************
// Aufräumen
tbResult CleanUp()
{
    // Alles löschen
    tbDirect3D::Instance().Exit();
    tbTextureManager::Instance().Exit();
    TB_SAFE_DELETE(g_pCubeEffect);
    TB_SAFE_DELETE(g_pCubeVB);
    TB_SAFE_DELETE(g_pCubeIB);

    // Die TriBase-Engine herunterfahren
    tbExit();

    return TB_OK;
}
// ******************************************************************
// Windows-Hauptfunktion
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   char* pcCommandLine,
                   int iShowCommand)
{
    // TriBase-Engine initialisieren
    tbInit();

    // Konfiguration abfragen
    tbResult r;
    if(r = tbDoConfigDialog(&g_Config))
    {
        if(r == TB_CANCELED) return 0;
        else
        {
            // Fehler!
            MessageBox(NULL, "Fehler im Konfigurationsdialog!", "Fehler",
                    MB_OK | MB_ICONEXCLAMATION);
            return 1;
        }
    }

    // Direct3D initialisieren
    if(tbDirect3D::Instance().Init(&g_Config,
                                   "Beispielprogramm Nr. 1: tbDirect3D",
                                   NULL,
                                   LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1))))
    {
        // Fehler!
        MessageBox(NULL, "Fehler bei der Direct3D-Initialisierung!", "Fehler",
                MB_OK | MB_ICONEXCLAMATION);
        CleanUp();
        return 1;
    }

    // Den Texturmanager initialisieren
    if(tbTextureManager::Instance().Init())
    {
        MessageBox(tbDirect3D::Instance().GetWindow(), "Fehler beim Initialisieren des Texturmanagers!",
                "Fehler", MB_OK | MB_ICONEXCLAMATION);
        CleanUp();
        return 1;
    }

    // Das Wasser initialisieren
    if(InitCube())
    {
        MessageBox(tbDirect3D::Instance().GetWindow(), "Fehler beim Initialisieren des Würfels!",
                "Fehler", MB_OK | MB_ICONEXCLAMATION);
        CleanUp();
        return 1;
    }

    if(tbDoMessageLoop(MoveProc, RenderProc))
    {
        MessageBox(tbDirect3D::Instance().GetWindow(), "Fehler beim Zeichnen!",
                "Fehler", MB_OK | MB_ICONEXCLAMATION);
        CleanUp();
        return 1;
    }

    // Aufräumen
    CleanUp();

    return 0;
}

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


Und noch die Effekt-Datei:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
TECHNIQUE T1
{
    PASS T1
    {
        Lighting    = False;
        ColorOp[0]  = SelectArg1;
        ColorArg1[0]    = Texture;
    }
}


Ich hoffe ihr könnt mir helfen!

Euer 3d-Anfänger

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

2

01.04.2010, 20:42

Hat denn das mit dem Dreieck geklappt?
Wenn du das nicht ausprobiert hast, dann macht zuest das und dann erweitere es zu dem Würfel Programm.

Wahrscheinlich fehlt irgendein setting o.ä.

3

01.04.2010, 23:36

überprüfe doch mal, ob das culling richrig eingestellt ist, die kamera müsste den würfel nämlich irgendwie von hinten sehen.

4

02.04.2010, 10:22

So, das mit dem Culling hab ich ausprobiert, aber es ändert sich nichts.
Dreiecke hab ich auch schon viele gemacht, auch Würfel, aber ich wollte es mal mit den neuen Klassen ausprobieren (tbVertexBuffer, tbIndexBuffer,...
Ich finde, dass es immer sehr schwer ist einen kleinen Fehler in so einem langen Programm zu finden, besonders wenn es kein Tippfehler, sondern ein logischer Fehler ist.

Bis demnächst
Euer 3D-Anfänger

Edit: Ich hab die Kamera auch mal an andere Positionen gestellt (zb. auf der Z-Achse -5), dennoch ist nichts zu sehen.
Außerdem ist mit gerade aufgefallen, dass da auch noch Normalenvektorn in meinem FVF sind. Ich glaube nicht, dass es etwas damit zu tun hat, denn ohne sie passiert dasselbe (hab ich schon ausprobiert).

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »3D-Anfaenger« (02.04.2010, 10:33)


5

02.04.2010, 10:54

Ihr braucht euch nicht mehr anzustrengen!!

Es lag am leeren des Bild- und Z-Buffers, was man ja bei einer Umgebungstextur wie in dem Beispiel, wo ich das meiste herauskopiert habe, nicht brauchte. Doch bei meiner Aufgabe schon!

Trotzdem vielen Dank für die Anstrengungen,

Euer 3d-Anfänger

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

6

02.04.2010, 11:02

Ich finde, dass es immer sehr schwer ist einen kleinen Fehler in so einem langen Programm zu finden, besonders wenn es kein Tippfehler, sondern ein logischer Fehler ist.

ein 265zeilen programm ist für dich noch groß?
hast du bevor du mit 3d angefangen hast schon projekte in der konsole und in 2d umgesetzt?
würd ich dir dringend empfehlen.
es zählt auch nicht die größe des programms sondern wie stark du das problem eingrenzen kannst.
wenn du gut objektorientiert programmierst(was man können sollte bevor man sich an die kompilizierte 3d programmierung wagt) und in regelmäßigen abständen testest sollte die fehlersuche in den meisten fällen kein problem sein.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

7

02.04.2010, 11:32

es zählt auch nicht die größe des programms sondern wie stark du das problem eingrenzen kannst.
wenn du gut objektorientiert programmierst

Es ist weniger, dass man unbedingt OO programmieren muss, sondern eher, dass man Abstraktion sinnvoll einsetzt. Man teilt Aufgabenbereiche korrekt ein und man weiss daher dann immer recht genau, wo etwas schief läuft.

8

02.04.2010, 15:42

Ja, das stimmt schon, aber bei diesem Problem hätte mir die Objektorientiertheit nicht so viel geholfen. Ansonsten habt ihr natürlich Recht.
Doch was könnte man denn alles so an Konsolenanwendungen schreiben? Als ich C++ gelernt habe, da habe ich so Dinge wie verkettete Listen oder binäre Bäume als, nun ja, größere Projekte angesehen. In die Richtung gehen dann doch wahrscheinlich auch andere Konsolenanwendung, oder?

Euer 3d-Anfänger

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

9

02.04.2010, 17:48

mein einziges "größeres" konsolenprojekt war zum beispiel ein programm das das ein-mal-eins und quadradzahlen abgefragt hat. dafür hab ich eine klasse genommen die eine liste mit sagen wir 10 aufgaben gemacht hat. beim abfragen der ergebnisse wurden bei einer falschen lösung die aufgaben ans ende der liste gestellt.
mein erstes 2d game(mit c++) war tetris mit der sdl(wobei die sfml wohl eine bessere wahl für mich gewesen wäre)
mein allererstes 2d spiel war eine frühe version davon. in meinen augen das beste für einen 2d anfänger.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

10

02.04.2010, 22:18

Man kann z.b. Tetris oder Snake als Konsolenprogramm realisieren. So als erster Gedanke. Wenn du das ganze schön haben willst empfehle ich dir die Improved Console mal anzuschauen (ist sehr klein und schick). http://www.c-plusplus.de/code/ic/index.php



Vielleicht kannst du sogar ein Pixel 2D Jump-Run in der Console schreiben :rolleyes: es geht schon einiges mit der ollen Konsole :P

Werbeanzeige