블로그 이미지
대갈장군

calendar

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

Notice

2008. 2. 14. 06:48 프로그래밍/DirectX
이제까지는 빛을 고려하지 않았다. 모든 물체가 골고루 빛을 받는 것이 자동으로 설정되어 있었다. 이제부터는 진짜 실제와 같은 빛을 어떻게 만들어 내는지 한번 연구해 보자.

1. Light in Nature and Light in 3D
상상해보자. 실제로 태양에서 오는 빛을 컴퓨터가 완벽하게 재현하려면 얼마나 힘이든지를... 거의 불가능하고 거기다 이것을 실시간으로 한다는것은 말도 안된다.

고로 Direct3D에서는 실제 빛을 모방하는 차원에서만 빛을 만드는데 빛의 타입빛 소스의 타입을 정의 함으로써 실제 빛과 유사하게 보이는 빛을 만들어 낸다.

Types of Lighting
이건 앞에서 했던 건데, 세가지 종류의 빛이 있다. diffuse lighting, ambient lighting, specular lighting.

Diffuse Lighting은 정면에서 받는 빛을 말한다. 전등 한개 있는 방에서 손을 들이대었을때 손의 밝은 면에 비치는 빛을 말한다.

Ambient Lighting은 위의 빛과는 달리 반사되어 들어오는 모든 방향의 빛을 말하는데 이것은 위의 예에서 어두운 손바닥 부분에 들어오는 빛인데, 어두운 손바닥 부분에도 분명히 빛이 존재한다.

Specular Lighting은 빛이 물체에 닿고 반사 될때 나가는 빛을 말한다. 다음 그림을 보면 조금 이해가 쉽다.


Image 9.2 - Diffuse Light

Image 9.2 - Diffuse Light

Image 9.3 - Ambient Light

Image 9.3 - Ambient Light

Image 9.4 - Specular Light

Image 9.4 - Specular Light


Types of Light Source
허라... 그랬던가? OpenGL에서는 오직 위에서 살펴본 3가지 종류의 빛만 있는 줄 알았는데 그것이 아니라 빛 소스의 형태를 정의하는 것도 있었던 것인가? 아니면 있었는데 내가 정확히 몰랐던 것인가?

자, light source에는 4가지 타입이 있는데,
1. Ambient Light
2. Directional Light
3. Point Light
4. Spot Light

1-1. Ambient Light
자자, 일단 정리를 하자면, 위에서 본 세가지 형태의 빛은 물체의 입장에서 봤을때의 빛이다. 물체의 밝은면, 어두운면, 그리고 반사빛이죠. 하지만 이제부터 다루는 것은 빛의 입장에서 봤을때의 빛이다. 염두해두고 읽자.

Ambient light는 말그대로 Ambient light를 만든다. Ambient라는 단어의 의미는 둘러싼 이라는 의미로서 주변광이라고 한다. 이것은 특정한 방향에서 오는 빛이 아닌, 태양이 떠있을때 야외에 존재하는 빛과 같다.
 
1-2. Directional Light
이건 뭐 이름에서 바로 느낌이 온다. 방향성을 가진 빛이다. 어디서 온다는 것이 명확한 빛이죠. 이 빛이 설정되어 있다면 이 빛은 ambient와 diffuse그리고 specular light를 생성하게 된다. (물체의 입장에서) 왜냐면, 직사 광선이 물체에 비춰지면 일단 반사광 (specular light)가 생기고 정면을 쏴주니까 입사광(diffuse light) 혹은 분산광이 생기게 되고 또한 이것도 일종의 여러방향에서 오는 빛이므로 ambient light (주변광)을 만든다.

1-3. Point Light
Image 9.6 - Point Light

Image 9.6 - Point Light

간단하게 위의 그림으로 설명이 된다. 이 빛 또한 ambient, diffuse, specular 를 만들어 낼 것이다.

1-4. Spot Light
Image 9.7 - Spot Light

