관리 메뉴

Kim's Programming

[다이렉트SDK 예제]DirectX Tutorial4 - Lighting 본문

Programming/DirectX

[다이렉트SDK 예제]DirectX Tutorial4 - Lighting

Programmer. 2016. 4. 15. 18:41

이번 포스팅에서는 Lighting에 대해서 포스팅합니다. Lighting은 빛에 대한 내용을 포스팅합니다.


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
//-----------------------------------------------------------------------------
// File: Lights.cpp
//
// Desc: Rendering 3D geometry is much more interesting when dynamic lighting
//       is added to the scene. To use lighting in D3D, you must create one or
//       Lights, setup a material, and make sure your geometry contains surface
//       normals. Lights may have a position, a color, and be of a certain type
//       such as directional (light comes from one direction), point (light
//       comes from a specific x,y,z coordinate and radiates in all directions)
//       or spotlight. Materials describe the surface of your geometry,
//       specifically, how it gets lit (diffuse color, ambient color, etc.).
//       Surface normals are part of a vertex, and are needed for the D3D's
//       internal lighting calculations.
//
// 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 )
 
 
 
 
//-----------------------------------------------------------------------------
// 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
 
// A structure for our custom vertex type. We added a normal, and omitted the
// color (which is provided by the material)
struct CUSTOMVERTEX
{
    D3DXVECTOR3 position; // The 3D position for the vertex
    D3DXVECTOR3 normal;   // The surface normal for the vertex        /Light를 사용하기 위해서는 반드시 Normal 값을 가져야함.
};
 
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)
 
 
 
 
//-----------------------------------------------------------------------------
// 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. Since we are now
    // using more complex geometry, we will create a device with a zbuffer.
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
 
    // 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
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
 
    // Turn on the zbuffer
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );//겹친 객체들의 z를 비교하여 앞쪽에 있는 색을 출력할 수 있도록 만들어줌. 끄면 나중에 칠한게 앞쪽으로 옴
 
    return S_OK;
}
 
 
 
 
//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: Creates the scene geometry
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
    // Create the vertex buffer.
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50 * * sizeof( CUSTOMVERTEX ),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer. We are algorithmically generating a cylinder
    // here, including the normals, which are used for lighting.
    CUSTOMVERTEX* pVertices;
    if( FAILED( g_pVB->Lock( 00, ( void** )&pVertices, ) ) )
        return E_FAIL;
    for( DWORD i = 0; i < 50; i++ )
    {
        FLOAT theta = ( * D3DX_PI * i ) / ( 50 - );
        pVertices[* i + 0].position = D3DXVECTOR3( sinf( theta ), -1.0f, cosf( theta ) );
        pVertices[* i + 0].normal = D3DXVECTOR3( sinf( theta ), 0.0f, cosf( theta ) );
        pVertices[* i + 1].position = D3DXVECTOR3( sinf( theta ), 1.0f, cosf( theta ) );
        pVertices[* i + 1].normal = D3DXVECTOR3( sinf( theta ), 0.0f, cosf( theta ) );
    }
    g_pVB->Unlock();
 
    return S_OK;
}
 
 
 
 
//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if( g_pVB != 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()
{
    // Set up world matrix
    D3DXMATRIXA16 matWorld;
    D3DXMatrixIdentity( &matWorld );
    //D3DXMatrixRotationX( &matWorld, timeGetTime() / 500.0f );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
 
    // 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 );
}
 
 
 
 
//-----------------------------------------------------------------------------
// Name: SetupLights()
// Desc: Sets up the Lights and materials for the scene.
//-----------------------------------------------------------------------------
VOID SetupLights()
{
    // Set up a material. The material here just has the diffuse and ambient
    // colors set to yellow. Note that only one material can be used at a time.
    D3DMATERIAL9 mtrl;                                                    //반사에 대한 색깔. 
    ZeroMemory( &mtrl, sizeof( D3DMATERIAL9 ) );
    mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;                                //Diffuse가 대표적 색깔.  
    mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
    mtrl.Diffuse.b = mtrl.Ambient.b = 1.0f;
    mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
    g_pd3dDevice->SetMaterial( &mtrl );                                    //Material을 바름
 
    // Set up a white, directional light, with an oscillating direction.
    // Note that many Lights may be active at a time (but each one slows down
    // the rendering of our scene). However, here we are just using one. Also,
    // we need to set the D3DRS_LIGHTING renderstate to enable lighting
    D3DXVECTOR3 vecDir;
    D3DLIGHT9 light;
    ZeroMemory( &light, sizeof( D3DLIGHT9 ) );
    light.Type = D3DLIGHT_DIRECTIONAL;                                    // D3DLIGHT_DIRECTIONAL: 태양빛 처럼 감쇠값이 없고 여러방향으로 감 위치는 중요 안함.
    light.Diffuse.r = 1.0f;                                                // D3DLIGHT_POINT: 조명처럼 감쇄값이 있고 여러방향으로 감 위치는 중요함.
    light.Diffuse.g = 1.0f;                                                
    light.Diffuse.b = 1.0f;
    vecDir = D3DXVECTOR3( cosf( timeGetTime() / 350.0f ),
                          1.0f,
                          sinf( timeGetTime() / 350.0f ) );
    D3DXVec3Normalize( ( D3DXVECTOR3* )&light.Direction, &vecDir );
    light.Range = 1000.0f;
    g_pd3dDevice->SetLight( 0&light );                                // 0번에 넣어서
    g_pd3dDevice->LightEnable( 0, TRUE );                                // 조명을 활성화 함. --> 조명을 여러개 해서 할 수 있음
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );                //--> 조명 킨다 만다 결정
 
    // Finally, turn on some ambient light.
    g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );            //Ambient Color : 은은하게 빛을 비춰주는 색깔(커텐 사이를 뚫고 오는 형태 같은 빛->기본조명)
}
 
 
 
 
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
    // Clear the backbuffer and the zbuffer
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
                         D3DCOLOR_XRGB( 00255 ), 1.0f, );
 
    // Begin the scene
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // Setup the Lights and materials
        SetupLights();
 
        // 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* 50 - );
 
        // 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 04: Lights",
                              WS_OVERLAPPEDWINDOW, 100100300300,
                              NULL, NULL, wc.hInstance, NULL );
 
    // Initialize Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        // Create the 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



