관리 메뉴

Kim's Programming

[다이렉트SDK 예제]DirectX Tutorial3 - Matrices 본문

Programming/DirectX

[다이렉트SDK 예제]DirectX Tutorial3 - Matrices

Programmer. 2016. 4. 15. 01:36

이번 포스팅에서는 Matrices에 대해서 다루겠습니다.


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
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
//-----------------------------------------------------------------------------
// File: Matrices.cpp
//
// Desc: Now that we know how to create a device and render some 2D vertices,
//       this tutorial goes the next step and renders 3D geometry. To deal with
//       3D geometry we need to introduce the use of 4x4 Matrices to transform
//       the geometry with translations, rotations, scaling, and setting up our
//       camera.
//
//       Geometry is defined in model space. We can move it (translation),
//       rotate it (rotation), or stretch it (scaling) using a world transform.
//       The geometry is then said to be in world space. Next, we need to
//       position the camera, or eye point, somewhere to look at the geometry.
//       Another transform, via the view matrix, is used, to position and
//       rotate our view. With the geometry then in view space, our last
//       transform is the projection transform, which "projects" the 3D scene
//       into our 2D viewport.
//
//       Note that in this tutorial, we are introducing the use of D3DX, which
//       is a set of helper utilities for D3D. In this case, we are using some
//       of D3DX's useful matrix initialization functions. To use D3DX, simply
//       include <d3dx9.h> and link with d3dx9.lib.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include <Windows.h>
#include <mmsystem.h>
#include <d3dx9.h>
#pragma warning( disable : 4996 // disable deprecated warning 
#include <strsafe.h>
#pragma warning( default : 4996 )
#include<math.h>
 
 
 
 
 
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // Our rendering device
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices
LPDIRECT3DVERTEXBUFFER9 g_pVB2 = NULL; // Buffer to hold vertices
LPDIRECT3DVERTEXBUFFER9 g_pVB3 = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVB4 = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVB5 = NULL;
// A structure for our custom vertex type
struct CUSTOMVERTEX
{
    FLOAT x, y, z;      // The untransformed, 3D position for the vertex
    DWORD color;        // The vertex color
};
 
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
 
 
 
 
//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Initializes Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
    // Create the D3D object.
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;
 
    // Set up the structure used to create the D3DDevice
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
 
    // Create the D3DDevice
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }
 
    // Turn off culling, so we see the front and back of the triangle
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
 
    // Turn off D3D lighting, since we are providing our own vertex colors
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
 
    return S_OK;
}
 
 
 
 
//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: Creates the scene geometry
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
    // Initialize three vertices for rendering a triangle
    CUSTOMVERTEX g_Vertices[] =
    {
        { -1.0f,-1.0f, 0.0f, 0xffff0000, },
        {  1.0f,-1.0f, 0.0f, 0xff0000ff, },
        {  0.0f, 1.0f, 0.0f, 0xffffffff, },
    };
 
 
 
    // Create the vertex buffer.
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( * sizeof( CUSTOMVERTEX ),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer.
    VOID* pVertices;
    if( FAILED( g_pVB->Lock( 0sizeof( g_Vertices ), ( void** )&pVertices, ) ) )
        return E_FAIL;
    memcpy( pVertices, g_Vertices, sizeof( g_Vertices ) );
    g_pVB->Unlock();
 
    CUSTOMVERTEX g_Vertices2[] =
    {
        { -1.0f,-1.0f, 0.0f, 0xffff0000, },
        { 1.0f,-1.0f, 0.0f, 0xffffffff, },
        { 0.0f, 1.0f, 0.0f, 0xffffffff, },
    };
 
 
 
    // Create the vertex buffer.
    if (FAILED(g_pd3dDevice->CreateVertexBuffer(* sizeof(CUSTOMVERTEX),
        0, D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT, &g_pVB2, NULL)))
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer.
    VOID* pVertices2;
    if (FAILED(g_pVB2->Lock(0sizeof(g_Vertices2), (void**)&pVertices2, 0)))
        return E_FAIL;
    memcpy(pVertices2, g_Vertices2, sizeof(g_Vertices2));
    g_pVB2->Unlock();
 
    CUSTOMVERTEX g_Vertices3[] =
    {
        { -1.0f,-1.0f, 0.0f, 0xffff0000, },
        { 1.0f,-1.0f, 0.0f, 0xff0777ff, },
        { 0.0f, 1.0f, 0.0f, 0xffffffff, },
    };
 
 
 
    // Create the vertex buffer.
    if (FAILED(g_pd3dDevice->CreateVertexBuffer(* sizeof(CUSTOMVERTEX),
        0, D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT, &g_pVB3, NULL)))
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer.
    VOID* pVertices3;
    if (FAILED(g_pVB3->Lock(0sizeof(g_Vertices3), (void**)&pVertices3, 0)))
        return E_FAIL;
    memcpy(pVertices3, g_Vertices3, sizeof(g_Vertices3));
    g_pVB3->Unlock();
 
    CUSTOMVERTEX g_Vertices4[] =
    {
        { -1.0f,-1.0f, 0.0f, 0xfff12300, },
        { 1.0f,-1.0f, 0.0f, 0xff0000ff, },
        { 0.0f, 1.0f, 0.0f, 0xff123fff, },
    };
 
 
 
    // Create the vertex buffer.
    if (FAILED(g_pd3dDevice->CreateVertexBuffer(* sizeof(CUSTOMVERTEX),
        0, D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT, &g_pVB4, NULL)))
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer.
    VOID* pVertices4;
    if (FAILED(g_pVB4->Lock(0sizeof(g_Vertices4), (void**)&pVertices4, 0)))
        return E_FAIL;
    memcpy(pVertices4, g_Vertices4, sizeof(g_Vertices4));
    g_pVB4->Unlock();
 
 
    CUSTOMVERTEX g_Vertices5[] =
    {
        { -1.0f,-1.0f, 0.0f, 0xffff0000, },
        { 1.0f,-1.0f, 0.0f, 0xff0000ff, },
        { 0.0f, 1.0f, 0.0f, 0xffffffff, },
    };
 
 
 
    // Create the vertex buffer.
    if (FAILED(g_pd3dDevice->CreateVertexBuffer(* sizeof(CUSTOMVERTEX),
        0, D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT, &g_pVB5, NULL)))
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer.
    VOID* pVertices5;
    if (FAILED(g_pVB5->Lock(0sizeof(g_Vertices5), (void**)&pVertices5, 0)))
        return E_FAIL;
    memcpy(pVertices5, g_Vertices5, sizeof(g_Vertices5));
    g_pVB5->Unlock();
 
    return S_OK;
}
 
 
 
 
//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if( g_pVB != NULL )
        g_pVB->Release();
 
    if (g_pVB2 != NULL)
        g_pVB->Release();
 
    if (g_pVB3 != NULL)
        g_pVB->Release();
 
    if (g_pVB4 != NULL)
        g_pVB->Release();
 
    if (g_pVB5 != NULL)
        g_pVB->Release();
 
    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();
 
    if( g_pD3D != NULL )
        g_pD3D->Release();
}
 
 
 