Image 9.7 - Spot Light

흠. 이것은 특수화된 빛의 종류인데 지정된 위치에서 지정된 방향으로 빛을 뿜는 것을 말한다. 그렇다면 이것이 Directional Light와 다른 점은 무엇인가? 규모의 차이인가? 그런 설명은 없으나, 내가 생각할때는 그렇다. 아마도 Spot Light는 정밀한 각도 조절 (빛의 분산각)이 가능하리라 본다.

1-5. Materials
어라 이건 위에 없던건데? :)

Image 9.8 - A Wooden Square

Image 9.8 - A Wooden Square

Image 9.9 - A Redwood Square

Image 9.9 - A Redwood Square

Image 9.10 - A Better Redwood Square

Image 9.10 - A Better Redwood Square

Image 9.11 - Purplewood?

Image 9.11 - Purplewood?
자, 위의 4개의 나무 텍스쳐가 입혀진 물체를 보자. 우선 9-8 그림은 그냥 일반적인 흰색 빛으로 비추었을 경우인데, 이때는 당연히 원래 물체의 색이 그대로 나타나게 된다.

이것은 빛이 없을때의 색상과 동일하다. 그렇다면 이제는 그림 9-9 처럼 사각형에 빨강색 속성을 넣어보자. 당연히 흰색 빛을 비추면 빨간색 속성을 가지는 사각형을 빨간색만 반사하고 고로 빨간색으로 보인다. 이때 여기다가 파랑색 조명을 주면 아무것도 보이지 않게 된다.

9-10 그림은 빨간색이 아닌 다른 색도 약간 조절해서 첨가한 것이다. 그림 9-11 은 파르스름한 빛을 비춘것이다. 그렇다면 9-11의 사각형은 무슨 색인가? 그 사각형은 아직 빨간색이다... 즉, 물체의 색상을 결정하는 것은 빛의 색상만이 아니고 물체의 색상도 기여를 한다는 점이다. 이 두가지가 썪여서 나타나게 되므로 색상을 결정하는 일은 항상 조심스럽다.

조언을 하자면, 기본적으로 빛의 색상은 늘 흰색 빛으로 하는 것이 머리가 덜 아플 것이다.

2. Vertex Normals
자, 다음과 같은 간단한 그림을 보면서 왜 이것이 필요한 가를 논해 보자꾸나.
Image 9.12 - A Diffusely Lit Square

Image 9.12 - A Diffusely Lit Square
 
배경이 검정색이 아니라서 조금 어색해 보이는데.. 우쨌든 Diffuse light로 비춰지는 저런 나무 판때기가 있다고 하자.

그러면 아래 그림처럼 물체를 기울인다면 어떻게 되어야 할까? 당연히 멀리 있는 (혹은 입사하는 빛과 경사가 커질수록) 어두워 져야 할 것이다.
Image 9.13 - Some Less Diffusely Lit Squares

Image 9.13 - Some Less Diffusely Lit Squares

바로 이것을 해결하기 위한 것이 Normal이다. 이 물체의 Normal은 이 물체의 표면에 수직한 선이 된다. (다음 그림)
Image 9.14 - The Squares and Their Normals

Image 9.14 - The Squares and Their Normals
이것이 왜 이렇게 되는지 이해가 되나? 당연히 그렇다... -_-

아래 그림은 조금 설명이 좋지 않은데 아마도 글쓴이가 잘 모르는 사람들에게 이해를 돕기 위해서 이렇게 했나보다.

입사하는 벡터 (빛의 한 가닥)은 벡터가 닿는 지점의 (surface) 법선 (normal vector)와의 곱으로 그 양이 계산되어 진다. (물리학 + 전자기학) 헐 이렇때 사용되네.. 헐헐...
Image 9.15 - Sizing Up the Normals

Image 9.15 - Sizing Up the Normals