3D geometry 렌더링은 씬에 빛이 추가되었을때 더 좋아 집니다. D3D에서 빛을 사용하는 것은 하나를 더 만들거나 빛을 만들어야 하고, 재질을 설정하고 당신의 geometry가 표면 백터를 포함해야 합니다. 빛은 위치, 색, 방향같은 타입을 포함하며(한방향으로 오는 방향성), 점(빛이 오는 특정 x,y,z 좌표와 모든 방향으로 방사되는것) 또는 스폿 라이트가지고 있습니다. 재질은 당신의 geometry의 표면을 묘사하며 특정하게 어떻게 빛을 받는지?(색의 퍼짐, 주변색 등) 표면 벡터는 vertex의 일부이며 D3D의 내부 빛 계산에 필요합니다.



전역변수


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//-----------------------------------------------------------------------------
// 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
 
// A structure for our custom vertex type. We added a normal, and omitted the
// color (which is provided by the material)
struct CUSTOMVERTEX
{
    D3DXVECTOR3 position; // The 3D position for the vertex
    D3DXVECTOR3 normal;   // The surface normal for the vertex        /Light를 사용하기 위해서는 반드시 Normal 값을 가져야함.
};
 
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)
cs


앞에와는 다르게 CUSTOMVERTEX의 모습이 달라졌습니다. position과 normal을 가지고 있는데 Light를 사용하기 위해서는 normal값을 포함하여야 하기 떄문에 normal Vector를 위한 변수를 구조체에 포함 시켰습니다.



InitD3D()


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
    //-----------------------------------------------------------------------------
    // 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. Since we are now
        // using more complex geometry, we will create a device with a zbuffer.
        D3DPRESENT_PARAMETERS d3dpp;
        ZeroMemory( &d3dpp, sizeof( d3dpp ) );
        d3dpp.Windowed = TRUE;
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
        d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
        d3dpp.EnableAutoDepthStencil = TRUE;
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
 
        // 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
        g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
 
        // Turn on the zbuffer
        g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );//겹친 객체들의 z를 비교하여 앞쪽에 있는 색을 출력할 수 있도록 만들어줌. 끄면 나중에 칠한게 앞쪽으로 옴
 
        return S_OK;
    }
cs


앞 예제들과는 다르게  CreateDevice에 이용되는 그래픽 카드 생성에 들어가는 변수 D3DPRESENT_PARAMETERS 구조체에 2개의 변수가 더 들어갑니다. EnableAutoDepthStencilAutoDepthStencilFormat이 더 들어갔습니다. EnableAutoDepthStencil을 TRUE를 주어서 깊이 버퍼를 사용한다고 명시해주며 AutoDepthStencilFormat은 표면의 스텐실 깊이를 설정해 줍니다.