//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: Sets up the world, view, and projection transform Matrices.
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
 
    static float a = 0;
    static float b = 0;
    b = 0.02;
    a+= 0.02;
    
    // For our world matrix, we will just rotate the object about the y-axis.
    D3DXMATRIXA16 matWorld;
    D3DXMATRIXA16 input1;
    D3DXMATRIXA16 input2;
    D3DXMATRIXA16 input3;
    D3DXMATRIXA16 output;
 
    // Set up the rotation matrix to generate 1 full rotation (2*PI radians) 
    // every 1000 ms. To avoid the loss of precision inherent in very high 
    // floating point numbers, the system time is modulated by the rotation 
    // period before conversion to a radian angle.
    UINT iTime = timeGetTime() % 1000;
    FLOAT fAngle = iTime * ( 2.0f * D3DX_PI ) / 1000.0f;
 
    //회전함수
    D3DXMatrixRotationY( &input2, fAngle );
    //이동함수
    //D3DXMatrixTranslation(&input2, a, 1.0f, 5.0f);
    //신축함수
    D3DXMatrixScaling(&input3, 0.20.20.2);
 
 
    D3DXMatrixMultiply(&input1, &input3, &input2);
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &input1 );
 
    //순서 : Scaling -> Rotation -> Translation 순서로 하면 웬만하면 그렇게 나온다. 그러면 그렇다
 
 
    // Set up our view matrix. A view matrix can be defined given an eye point,
    // a point to lookat, and a direction for which way is up. Here, we set the
    // eye five units back along the z-axis and up three units, look at the
    // origin, and define "up" to be in the y-direction.
    D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
 
    // For the projection matrix, we set up a perspective transform (which
    // transforms geometry from 3D view space to 2D viewport space, with
    // a perspective divide making objects smaller in the distance). To build
    // a perpsective transform, we need the field of view (1/4 pi is common),
    // the aspect ratio, and the near and far clipping planes (which define at
    // what distances geometry should be no longer be rendered).
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 41.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
//1. 월드 매트릭스 --> Rotation, Scale, Translation
//2. 카메라 매트릭스 --> 카메라 위치
//3. 프로젝션 매트릭스 --> 모니터에 표시
 
