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

05.09.2006, 20:56

Rotation eines Dreiecks

Ich hab mal versucht ein Dreieck rotieren zu lassen, ohne die TriBase-Funktionen zu nutzen.

Resultat ist, das Dreieck dreht sich etwa zur hälfte dann klappt es seltsam um(schwer zu beschreiben) und ist aufeinmal ein Viereck....wenn es die zweite Hälfte der Rotation durchlaufen hat und an seinem ausgangspunkt ist, wird es wieder zu einen dreieck.

denke mal, mein rotationscode ist nicht so ganz richtig:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
BOOL Rotation()
{
    D3DXMATRIX matRotationX,matRotationY,matTranslation;

    D3DXMatrixRotationX(&matRotationX,g_angle); //x rotation ( NEW )

    //D3DXMatrixRotationY(&matRotationY,g_angle * 0.75f); //y rotation ( NEW )

    D3DXMatrixTranslation(&matTranslation,0.0f,0.0f,0.0f); //translation ( NEW )


    g_pD3DDevice->SetTransform(D3DTS_WORLD,&(matRotationX *  matTranslation));

    g_angle += 0.01f;

    //Wenn volle Drehung durchgeführt, Wert wieder auf Null zurücksetzen

    if(g_angle == 360.0f)
        g_angle = 0.0;


    return TRUE;
}


was könnte das problem sein?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

05.09.2006, 22:21

das mit dem viereck ist interessant^^, klingt als würde ein punkt gegen unendlich wandern oder so.

naja, was mir gleich auffällt ist, dass du scheinbar mit grad arbeitest, D3DXMatrixRotation*() wie so ziemlich alles andere auch aber mit radiant arbeitet (g_angle sollte also bei 2*PI auf 0.0 gesetzt werden, nicht bei 360...).
umrechnung: winkel_in_radiant = winkel_in_grad * PI / 180
durch den kleinen inkrement sollte das aber eigentlich nicht wirklich zu problemen führen.

wo ich mir nicht ganz sicher bin ist das hier:

C-/C++-Quelltext

1
g_pD3DDevice->SetTransform(D3DTS_WORLD,&(matRotationX *  matTranslation));


verzichte evtl. mal auf die multiplikation (die bei deiner jetzigen translationsmatrix sowieso nichts macht) und machs so:

C-/C++-Quelltext

1
g_pD3DDevice->SetTransform(D3DTS_WORLD, &matRotationX );


oder versuchs mal so:

C-/C++-Quelltext

1
g_pD3DDevice->SetTransform(D3DTS_WORLD,&D3DXMATRIX(matRotationX *  matTranslation));

Phili

unregistriert

3

05.09.2006, 22:26

versuch mal
g_pD3DDevice->SetTransform(D3DTS_WORLD, &matRotationX);

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

4

06.09.2006, 12:37

Hi,

Ein paar Bemerkungen zu dem Problem:

Eine Translation (Verschiebung) von (0, 0, 0) kannst du auch weglassen. (sollte aber kein Problem sein)

Selbst wenn die Funktionen in Grad rechnen würden, ist unwahrscheinlich, dass ein float mit dem Vergleich "== 360.0f" erkannt wird. float (und auch double) Werte sollte man niemals mit "==" vergleichen. Besser ist da

C-/C++-Quelltext

1
if (fabs (g_angle - 360.0f) < 1.0e-5f)


In diesem Fall sogar noch besser (weil im Bogenmaß):

C-/C++-Quelltext

1
g_angle = ::fmodf (g_angle + 0.01f, 2.0f * PI);


Damit wird dann immer ein Winkel zwischen [0, 2pi) benutzt, was nummerisch auch in Ordnung ist. (Andernfalls können die Winkelfunktionen auch schonmal aus dem Ruder laufen :))

Gruss,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Steven77

Alter Hase

Beiträge: 515

Wohnort: Münster - Gievenbeach

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

5

06.09.2006, 14:34

Warum nicht einfach...

C-/C++-Quelltext

