光照

#include <d3d9.h>
#pragma warning( disable : 4996 ) // disable deprecated warning 
#include <strsafe.h>
#pragma warning( default : 4996 )
#include <d3dx9math.h>


bool InitD3D(HWND hWnd, bool fullscreen);
void RenderScene();
void ShutDown();
bool InitializeObjects();
void SetupLight(LPDIRECT3DDEVICE9, UINT);


LPDIRECT3D9 g_D3D = NULL;
LPDIRECT3DDEVICE9 g_D3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_VertexBuffer = NULL;   //顶点缓存接口

struct CUSTOMVERTEX
{
    FLOAT _x, _y, _z;             
    FLOAT  _nx,_ny,_nz;                   
    CUSTOMVERTEX(FLOAT x, FLOAT y, FLOAT z, FLOAT nx,FLOAT ny,FLOAT nz)
        : _x(x), _y(y), _z(z), _nx(nx), _ny(ny), _nz(nz){}
};

#define D3DFVF_VERTEX (D3DFVF_XYZ  | D3DFVF_NORMAL)
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
        break;
    case WM_KEYUP:
        if (wParam == VK_ESCAPE)
            PostQuitMessage(0);
        break;
    default:
        break;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevInst, LPSTR cmdLine, int show)
{
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0, 0, hInst, NULL, NULL, NULL, NULL, L"UGPDX", NULL };

    RegisterClassEx(&wc);

    HWND hWnd = CreateWindow(L"UGPDX", L"Blank D3D Window", WS_OVERLAPPEDWINDOW, 100, 100, 640, 480, NULL, NULL, wc.hInstance, NULL);

    if (InitD3D(hWnd, false))
    {
        ShowWindow(hWnd, SW_SHOWDEFAULT);
        UpdateWindow(hWnd);

        MSG msg;
        ZeroMemory(&msg, sizeof(msg));

        while (msg.message != WM_QUIT)
        {
            if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            else
            {
                RenderScene();
            }
        }
    }

    ShutDown();
    UnregisterClass(L"UGPDX", wc.hInstance);
    return 0;
}

bool InitD3D(HWND hWnd, bool fullscreen)
{
    D3DDISPLAYMODE displayMode;

    g_D3D = Direct3DCreate9(D3D9b_SDK_VERSION);

    if (g_D3D == NULL)
        return false;

    if (FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
        return false;

    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));

    if (fullscreen)
    {
        d3dpp.Windowed = FALSE;
        d3dpp.BackBufferWidth = 640;
        d3dpp.BackBufferHeight = 480;
    }
    else
        d3dpp.Windowed = TRUE;

    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = displayMode.Format;

    if (FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_D3DDevice)))
        return false;

    if (!InitializeObjects()) return false;

    return true;

}

void RenderScene()
{
    g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

    g_D3DDevice->BeginScene();

    //reset lighting
    if (::GetAsyncKeyState(0x31) & 0x8000f)
    {
        SetupLight(g_D3DDevice, 1);
    }
    if (::GetAsyncKeyState(0x32) & 0x8000f)
    {
        SetupLight(g_D3DDevice, 2);
    }
    if (::GetAsyncKeyState(0x33) & 0x8000f)
    {
        SetupLight(g_D3DDevice, 3);
    }

    //set world Trans Matrix
    D3DXMATRIX matWorld;
    D3DXMatrixRotationY(&matWorld, ::timeGetTime() / 500.0f);
    g_D3DDevice->SetTransform(D3DTS_WORLD, &matWorld);

    //print 
    g_D3DDevice->SetStreamSource(0, g_VertexBuffer, 0, sizeof(CUSTOMVERTEX));
    g_D3DDevice->SetFVF(D3DFVF_VERTEX);
    g_D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4);
    g_D3DDevice->EndScene();

    g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}

void ShutDown()
{
    if (g_D3DDevice != NULL)
        g_D3DDevice->Release();
    if (g_D3D != NULL)
        g_D3D->Release();
    if (g_VertexBuffer != NULL)
        g_VertexBuffer->Release();

    g_D3D = NULL;
    g_D3DDevice = NULL;
    g_VertexBuffer = NULL;
}