//----> 하나라도 빠지면 디폴트로 넣어줌
 
VOID SetupMatrices2()
{
 
    static float a = 0;
    static float b = 0;
    b = 0.02;
    a += 0.02;
 
    // For our world matrix, we will just rotate the object about the y-axis.
    D3DXMATRIXA16 matWorld;
    D3DXMATRIXA16 input1;
    D3DXMATRIXA16 input2;
    D3DXMATRIXA16 input3;
    D3DXMATRIXA16 input4;
    D3DXMATRIXA16 output;
 
    // Set up the rotation matrix to generate 1 full rotation (2*PI radians) 
    // every 1000 ms. To avoid the loss of precision inherent in very high 
    // floating point numbers, the system time is modulated by the rotation 
    // period before conversion to a radian angle.
    UINT iTime = timeGetTime() % 1000;
    FLOAT fAngle = iTime * (2.0f * D3DX_PI) / 1000.0f;
 
    //이동함수
    D3DXMatrixTranslation(&input2, 7.0f, 0.0f, 0.0f);
    //신축함수
    D3DXMatrixScaling(&input3, 0.1f, 0.1f, 0.1f);
    //회전함수
    D3DXMatrixRotationY(&input1, fAngle);
    D3DXMatrixRotationY(&input4, a);
 
    D3DXMatrixMultiply(&output, &input3, &input4); // 신축 -> 자전 -> 이동 -> 공전
    D3DXMatrixMultiply(&output, &input2, &output);
    D3DXMatrixMultiply(&output, &input1, &output);
 
 
    g_pd3dDevice->SetTransform(D3DTS_WORLD, &output);
 
    //순서 : Scaling -> Rotation -> Translation 순서로 하면 웬만하면 그렇게 나온다. 그러면 그렇다
 
 
    // Set up our view matrix. A view matrix can be defined given an eye point,
    // a point to lookat, and a direction for which way is up. Here, we set the
    // eye five units back along the z-axis and up three units, look at the
    // origin, and define "up" to be in the y-direction.
    D3DXVECTOR3 vEyePt(0.0f, 3.0f, -5.0f);
    D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec);
    g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
 
    // For the projection matrix, we set up a perspective transform (which
    // transforms geometry from 3D view space to 2D viewport space, with
    // a perspective divide making objects smaller in the distance). To build
    // a perpsective transform, we need the field of view (1/4 pi is common),
    // the aspect ratio, and the near and far clipping planes (which define at
    // what distances geometry should be no longer be rendered).
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 41.0f, 1.0f, 100.0f);
    g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}