1
if (g_angle >= _2PI) g_angle = 0.0f;
?
Kommen Sie nie mit einem Schwert zu einer Schießerei.

6

06.09.2006, 19:55

Hmm....funktioniert leider nicht, hier der komplette code , hoffe das ist jetzt nicht zu dreist euch den ganzen source vorzusetzen..... :

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
// MySelf.cpp : Definiert den Einstiegspunkt für die Anwendung.

//


#include "stdafx.h"
#include "MySelf.h"
#include <windows.h>
#include <d3dx9.h>
#include <d3d9.h>

// Globale Variablen:

HINSTANCE hInst;                                // Aktuelle Instanz

TCHAR szTitle[100] = TEXT("Titelleistentext");                  // Titelleistentext

TCHAR szWindowClass[100] = TEXT("TriBase");         // Klassenname des Hauptfensters


PDIRECT3DDEVICE9    g_pD3DDevice = NULL;
PDIRECT3D9          g_pD3D = NULL;
PDIRECT3DTEXTURE9   g_pTexture;
HWND                g_hWnd;
bool                g_bRun = TRUE;
float               g_angle = 0.0f;


Funktionen:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
//D3D Initialisieren

BOOL                InitD3D();
//Objekt drehen

BOOL                Rotation();
//Rendern des Dreiecks

BOOL                RenderTriangle();
//D3D Runterfahren

BOOL                ExitD3D();

#define TB_DEG_TO_RAD(x)        ((x) * 0.0174532925199432957692369076848f)  // Grad -> Bogenmaß

#define PI                      3.14159265

struct Vertex
{
    //Positionskoordinaten

    float   x,y,z;
    //Farbe

    DWORD   color;
    //Texturkoordinaten

    float   u, v;
};