bool InitializeObjects()
{

    //创建顶点缓存,填充顶点数据
    if (FAILED(g_D3DDevice->CreateVertexBuffer(12 * sizeof(CUSTOMVERTEX), 0, D3DFVF_VERTEX, D3DPOOL_DEFAULT, &g_VertexBuffer, NULL)))
        return false;

    CUSTOMVERTEX *pVertices = NULL;
    if (FAILED(g_VertexBuffer->Lock(0, 0, (void**)&pVertices, 0)))
        return false;

    pVertices[0] = CUSTOMVERTEX(-1, 0, -1, 0,0.707f,-0.707f);
    pVertices[1] = CUSTOMVERTEX(0,1,0,0,0.707f,-0.707f);
    pVertices[2] = CUSTOMVERTEX(1,0,-1,0,0.707f,-0.707f);

    pVertices[3] = CUSTOMVERTEX(-1,0,1,-0.707f,0.707f,0);
    pVertices[4] = CUSTOMVERTEX(0,1,0,-0.707f,0.707f,0);
    pVertices[5] = CUSTOMVERTEX(-1,0,-1,-0.707f,0.707f,0);

    pVertices[6] = CUSTOMVERTEX(1,0,-1,0.707f,0.707f,0);
    pVertices[7] = CUSTOMVERTEX(0,1,0,0.707f,0.707f,0);
    pVertices[8] = CUSTOMVERTEX(1,0,1, 0,0.707f, 0.707f);

    pVertices[9] = CUSTOMVERTEX(1,0,1, 0,0.707f, 0.707f);
    pVertices[10] = CUSTOMVERTEX(0,1,0, 0,0.707f, 0.707f);
    pVertices[11] = CUSTOMVERTEX(-1,0,1, 0,0.707f, 0.707f);
    g_VertexBuffer->Unlock();

    //set Material
    D3DMATERIAL9 mtrl;
    ::ZeroMemory(&mtrl, sizeof(mtrl));
    mtrl.Ambient = D3DXCOLOR(1, 1, 1, 1);
    mtrl.Diffuse = D3DXCOLOR(1, 1, 1, 1);
    mtrl.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1);
    mtrl.Emissive = D3DXCOLOR(0, 0, 0, 1);
    g_D3DDevice->SetMaterial(&mtrl);

    //set light
    SetupLight(g_D3DDevice, 1);
    g_D3DDevice->SetRenderState(D3DRS_LIGHTING, true);
    g_D3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, true);
    g_D3DDevice->SetRenderState(D3DRS_SPECULARENABLE, true);

    //set view transform Matrix
    D3DXMATRIX matView;
    D3DXVECTOR3 vEye(0, 1, -5);
    D3DXVECTOR3 vAt(0, 0, 0);
    D3DXVECTOR3 vUp(0, 1, 0);
    D3DXMatrixLookAtLH(&matView, &vEye, &vAt, &vUp);
    g_D3DDevice->SetTransform(D3DTS_VIEW, &matView);

    //set Projection matrix
    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4.0f, 1, 1, 1000);
    g_D3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
    return true;
}

void SetupLight(LPDIRECT3DDEVICE9 pd3dDevice, UINT nType)
{
    static D3DLIGHT9 light;
    ::ZeroMemory(&light, sizeof(light));

    switch (nType)
    {
    case 1:
        light.Type = D3DLIGHT_POINT;
        light.Ambient = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1);
        light.Diffuse = D3DXCOLOR(1, 1, 1, 1);
        light.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1);
        light.Position = D3DXVECTOR3(-300, 0, 0);
        light.Attenuation0 = 1;
        light.Attenuation1 = 0;
        light.Attenuation2 = 0;
        light.Range = 300;
        break;
    case 2:
        light.Type = D3DLIGHT_DIRECTIONAL;
        light.Ambient = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1);
        light.Diffuse = D3DXCOLOR(1, 1, 1, 1);
        light.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1);
        light.Direction = D3DXVECTOR3(1, 0, 0);
        break;
    case 3:
        light.Type = D3DLIGHT_SPOT;
        light.Position = D3DXVECTOR3(0, 300, 0);
        light.Position = D3DXVECTOR3(0, -1, 0);
        light.Ambient = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1.0f);
        light.Diffuse = D3DXCOLOR(1, 1, 1, 1);
        light.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 0.3f);
        light.Attenuation0 = 1;
        light.Attenuation1 = 0;
        light.Attenuation2 = 0;
        light.Range = 300;
        light.Falloff = 0.1f;
        light.Phi = D3DX_PI / 3.0f;
        light.Theta = D3DX_PI / 6.0f;
        break;

    default:
        break;
    }

    g_D3DDevice->SetLight(0, &light);
    g_D3DDevice->LightEnable(0, true);
    g_D3DDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(92, 92, 92));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值