//1. 월드 매트릭스 --> Rotation, Scale, Translation
//2. 카메라 매트릭스 --> 카메라 위치
//3. 프로젝션 매트릭스 --> 모니터에 표시
 
 
VOID SetupMatrices3()//달
{
 
    static float a = 0;
    static float b = 0;
    b = 0.02;
    a += 0.02;
 
    // For our world matrix, we will just rotate the object about the y-axis.
    D3DXMATRIXA16 matWorld;
    D3DXMATRIXA16 input1;
    D3DXMATRIXA16 input2;
    D3DXMATRIXA16 input3;
    D3DXMATRIXA16 input4;
    D3DXMATRIXA16 input5;
    D3DXMATRIXA16 input6;
    D3DXMATRIXA16 output;
 
    // Set up the rotation matrix to generate 1 full rotation (2*PI radians) 
    // every 1000 ms. To avoid the loss of precision inherent in very high 
    // floating point numbers, the system time is modulated by the rotation 
    // period before conversion to a radian angle.
    UINT iTime = timeGetTime() % 1000;
    FLOAT fAngle = iTime * (2.0f * D3DX_PI) / 1000.0f;
 
    //이동함수
    D3DXMatrixTranslation(&input2, 7.0f, 0.0f, 0.0f);
    //신축함수
    D3DXMatrixScaling(&input3, 0.1f, 0.1f, 0.1f);
    //회전함수
    D3DXMatrixRotationY(&input1, fAngle);
    D3DXMatrixRotationY(&input4, a);
 
    D3DXMatrixMultiply(&output, &input3, &input4); // 신축 -> 자전 -> 이동 -> 공전
    D3DXMatrixMultiply(&output, &input2, &output);
    D3DXMatrixMultiply(&output, &input1, &output);
 
    D3DXMatrixMultiply(&output, &input2, &output);
    D3DXMatrixMultiply(&output, &input1, &output);
 
 
 
 
    g_pd3dDevice->SetTransform(D3DTS_WORLD, &output);
 
    //순서 : Scaling -> Rotation -> Translation 순서로 하면 웬만하면 그렇게 나온다. 그러면 그렇다
 
 
    // Set up our view matrix. A view matrix can be defined given an eye point,
    // a point to lookat, and a direction for which way is up. Here, we set the
    // eye five units back along the z-axis and up three units, look at the
    // origin, and define "up" to be in the y-direction.
    D3DXVECTOR3 vEyePt(0.0f, 3.0f, -5.0f);
    D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec);
    g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
 
    // For the projection matrix, we set up a perspective transform (which
    // transforms geometry from 3D view space to 2D viewport space, with
    // a perspective divide making objects smaller in the distance). To build
    // a perpsective transform, we need the field of view (1/4 pi is common),
    // the aspect ratio, and the near and far clipping planes (which define at
    // what distances geometry should be no longer be rendered).
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 41.0f, 1.0f, 100.0f);
    g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}
//1. 월드 매트릭스 --> Rotation, Scale, Translation
//2. 카메라 매트릭스 --> 카메라 위치
//3. 프로젝션 매트릭스 --> 모니터에 표시
 
VOID SetupMatrices4()
{
 
    static float a = 0;
    static float b = 0;
    b = 0.02;
    a += 0.02;
 
    // For our world matrix, we will just rotate the object about the y-axis.
    D3DXMATRIXA16 matWorld;
    D3DXMATRIXA16 input1;
    D3DXMATRIXA16 input2;
    D3DXMATRIXA16 input3;
    D3DXMATRIXA16 input4;
    D3DXMATRIXA16 output;
 
    // Set up the rotation matrix to generate 1 full rotation (2*PI radians) 
    // every 1000 ms. To avoid the loss of precision inherent in very high 
    // floating point numbers, the system time is modulated by the rotation 
    // period before conversion to a radian angle.
    UINT iTime = timeGetTime() % 1000;
    FLOAT fAngle = iTime * (2.0f * D3DX_PI) / 1000.0f;
 
    //이동함수
    D3DXMatrixTranslation(&input2, 6.0f, 0.0f, 0.0f);
    //신축함수
    D3DXMatrixScaling(&input3, 0.3f, 0.3f, 0.3f);
    //회전함수
    D3DXMatrixRotationY(&input1, fAngle);
    D3DXMatrixRotationY(&input4, 2*a);
 
    D3DXMatrixMultiply(&output, &input3, &input4); // 신축 -> 자전 -> 이동 -> 공전
    D3DXMatrixMultiply(&output, &input2, &output);
    D3DXMatrixMultiply(&output, &input1, &output);
 
 
    g_pd3dDevice->SetTransform(D3DTS_WORLD, &output);
 
    //순서 : Scaling -> Rotation -> Translation 순서로 하면 웬만하면 그렇게 나온다. 그러면 그렇다
 
 
    // Set up our view matrix. A view matrix can be defined given an eye point,
    // a point to lookat, and a direction for which way is up. Here, we set the
    // eye five units back along the z-axis and up three units, look at the
    // origin, and define "up" to be in the y-direction.
    D3DXVECTOR3 vEyePt(0.0f, 3.0f, -5.0f);
    D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec);
    g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
 
    // For the projection matrix, we set up a perspective transform (which
    // transforms geometry from 3D view space to 2D viewport space, with
    // a perspective divide making objects smaller in the distance). To build
    // a perpsective transform, we need the field of view (1/4 pi is common),
    // the aspect ratio, and the near and far clipping planes (which define at
    // what distances geometry should be no longer be rendered).
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 41.0f, 1.0f, 100.0f);
    g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}