Vertex g_TriangleData[3] =
{
    {-0.0f, 0.25f, 0.0f, D3DCOLOR_XRGB(255, 255, 255), 0.0f, 0.5f},
    {-0.25f, -0.25f, 0.0f, D3DCOLOR_XRGB(255, 255, 255), -0.5f, -0.5f},
    {0.25f, -0.25f, 0.0f, D3DCOLOR_XRGB(255, 255, 255), 0.5f, -0.5f}
};

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    // TODO: Hier Code einfügen.

    MSG msg;

    MyRegisterClass(hInstance);

    // Anwendungsinitialisierung ausführen:

    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    InitD3D();

    while(g_bRun)
    {
        RenderTriangle();
        // Hauptmeldungsschleife:

        while (PeekMessage(&msg, g_hWnd, 0, 0, PM_REMOVE))
        {
            if(msg.message == WM_QUIT)
                break;
    
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
        
    ExitD3D();

    UnregisterClass(szWindowClass, hInstance);

    return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYSELF));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_MYSELF);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   

   hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern


   g_hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
                        GetSystemMetrics(SM_CXSCREEN) / 2 - (1024 / 2), GetSystemMetrics(SM_CYSCREEN) / 2 - (768 / 2),
                        1024, 768,
                        NULL, NULL, hInstance, NULL);

   if (!g_hWnd)
   {
      return FALSE;
   }

   ShowWindow(g_hWnd, nCmdShow);
   UpdateWindow(g_hWnd);

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND g_hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE:
        break;
    case WM_KEYDOWN:
        switch(wParam)
        {
        case VK_ESCAPE:
            SendMessage(g_hWnd, WM_QUIT, 0, NULL);
            break;
        }
        break;
    case WM_CLOSE:
        SendMessage(g_hWnd, WM_QUIT, 0, NULL);
    case WM_QUIT:
        g_bRun = false;
        DestroyWindow(g_hWnd);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(g_hWnd, message, wParam, lParam);
    }
    return 0;
}
BOOL InitD3D()
{
    D3DPRESENT_PARAMETERS   PresentParms;
    D3DDISPLAYMODE          DisplayMode;
    //GGf. überprüfen ob GraKa die gesetzten Modien überhaupt leisten kann

    HRESULT hResult;

    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

    if(FAILED(g_pD3D->GetAdapterDisplayMode(0, &DisplayMode)))
    {
        MessageBox(NULL, TEXT("Error setting the display mode."), TEXT("Error!"), MB_OK);
        return false;
    }

    if(g_pD3D == NULL)
    {
        return FALSE;
    }

    memset(&PresentParms,0, sizeof(D3DPRESENT_PARAMETERS));

    PresentParms.Windowed                   = TRUE;
    PresentParms.BackBufferWidth            = 1024;
    PresentParms.BackBufferHeight           = 768;
    PresentParms.BackBufferFormat           = D3DFMT_A8R8G8B8;
    PresentParms.BackBufferCount            = 1;
    PresentParms.MultiSampleType            = D3DMULTISAMPLE_6_SAMPLES;
    PresentParms.SwapEffect                 = D3DSWAPEFFECT_DISCARD;
    PresentParms.hDeviceWindow              = NULL;
    PresentParms.EnableAutoDepthStencil     = TRUE;
    PresentParms.AutoDepthStencilFormat     = D3DFMT_D24S8;
    PresentParms.Flags                      = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
    PresentParms.PresentationInterval       = D3DPRESENT_INTERVAL_DEFAULT;
    PresentParms.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;

    

    //Erzeugen und initialisieren des Gerätes

    if(FAILED(hResult = g_pD3D->CreateDevice(0,
                                            D3DDEVTYPE_HAL,
                                            g_hWnd,
                                            D3DCREATE_HARDWARE_VERTEXPROCESSING,
                                            &PresentParms,
                                            &g_pD3DDevice)))
    {
        MessageBox(g_hWnd, TEXT("Fehler bei CreateDevice"), TEXT("Fehler!!!"), MB_ICONERROR);
    }

    if(FAILED(hResult = g_pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)))
    {
        MessageBox(g_hWnd, TEXT("Fehler beim setzten der\n FlexibleVertexFormate"), TEXT("Fehler!!!"), MB_ICONERROR); 
    }

    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    g_pD3DDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE);


    //Laden der Texture

    if(FAILED(hResult = D3DXCreateTextureFromFileEx(g_pD3DDevice,
                                                    TEXT("Texture.bmp"),
                                                    D3DX_DEFAULT,
                                                    D3DX_DEFAULT,
                                                    D3DX_DEFAULT,
                                                    0,
                                                    D3DFMT_UNKNOWN,
                                                    D3DPOOL_MANAGED,
                                                    D3DX_FILTER_NONE,
                                                    D3DX_DEFAULT,
                                                    0,
                                                    NULL,
                                                    NULL,
                                                    &g_pTexture)))
    {
        MessageBox(g_hWnd, TEXT("Fehler beim Laden der\n Texture"), TEXT("Fehler!!!"), MB_ICONERROR); 
    }

    
    g_pD3DDevice->SetTexture(0, g_pTexture);

    //Benutzung der Filter einstellen

    g_pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    g_pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
    g_pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);

    return TRUE;
}

BOOL Rotation()
{
    D3DXMATRIX matRotationX,matRotationY,matTranslation;

    D3DXMatrixRotationX(&matRotationX,g_angle);
    //D3DXMatrixRotationY(&matRotationY,g_angle * 0.75f); 

    D3DXMatrixTranslation(&matTranslation,0.0f,0.0f,0.0f); 

    g_pD3DDevice->SetTransform(D3DTS_WORLD,&matRotationX);

    g_angle += 0.1f;

    //Wenn volle Drehung durchgeführt, Wert wieder auf Null zurücksetzen

    if(g_angle >= 2* PI)
        g_angle = 0.0f;

    


    return TRUE;
}