하지만, 슬픈 소식이 있으니 바로 D3D는 알아서 이런 법선 벡터를 정의해주지 않는다는 것! 젠장.


3. Creating Lights
불행하게도.... 빛을 설정하고 적용하는 과정은 그닥 쉽지가 않단다. 다음과 같은 일련의 과정을 주욱 거쳐야 하는데,

1. Setting Up a New Flexible Vertex Format
2. light 켜기
3. Ambient light 설정(속성)
4. Diffuse light의 속성 설정 및 생성
5. Material 속성 설정 및 생성


아, 여기서는 상당히 정리 정돈을 잘해놓았구나. 이 지은이는 D3D에 대한 충분한 이해가 있구나... :)
아놔 젠장. 여기서만 두번 에러나서 컴퓨터 다시 껐다 켰네 젠장할... 이부분은 나중에 쓸까보다 콱 그냥. 소스 파일 코드에 texture 파일 이름 틀렸다. 쓰붕새

1. Setting Up a New Flexible Vertex Format
struct CUSTOMVERTEX {FLOAT X, Y, Z; D3DVECTOR NORMAL; FLOAT U, V;};
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)

새로 등장한 타입 D3DVECTOR는
typedef struct D3DVECTOR {
    float x, y, z;
} D3DVECTOR, *LPD3DVECTOR;

사실 걍 구조체.

2. Turning the Lighting On
불을 켜자.
d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE);

3. Setting the Ambient Light
Ambient light 추가 설치하는데 이 빛은 diffuse나 specular 빛이 없어도 은은하게 퍼지는 주변광이다. 명심하도록... 주변광일뿐 물체를 직접적으로 비추는 빛은 아니다. (Not spot light)

d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));    // ambient light

4. Creating and Setting the Diffuse Light

// this is the function that sets up the lights and materials
void init_light(void)
{
    D3DLIGHT9 light;    // create the light struct

    ZeroMemory(&light, sizeof(light));    // clear out the light struct for use
    light.Type = D3DLIGHT_DIRECTIONAL;    // make the light type 'directional light'
    light.Diffuse.r = 0.5f;    // .5 red
    light.Diffuse.g = 0.5f;    // .5 green
    light.Diffuse.b = 0.5f;    // .5 blue
    light.Diffuse.a = 1.0f;    // full alpha (we'll get to that soon)

    D3DVECTOR vecDirection = {-1.0f, -0.3f, -1.0f};    // the direction of the light
    light.Direction = vecDirection;    // set the direction

    d3ddev->SetLight(0, &light);    // send the light struct properties to light #0
    d3ddev->LightEnable(0, TRUE);    // turn on light #0

    return;
}

이제 뭔가 좀 나오는것 같아 보이는데 여기서 새로 등장한 D3DLIGHT9이라는 구조체는 빛의 속성에 대한 구조체로 각종 정보를 저장할 수 있다.

Type인자에서 빛의 종류를 결정하는데 다음과 같은 인자가 들어갈 수 있다.
Value Description
D3DLIGHT_DIRECTIONAL Creates a directional light, a light that comes from everywhere at once, but shines only in one direction.
D3DLIGHT_POINT Creates a point light, a light that emanates equally in all directions from one exact point.
D3DLIGHT_SPOT Creates a spot light, a light that emanates in one direction from one exact point.
[Close Table]

그 다음에 Diffuse 인자에 보면 다시 r,g,b,a로 나뉘어 색상을 정의 가능하게 해놓았고 (빛의 색) Direction인자에서는 어디로 비출것인가를 결정한다.

다음 두개의 함수인 SetLight(0, &light)와 LightEnable(0, TRUE)는 0 번호의 빛에 사용자가 만든 light 구조체를
대입하고 0번 빛을 활성화 하라는 의미다.

5. Creating and Setting the Material