//1. 월드 매트릭스 --> Rotation, Scale, Translation
//2. 카메라 매트릭스 --> 카메라 위치
//3. 프로젝션 매트릭스 --> 모니터에 표시
 
VOID SetupMatrices5()
{
 
    static float a = 0;
    static float b = 0;
    b = 0.02;
    a += 0.02;
 
    // For our world matrix, we will just rotate the object about the y-axis.
    D3DXMATRIXA16 matWorld;
    D3DXMATRIXA16 input1;
    D3DXMATRIXA16 input2;
    D3DXMATRIXA16 input3;
    D3DXMATRIXA16 input4;
    D3DXMATRIXA16 output;
 
    // Set up the rotation matrix to generate 1 full rotation (2*PI radians) 
    // every 1000 ms. To avoid the loss of precision inherent in very high 
    // floating point numbers, the system time is modulated by the rotation 
    // period before conversion to a radian angle.
    UINT iTime = timeGetTime() % 1000;
    FLOAT fAngle = iTime * (2.0f * D3DX_PI) / 1000.0f;
 
    //이동함수
    D3DXMatrixTranslation(&input2, 15.0f, 0.0f, 0.0f);
    //신축함수
    D3DXMatrixScaling(&input3, 0.15f, 0.15f, 0.15f);
    //회전함수
    D3DXMatrixRotationY(&input1, 2*fAngle);
    D3DXMatrixRotationY(&input4, * a);
 
    D3DXMatrixMultiply(&output, &input3, &input4); // 신축 -> 자전 -> 이동 -> 공전
    D3DXMatrixMultiply(&output, &input2, &output);
    D3DXMatrixMultiply(&output, &input1, &output);
 
 
    g_pd3dDevice->SetTransform(D3DTS_WORLD, &output);
 
    //순서 : Scaling -> Rotation -> Translation 순서로 하면 웬만하면 그렇게 나온다. 그러면 그렇다
 
 
    // Set up our view matrix. A view matrix can be defined given an eye point,
    // a point to lookat, and a direction for which way is up. Here, we set the
    // eye five units back along the z-axis and up three units, look at the
    // origin, and define "up" to be in the y-direction.
    D3DXVECTOR3 vEyePt(0.0f, 3.0f, -5.0f);
    D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec);
    g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
 
    // For the projection matrix, we set up a perspective transform (which
    // transforms geometry from 3D view space to 2D viewport space, with
    // a perspective divide making objects smaller in the distance). To build
    // a perpsective transform, we need the field of view (1/4 pi is common),
    // the aspect ratio, and the near and far clipping planes (which define at
    // what distances geometry should be no longer be rendered).
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 41.0f, 1.0f, 100.0f);
    g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}