BOOL RenderTriangle()
{
    //Buffer clearen und Hintergrundfarbe setzen

    g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 100, 0), 1.0f, 0);

    //Start des Zeichnen

    g_pD3DDevice->BeginScene();

    Rotation();

    PDIRECT3DVERTEXBUFFER9 VertexBuffer;
    //Vertexbuffer anlegen

    g_pD3DDevice->CreateVertexBuffer(3 * sizeof(Vertex), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &VertexBuffer, NULL);

    Vertex* Vertices;

    //Sperren des Speichbereichs

    if(FAILED(VertexBuffer->Lock(0, sizeof(g_TriangleData), (void**)&Vertices, 0)))
    {
        MessageBox(g_hWnd, TEXT("Fehler beim locken des VertexBuffer"), TEXT("Fehler!!!"), MB_ICONERROR); 
    }

    //Kopieren der Datei in den Buffer

    memcpy(Vertices, g_TriangleData, sizeof(g_TriangleData));

    //Bereich wieder Freigeben

    VertexBuffer->Unlock();

    g_pD3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(Vertex));

    //Zeichnen des Dreiecks

    g_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 1, g_TriangleData, sizeof(Vertex));

    //Buffer freigeben

    VertexBuffer->Release();

    g_pD3DDevice->EndScene();
    
    //Sichtbar machen

    g_pD3DDevice->Present(NULL, NULL, NULL, NULL);

    return TRUE;
}

BOOL ExitD3D()
{
    if(g_pD3D != NULL)
    {
        g_pD3D->Release();
        g_pD3D = NULL;
    }

    if(g_pD3DDevice != NULL)
    {
        g_pD3DDevice->Release();
        g_pD3DDevice = NULL;
    }

    if(g_pTexture != NULL)
    {
        g_pTexture->Release();
        g_pTexture = NULL;
    }

    return TRUE;
}

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

06.09.2006, 20:45

habs nur mal schnell überflogen.
was mir dabei aufgefallen ist:
  • du setzt kein FVF (aufruf von SetFVF() fehlt, habs zumindest nicht entdecken können)
  • dein vertex buffer is sinnos (verwendung von DrawPrimitiveUP())
außerdem solltest du nach möglichkeit einen vertexbuffer nie in der render funktion erstellen (vor allem hier, weils auch vorher geht), denn das erstellen, locken und dinge reinkopieren braucht seine zeit.
und dein fvf stimmt mit deinem vertex format nicht überein (deine vertices haben texturkoordinaten, D3DFVF_TEX1 fehlt aber).

das wärs erstmal ;)

8

06.09.2006, 21:17

danke für die tipps, das FVF setze ich schon

if(FAILED(hResult = g_pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)))
{
MessageBox(g_hWnd, TEXT("Fehler beim setzten der\n FlexibleVertexFormate"), TEXT("Fehler!!!"), MB_ICONERROR);
}


die Texture hab ich testweise mal auskommentiert, wird zwar geladen, aber nicht gesetzt.

Hab mich etwas rumgelesen und dann noch eine View matrix und projectionsmatrix eingebaut. damit funktioniert es. Allerdings tu ich es etwas schwer die Begründung dafür zu verstehen.

könnte der effekt des "vierrecks" ein resultat aus einem falschen/zu nahem blickwinkel sein?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

9

06.09.2006, 22:04

sry, hab SetFVF() echt nicht gesehn^^.
gut das es jetzt geht :D
das mit dem viereck ist in der tat merkwürdig. da du keine projektions- und viewmatrix hattest und die w koordinate der vertices nicht angegeben hast, könnte da evtl. was komisches passiert sein (w koordiante auf einmal 0 oder so).

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

10

07.09.2006, 12:17

Zitat von »"Steven77"«

Warum nicht einfach...

C-/C++-Quelltext

1
if (g_angle >= _2PI) g_angle = 0.0f;
?


Also wirklich...

was ist denn das Ergebnis von:

C-/C++-Quelltext

1
::fmodf (2.0f * PI + 0.01f, 2.0f * PI);


... jedenfalls ganz sicher nicht 0.0f. Darum muss/sollte man bei Rotationen immer modulo rechnen, wenn man eine kontinuierliche Animation haben will. Okay, bei entsprechend kleiner Schrittweite wird das kaum auffallen, aber modulo ist mathematisch einfach korrekter.

Gruss,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Werbeanzeige