또 SetRender을 이용하여 컬링모드를 앞과 다르게 꺼주었고 Z버퍼를 활성화 시켜주었습니다. Z 버퍼란 겹친 객체들의 z값을 비교하여 앞쪽에 있는 대상의 색을 출력할 수 있도록 하는 것입니다. 이를 끄면 앞뒤가 겹치거나 안맞는 결과가 생기게 됩니다.


 

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
//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: Creates the scene geometry
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
    // Create the vertex buffer.
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50 * * sizeof( CUSTOMVERTEX ),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }
 
    // Fill the vertex buffer. We are algorithmically generating a cylinder
    // here, including the normals, which are used for lighting.
    CUSTOMVERTEX* pVertices;
    if( FAILED( g_pVB->Lock( 00, ( void** )&pVertices, ) ) )
        return E_FAIL;
    for( DWORD i = 0; i < 50; i++ )
    {
        FLOAT theta = ( * D3DX_PI * i ) / ( 50 - );
        pVertices[* i + 0].position = D3DXVECTOR3( sinf( theta ), -1.0f, cosf( theta ) );
        pVertices[* i + 0].normal = D3DXVECTOR3( sinf( theta ), 0.0f, cosf( theta ) );
        pVertices[* i + 1].position = D3DXVECTOR3( sinf( theta ), 1.0f, cosf( theta ) );
        pVertices[* i + 1].normal = D3DXVECTOR3( sinf( theta ), 0.0f, cosf( theta ) );
    }
    g_pVB->Unlock();
 
    return S_OK;
}
cs


InitGeometry()는 전에는 삼각형 점들을 이용하여 하나하나 만들어서 조합해서 만들고는 했는데 이번에는 미리 CUSTOMVERTEX 갯수를 미리 지정해둔 다음 이 만큼의 점들을 알고리즘을 통해서 원통을 생성합니다.



SetupLights()


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
//-----------------------------------------------------------------------------
// Name: SetupLights()
// Desc: Sets up the Lights and materials for the scene.
//-----------------------------------------------------------------------------
VOID SetupLights()
{
    // Set up a material. The material here just has the diffuse and ambient
    // colors set to yellow. Note that only one material can be used at a time.
    D3DMATERIAL9 mtrl;                                                    //반사에 대한 색깔. 
    ZeroMemory( &mtrl, sizeof( D3DMATERIAL9 ) );
    mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;                                //Diffuse가 대표적 색깔.  
    mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
    mtrl.Diffuse.b = mtrl.Ambient.b = 1.0f;
    mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
    g_pd3dDevice->SetMaterial( &mtrl );                                    //Material을 바름
 
    // Set up a white, directional light, with an oscillating direction.
    // Note that many Lights may be active at a time (but each one slows down
    // the rendering of our scene). However, here we are just using one. Also,
    // we need to set the D3DRS_LIGHTING renderstate to enable lighting
    D3DXVECTOR3 vecDir;
    D3DLIGHT9 light;
    ZeroMemory( &light, sizeof( D3DLIGHT9 ) );
    light.Type = D3DLIGHT_DIRECTIONAL;                                    // D3DLIGHT_DIRECTIONAL: 태양빛 처럼 감쇠값이 없고 여러방향으로 감 위치는 중요 안함.
    light.Diffuse.r = 1.0f;                                                // D3DLIGHT_POINT: 조명처럼 감쇄값이 있고 여러방향으로 감 위치는 중요함.
    light.Diffuse.g = 1.0f;                                                
    light.Diffuse.b = 1.0f;
    vecDir = D3DXVECTOR3( cosf( timeGetTime() / 350.0f ),
                          1.0f,
                          sinf( timeGetTime() / 350.0f ) );
    D3DXVec3Normalize( ( D3DXVECTOR3* )&light.Direction, &vecDir );
    light.Range = 1000.0f;
    g_pd3dDevice->SetLight( 0&light );                                // 0번에 넣어서
    g_pd3dDevice->LightEnable( 0, TRUE );                                // 조명을 활성화 함. --> 조명을 여러개 해서 할 수 있음
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );                //--> 조명 킨다 만다 결정
 
    // Finally, turn on some ambient light.
    g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );            //Ambient Color : 은은하게 빛을 비춰주는 색깔(커텐 사이를 뚫고 오는 형태 같은 빛->기본조명)
}
cs



SetupLights()함수는 빛에 대해 설정하는 함수입니다. D3DMATERIAL9 구조체를 이용해서 반사에 대한 색을 설정합니다. Diffuse가 대표적인 색이며 그외에 더 있습니다. 색의 세기를 정하는 부분입니다.  동일하게 섞어 주므로 결과적으로는 하얀색이 나오게 됩니다. 설정이 끝나면 SetMaterial을 이용하여 Material을 발라줍니다.


다음은 빛에 대한 설정을 합니다. D3DLIGHT9 구조체의 객체를 만든다음 초기화를 해준뒤 light 종류, 빛 등등을 설정해 줍니다.


SetLight함수를 통해서 빛을 설정해주고, LightEnable함수를 통해서 빛을 활성화 할지 말지를 설정해주며, SetRenderState를 통해서 빛을 켜 줍니다. 마지막으로 SetRenderState(D3DRS_AMBIENT를 통해서는 은은하게 빛을 비춰 주는 색을 의미합니다.


하지만 Light는 대부분 Texture에서 처리하지 실시간으로 빛을 처리 하지는 않습니다.  이상으로 포스팅을 마치겠습니다.


마지막은 Ligting의 실행 입니다.