//1. 월드 매트릭스 --> Rotation, Scale, Translation
//2. 카메라 매트릭스 --> 카메라 위치
//3. 프로젝션 매트릭스 --> 모니터에 표시
 
 
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
    // Clear the backbuffer to a black color
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 00), 1.0f, );
 
    // Begin the scene
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
 
        //태양
        // Setup the world, view, and projection Matrices
        SetupMatrices();
 
        // Render the vertex buffer contents
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0sizeof( CUSTOMVERTEX ) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0);
 
        
 
        SetupMatrices2();
        //지구
        // Render the vertex buffer contents
        g_pd3dDevice->SetStreamSource(0, g_pVB2, 0sizeof(CUSTOMVERTEX));
        g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
        g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 01);
 
        SetupMatrices3();
        //달
        // Render the vertex buffer contents
        g_pd3dDevice->SetStreamSource(0, g_pVB3, 0sizeof(CUSTOMVERTEX));
        g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
        g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 01);
 
        SetupMatrices4();
        //달
        // Render the vertex buffer contents
        g_pd3dDevice->SetStreamSource(0, g_pVB4, 0sizeof(CUSTOMVERTEX));
        g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
        g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 01);
 
        SetupMatrices5();
        //달
        // Render the vertex buffer contents
        g_pd3dDevice->SetStreamSource(0, g_pVB5, 0sizeof(CUSTOMVERTEX));
        g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
        g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 01);
 
        // End the scene
        g_pd3dDevice->EndScene();
    }
 
    // Present the backbuffer contents to the display
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
 
 
 
 
//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( );
            return 0;
    }
 
    return DefWindowProc( hWnd, msg, wParam, lParam );
}
 
 
 
 
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
    UNREFERENCED_PARAMETER( hInst );
 
    // Register the window class
    WNDCLASSEX wc =
    {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
        L"D3D Tutorial", NULL
    };
    RegisterClassEx( &wc );
 
    // Create the application's window
    HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 03: Matrices",
                              WS_OVERLAPPEDWINDOW, 300300768768,
                              NULL, NULL, wc.hInstance, NULL );
 
    // Initialize Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        // Create the scene geometry
        if( SUCCEEDED( InitGeometry() ) )
        {
            // Show the window
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );
 
            // Enter the message loop
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) );
            while( msg.message != WM_QUIT )
            {
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
                {
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                }
                else
                    Render();
            }
        }
    }
 
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}
cs


지금까지의 예제에서는 2D를 하였고 이번부터는 3D를 렌더링 하게됩니다. 3D Geometry에서는 우리는 4x4행렬을 이용하여 이동, 회전, 확대, 그리고 카메라 설정에 사용하게됩니다. Geometry는 모델 공간을 정의합니다. 월드 좌표 변환을 이용하여도 회전, 확대, 이동을 할 수 있기 때문에  gerometry는 월드 공간이라고 할 수 있습니다. 다음으로는 우리는 카메라의 위치, 눈의 위치, 그리고 geometry를 바라보는 위치가 필요합니다. 뷰 매트릭스를 통한 변형은 우리가 보는 것을 돌리거나 위치 시킬 수 있습니다. view space안에서 geometry는 투영 변환을 통하여 3D를 2D뷰포트로 변형시키게 됩니다.


이번에는 VB를 여러개 사용했기 때문에 겹쳐보이는 여러개가 있을 수 있습니다.


전역변수


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // Our rendering device
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices
LPDIRECT3DVERTEXBUFFER9 g_pVB2 = NULL; // Buffer to hold vertices
LPDIRECT3DVERTEXBUFFER9 g_pVB3 = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVB4 = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVB5 = NULL;
// A structure for our custom vertex type
struct CUSTOMVERTEX
{
    FLOAT x, y, z;      // The untransformed, 3D position for the vertex
    DWORD color;        // The vertex color
};
 
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
cs

 vertices와는 달리 CUSTOMVERTEX의 정의가 달라졌습니다. 원래 rhw라는 변수가 하나더 있었는데요 기존에 이는 동차좌표계 표기를 위한 좌표였습니다. Matrices에서는 동차좌표계 없이 사용하게 됩니다.