// this is the function that sets up the lights and materials
void init_light(void)
{
    D3DLIGHT9 light;    // create the light struct
    D3DMATERIAL9 material;    // create the material struct

    ZeroMemory(&light, sizeof(light));    // clear out the struct for use
    light.Type = D3DLIGHT_DIRECTIONAL;    // make the light type 'directional light'
    light.Diffuse.r = 0.5f;    // .5 red
    light.Diffuse.g = 0.5f;    // .5 green
    light.Diffuse.b = 0.5f;    // .5 blue
    light.Diffuse.a = 1.0f;    // full alpha (we'll get to that soon)

    D3DVECTOR vecDirection = {-1.0f, -0.3f, -1.0f};    // the direction of the light
    light.Direction = vecDirection;    // set the direction

    d3ddev->SetLight(0, &light);    // send the light struct properties to light #0
    d3ddev->LightEnable(0, TRUE);    // turn on light #0

    ZeroMemory(&material, sizeof(D3DMATERIAL9));    // clear out the struct for use
    material.Diffuse.r = material.Ambient.r = 1.0f;    // set the material to full red
    material.Diffuse.g = material.Ambient.g = 1.0f;    // set the material to full green
    material.Diffuse.b = material.Ambient.b = 1.0f;    // set the material to full blue
    material.Diffuse.a = material.Ambient.a = 1.0f;    // set the material to full alpha

    d3ddev->SetMaterial(&material);    // set the globably-used material to &material


    return;
}

이제 마지막 단계인 material 설정인데 각 점마다 색상을 주는 방식과는 확연히 다르다. 한번 material을 설정하면 바꾸기 전까지는 계속 그 색상으로 모든 점들이 그려지게 된다.

새로운 구조체가 또 등장을 했는데 D3DMATERIAL9이다. 그리고 여기에 새로운 멤버인 material.Diffuse가 있는데 이 색이 바로 diffuse 빛이 들어올때 어떤 색으로 반사 할 것인가를 지정한다.

이와 유사하게 material.Ambient가 있는데 이것은 ambient light가 들어올때 어떤 색으로 반사할지를 지정한다. 아주 중요한 점은 이 둘은 두개의 다른 빛의 종류에 서로 각각 독립적으로 반사한다는 점을 명심하라.

쏘쓰 코뜨

// include the basic windows header files and the Direct3D header file
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
#include <d3dx9.h>

// define the screen resolution and keyboard macros
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

// include the Direct3D Library files
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")

// global declarations
LPDIRECT3D9 d3d;    // the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev;    // the pointer to the device class
LPDIRECT3DVERTEXBUFFER9 t_buffer = NULL;    // the pointer to the vertex buffer

// texture declarations
LPDIRECT3DTEXTURE9 texture_1;    // our first texture

// function prototypes
void initD3D(HWND hWnd);    // sets up and initializes Direct3D
void render_frame(void);    // renders a single frame
void cleanD3D(void);    // closes Direct3D and releases memory
void init_graphics(void);    // 3D declarations
void init_light(void);    // sets up the light and the material

struct CUSTOMVERTEX {FLOAT X, Y, Z; D3DVECTOR NORMAL; FLOAT U, V;};
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)

// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    HWND hWnd;
    WNDCLASSEX wc;

    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = L"WindowClass";

    RegisterClassEx(&wc);

    hWnd = CreateWindowEx(NULL, L"WindowClass", L"Our Direct3D Program",
                          WS_EX_TOPMOST | WS_POPUP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
                          NULL, NULL, hInstance, NULL);

    ShowWindow(hWnd, nCmdShow);

    // set up and initialize Direct3D
    initD3D(hWnd);

    // enter the main loop:

    MSG msg;

    while(TRUE)
    {
        DWORD starting_point = GetTickCount();

        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                break;

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        render_frame();

        // check the 'escape' key
        if(KEY_DOWN(VK_ESCAPE))
            PostMessage(hWnd, WM_DESTROY, 0, 0);

        while ((GetTickCount() - starting_point) < 25);
    }

    // clean up DirectX and COM
    cleanD3D();

    return msg.wParam;
}


// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            } break;
    }

    return DefWindowProc (hWnd, message, wParam, lParam);
}


// this function initializes and prepares Direct3D for use
void initD3D(HWND hWnd)
{
    d3d = Direct3DCreate9(D3D_SDK_VERSION);

    D3DPRESENT_PARAMETERS d3dpp;

    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.Windowed = FALSE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = hWnd;
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
    d3dpp.BackBufferWidth = SCREEN_WIDTH;
    d3dpp.BackBufferHeight = SCREEN_HEIGHT;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    // create a device class using this information and the info from the d3dpp stuct
    d3d->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd,
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &d3dpp,
                      &d3ddev);

    init_graphics();    // call the function to initialize the cube
    init_light();    // call the function to initialize the light and material

    d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE);    // turn on the 3D lighting
    d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer
    d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));    // ambient light

    return;
}


// this is the function used to render a single frame
void render_frame(void)
{
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

    d3ddev->BeginScene();

    // select which vertex format we are using
    d3ddev->SetFVF(CUSTOMFVF);

    // set the view transform
    D3DXMATRIX matView;    // the view transform matrix
    D3DXMatrixLookAtLH(&matView,
    &D3DXVECTOR3 (0.0f, 8.0f, 25.0f),    // the camera position
    &D3DXVECTOR3 (0.0f, 0.0f, 0.0f),      // the look-at position
    &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));    // the up direction
    d3ddev->SetTransform(D3DTS_VIEW, &matView);

    // set the projection transform
    D3DXMATRIX matProjection;    // the projection transform matrix
    D3DXMatrixPerspectiveFovLH(&matProjection,
                               D3DXToRadian(45),    // the horizontal field of view
                               (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
                               1.0f,    // the near view-plane
                               100.0f);    // the far view-plane
    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);

    // set the world transform
    static float index = 0.0f; index+=0.03f;    // an ever-increasing float value
    D3DXMATRIX matRotateY;    // a matrix to store the rotation for each triangle
    D3DXMatrixRotationY(&matRotateY, index);    // the rotation matrix
    d3ddev->SetTransform(D3DTS_WORLD, &(matRotateY));    // set the world transform

    // select the vertex buffer to display
    d3ddev->SetStreamSource(0, t_buffer, 0, sizeof(CUSTOMVERTEX));

    // set the texture
    d3ddev->SetTexture(0, texture_1);

    // draw the textured square
    d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
    d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 2);
    d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 8, 2);
    d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 12, 2);
    d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 16, 2);
    d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 20, 2);

    d3ddev->EndScene();

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

    return;
}


// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
    t_buffer->Release();    // close and release the vertex buffer
    texture_1->Release();    // close and release the texture
    d3ddev->Release();    // close and release the 3D device
    d3d->Release();    // close and release Direct3D

    return;
}