InitGeometry()


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
HRESULT InitGeometry()
{
    // Initialize three vertices for rendering a triangle
    CUSTOMVERTEX g_Vertices[] =
    {
        { -1.0f,-1.0f, 0.0f, 0xffff0000, },
        {  1.0f,-1.0f, 0.0f, 0xff0000ff, },
        {  0.0f, 1.0f, 0.0f, 0xffffffff, },
    };
 
 
 
    // Create the vertex buffer.
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( * sizeof( CUSTOMVERTEX ),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer.
    VOID* pVertices;
    if( FAILED( g_pVB->Lock( 0sizeof( g_Vertices ), ( void** )&pVertices, ) ) )
        return E_FAIL;
    memcpy( pVertices, g_Vertices, sizeof( g_Vertices ) );
    g_pVB->Unlock();
 
    CUSTOMVERTEX g_Vertices2[] =
    {
        { -1.0f,-1.0f, 0.0f, 0xffff0000, },
        { 1.0f,-1.0f, 0.0f, 0xffffffff, },
        { 0.0f, 1.0f, 0.0f, 0xffffffff, },
    };
 
 
 
    // Create the vertex buffer.
    if (FAILED(g_pd3dDevice->CreateVertexBuffer(* sizeof(CUSTOMVERTEX),
        0, D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT, &g_pVB2, NULL)))
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer.
    VOID* pVertices2;
    if (FAILED(g_pVB2->Lock(0sizeof(g_Vertices2), (void**)&pVertices2, 0)))
        return E_FAIL;
    memcpy(pVertices2, g_Vertices2, sizeof(g_Vertices2));
    g_pVB2->Unlock();
 
    CUSTOMVERTEX g_Vertices3[] =
    {
        { -1.0f,-1.0f, 0.0f, 0xffff0000, },
        { 1.0f,-1.0f, 0.0f, 0xff0777ff, },
        { 0.0f, 1.0f, 0.0f, 0xffffffff, },
    };
 
 
 
    // Create the vertex buffer.
    if (FAILED(g_pd3dDevice->CreateVertexBuffer(* sizeof(CUSTOMVERTEX),
        0, D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT, &g_pVB3, NULL)))
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer.
    VOID* pVertices3;
    if (FAILED(g_pVB3->Lock(0sizeof(g_Vertices3), (void**)&pVertices3, 0)))
        return E_FAIL;
    memcpy(pVertices3, g_Vertices3, sizeof(g_Vertices3));
    g_pVB3->Unlock();
 
    CUSTOMVERTEX g_Vertices4[] =
    {
        { -1.0f,-1.0f, 0.0f, 0xfff12300, },
        { 1.0f,-1.0f, 0.0f, 0xff0000ff, },
        { 0.0f, 1.0f, 0.0f, 0xff123fff, },
    };
 
 
 
    // Create the vertex buffer.
    if (FAILED(g_pd3dDevice->CreateVertexBuffer(* sizeof(CUSTOMVERTEX),
        0, D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT, &g_pVB4, NULL)))
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer.
    VOID* pVertices4;
    if (FAILED(g_pVB4->Lock(0sizeof(g_Vertices4), (void**)&pVertices4, 0)))
        return E_FAIL;
    memcpy(pVertices4, g_Vertices4, sizeof(g_Vertices4));
    g_pVB4->Unlock();
 
 
    CUSTOMVERTEX g_Vertices5[] =
    {
        { -1.0f,-1.0f, 0.0f, 0xffff0000, },
        { 1.0f,-1.0f, 0.0f, 0xff0000ff, },
        { 0.0f, 1.0f, 0.0f, 0xffffffff, },
    };
 
 
 
    // Create the vertex buffer.
    if (FAILED(g_pd3dDevice->CreateVertexBuffer(* sizeof(CUSTOMVERTEX),
        0, D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT, &g_pVB5, NULL)))
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer.
    VOID* pVertices5;
    if (FAILED(g_pVB5->Lock(0sizeof(g_Vertices5), (void**)&pVertices5, 0)))
        return E_FAIL;
    memcpy(pVertices5, g_Vertices5, sizeof(g_Vertices5));
    g_pVB5->Unlock();
 
    return S_OK;
}
cs


Vertices와는 다르게 Matrices는 initVB함수가 initGeometry함수로 바뀌었습니다. 사용법은 비슷합니다. 하지만 이름만 조금 바뀌었습니다.



SetupMatrices()


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
//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: Sets up the world, view, and projection transform Matrices.
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
 
    static float a = 0;
    static float b = 0;
    b = 0.02;
    a+= 0.02;
    
    // For our world matrix, we will just rotate the object about the y-axis.
    D3DXMATRIXA16 matWorld;
    D3DXMATRIXA16 input1;
    D3DXMATRIXA16 input2;
    D3DXMATRIXA16 input3;
    D3DXMATRIXA16 output;
 
    // Set up the rotation matrix to generate 1 full rotation (2*PI radians) 
    // every 1000 ms. To avoid the loss of precision inherent in very high 
    // floating point numbers, the system time is modulated by the rotation 
    // period before conversion to a radian angle.
    UINT iTime = timeGetTime() % 1000;
    FLOAT fAngle = iTime * ( 2.0f * D3DX_PI ) / 1000.0f;
 
    //회전함수
    D3DXMatrixRotationY( &input2, fAngle );
    //이동함수
    //D3DXMatrixTranslation(&input2, a, 1.0f, 5.0f);
    //신축함수
    D3DXMatrixScaling(&input3, 0.20.20.2);
 
 
    D3DXMatrixMultiply(&input1, &input3, &input2);
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &input1 );
 
    //순서 : Scaling -> Rotation -> Translation 순서로 하면 웬만하면 그렇게 나온다. 그러면 그렇다
 
 
    // Set up our view matrix. A view matrix can be defined given an eye point,
    // a point to lookat, and a direction for which way is up. Here, we set the
    // eye five units back along the z-axis and up three units, look at the
    // origin, and define "up" to be in the y-direction.
    D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
 
    // For the projection matrix, we set up a perspective transform (which
    // transforms geometry from 3D view space to 2D viewport space, with
    // a perspective divide making objects smaller in the distance). To build
    // a perpsective transform, we need the field of view (1/4 pi is common),
    // the aspect ratio, and the near and far clipping planes (which define at
    // what distances geometry should be no longer be rendered).
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 41.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
//1. 월드 매트릭스 --> Rotation, Scale, Translation
//2. 카메라 매트릭스 --> 카메라 위치
//3. 프로젝션 매트릭스 --> 모니터에 표시
 
//----> 하나라도 빠지면 디폴트로 넣어줌
cs



SetupMatrice함수는 월드 좌표, 뷰, 투영에 대한 메트릭스를 설정합니다. 위에서 말했던 형태와 같이 D3DMATRIXA16구조체를 이용하여 4*4 행렬을 이용할 수 있게 합니다. 이는 또 밑에서 회전, 이동, 신축함수를 이용할 수 있는데 다음과 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Build a matrix which scales by (sx, sy, sz)
D3DXMATRIX* WINAPI D3DXMatrixScaling
    ( D3DXMATRIX *pOut, FLOAT sx, FLOAT sy, FLOAT sz );
 
// Build a matrix which translates by (x, y, z)
D3DXMATRIX* WINAPI D3DXMatrixTranslation
    ( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z );
 
// Build a matrix which rotates around the X axis
D3DXMATRIX* WINAPI D3DXMatrixRotationX
    ( D3DXMATRIX *pOut, FLOAT Angle );
 
// Build a matrix which rotates around the Y axis
D3DXMATRIX* WINAPI D3DXMatrixRotationY
    ( D3DXMATRIX *pOut, FLOAT Angle );
 
// Build a matrix which rotates around the Z axis
D3DXMATRIX* WINAPI D3DXMatrixRotationZ
    ( D3DXMATRIX *pOut, FLOAT Angle );
cs

D3DMatrixScaling은 신축용 함수이며 Translation은 이동함수이며 D3DMatrixRotation(축) 함수는 축에 따라서 회전 시키는 함수입니다. Matrix 여러개를 사용하고 싶으면 4*4행렬끼리 곱한다음 적용시키면 되는데 이는 D3DMatrixMultiply함수를 이용하여 곱할 수 있습니다. 변형 함수들을 이용하여 행렬을 정해 준 뒤에 그 행렬을 이용하여 마지막에 SetTransform 함수를 이용하여 최종적인 모양을 출력시키도록합니다. 일반적으로 Scaling -> Rotation -> Translation 순서로 적용을 시키면 생각한 대로 보여줄 수 있습니다.


뷰 행렬을 설정합니다. 이 부분에서는 vEyePt, v LookatPt, vUpVec들을 성적합니다. 간단히 말해 보이는 위치 카메라 위치 등을 설정합니다.

이 부분들도 설정이 끝이나면 SetTransform을 통하여 위치를 잡아줍니다.


다음은 투영 행렬입니다. 3D에 있던 물체를 2D에 투영시키는 것입니다. 원근 투영은 멀리 있으면 작게 가까이 있으면 크게 하게 됩니다. 역시 이부분 또한 설정이 끝이나면 SetTransform을 통하여 위치를 잡아줍니다.


SetupMatrices함수에서는 하나라도 빠지면 디폴트 값이 들어오게됩니다.


제일 위에 있는 소스의 결과는 다음과 같이 나오게 됩니다.





다음 포스팅에서는 Light에 대해서 포스팅 하겠습니다.