// this is the function that puts the 3D models into video RAM
void init_graphics(void)
{
    // load the texture we will use
    D3DXCreateTextureFromFile(d3ddev,
                              L"wood1.png",
                              &texture_1);

    // create the vertices using the CUSTOMVERTEX struct
    CUSTOMVERTEX t_vert[] =
    {
        // side 1
        { -3.0f, 3.0f, -3.0f, 0, 0, -1, 0, 1, },
        { 3.0f, 3.0f, -3.0f, 0, 0, -1, 1, 1, },
        { -3.0f, -3.0f, -3.0f, 0, 0, -1, 0, 0, },
        { 3.0f, -3.0f, -3.0f, 0, 0, -1, 1, 0, },

        // side 2
        { -3.0f, 3.0f, 3.0f, 0, 0, 1, 0, 1, },
        { -3.0f, -3.0f, 3.0f, 0, 0, 1, 0, 0, },
        { 3.0f, 3.0f, 3.0f, 0, 0, 1, 1, 1, },
        { 3.0f, -3.0f, 3.0f, 0, 0, 1, 1, 0, },

        // side 3
        { -3.0f, 3.0f, 3.0f, 0, 1, 0, 0, 1, },
        { 3.0f, 3.0f, 3.0f, 0, 1, 0, 1, 1, },
        { -3.0f, 3.0f, -3.0f, 0, 1, 0, 0, 0, },
        { 3.0f, 3.0f, -3.0f, 0, 1, 0, 1, 0, },

        // side 4
        { -3.0f, -3.0f, 3.0f, 0, -1, 0, 0, 1, },
        { -3.0f, -3.0f, -3.0f, 0, -1, 0, 0, 0, },
        { 3.0f, -3.0f, 3.0f, 0, -1, 0, 1, 1, },
        { 3.0f, -3.0f, -3.0f, 0, -1, 0, 1, 0, },

        // side 5
        { 3.0f, 3.0f, -3.0f, 1, 0, 0, 1, 0, },
        { 3.0f, 3.0f, 3.0f, 1, 0, 0, 1, 1, },
        { 3.0f, -3.0f, -3.0f, 1, 0, 0, 0, 0, },
        { 3.0f, -3.0f, 3.0f, 1, 0, 0, 0, 1, },

        // side 6
        { -3.0f, 3.0f, -3.0f, -1, 0, 0, 1, 0, },
        { -3.0f, -3.0f, -3.0f, -1, 0, 0, 0, 0, },
        { -3.0f, 3.0f, 3.0f, -1, 0, 0, 1, 1, },
        { -3.0f, -3.0f, 3.0f, -1, 0, 0, 0, 1, },
    };    // that reminds me of programming in binary!


    // create a vertex buffer interface called t_buffer
    d3ddev->CreateVertexBuffer(24*sizeof(CUSTOMVERTEX),
                               0,
                               CUSTOMFVF,
                               D3DPOOL_MANAGED,
                               &t_buffer,
                               NULL);

    VOID* pVoid;    // a void pointer

    // lock t_buffer and load the vertices into it
    t_buffer->Lock(0, 0, (void**)&pVoid, 0);
    memcpy(pVoid, t_vert, sizeof(t_vert));
    t_buffer->Unlock();

    return;
}


// this is the function that sets up the lights and materials
void init_light(void)
{
    D3DLIGHT9 light;    // create the light struct
    D3DMATERIAL9 material;    // create the material struct

    ZeroMemory(&light, sizeof(light));    // clear out the struct for use
    light.Type = D3DLIGHT_DIRECTIONAL;    // make the light type 'directional light'
    light.Diffuse.r = 0.5f;    // .5 red
    light.Diffuse.g = 0.5f;    // .5 green
    light.Diffuse.b = 0.5f;    // .5 blue
    light.Diffuse.a = 1.0f;    // full alpha (we'll get to that soon)

    D3DVECTOR vecDirection = {-1.0f, -0.3f, -1.0f};    // the direction of the light
    light.Direction = vecDirection;    // set the direction

    d3ddev->SetLight(0, &light);    // send the light struct properties to light #0
    d3ddev->LightEnable(0, TRUE);    // turn on light #0

    ZeroMemory(&material, sizeof(D3DMATERIAL9));    // clear out the struct for use
    material.Diffuse.r = material.Ambient.r = 1.0f;    // set the material to full red
    material.Diffuse.g = material.Ambient.g = 1.0f;    // set the material to full green
    material.Diffuse.b = material.Ambient.b = 1.0f;    // set the material to full blue
    material.Diffuse.a = material.Ambient.a = 1.0f;    // set the material to full alpha

    d3ddev->SetMaterial(&material);    // set the globably-used material to &material

    return;
}


결과


Image 9.17 - A Wooden Crate

Image 9.17 - A Wooden Crate






posted by 대갈장군