Direct3D 光照练习
程序员文章站
2022-07-13 10:10:45
...
我什么都不想说,就是来一张结果图撒
代码
// tWinMain.cpp : Defines the entry point for the application.
#include "windows.h"
#include "tchar.h"
#include "d3d9.h"
#include "d3dx9.h"
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "winmm.lib")
#define WNDWIDTH 800
#define WNDHEIGHT 600
// Global Variables:
HWND g_hWnd = NULL;
LPDIRECT3D9 g_pDirect3D = NULL;
LPDIRECT3DDEVICE9 g_pDirect3DDevice = NULL;
LPD3DXFONT g_pD3DXFont = NULL;
LPD3DXMESH g_teapot = NULL;
LPD3DXMESH g_cube = NULL;
LPD3DXMESH g_sphere = NULL;
LPD3DXMESH g_torus = NULL;
D3DXMATRIX g_WorldMatrix[4], R;
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HRESULT Direct3DInit();
VOID Direct3DRender();
VOID Direct3DClean();
bool GameInit();
void MatrixSet();
void LightSet(int nLight);
void GameRender();
void GameClean();
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg = {0};
// Initialize global strings
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
// Main message loop:
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Direct3DRender();
}
}
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(NULL, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = _T("WndClass");
wcex.hIconSm = LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION));
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
g_hWnd = CreateWindow(_T("WndClass"), _T("LearnGame"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, WNDWIDTH, WNDHEIGHT, NULL, NULL, hInstance, NULL);
if (!g_hWnd)
{
return FALSE;
}
if (FAILED(Direct3DInit()))
{
return FALSE;
}
ShowWindow(g_hWnd, nCmdShow);
UpdateWindow(g_hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
{
Direct3DClean();
DestroyWindow(hWnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
HRESULT Direct3DInit()
{
g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION);
if (g_pDirect3D == NULL)
{
return E_FAIL;
}
D3DCAPS9 d3dcaps;
ZeroMemory(&d3dcaps, sizeof(D3DCAPS9));
if (FAILED(g_pDirect3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dcaps)))
{
return E_FAIL;
}
int vp = 0;
if (d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
{
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
}
else
{
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));
d3dpp.BackBufferWidth = WNDWIDTH;
d3dpp.BackBufferHeight = WNDHEIGHT;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = g_hWnd;
d3dpp.Windowed = TRUE;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = 0;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
if (FAILED(g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, vp, &d3dpp, &g_pDirect3DDevice)))
{
return E_FAIL;
}
if (FAILED(D3DXCreateFont(g_pDirect3DDevice, 24, 0, 0, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, _T("Arial"), &g_pD3DXFont)))
{
return E_FAIL;
}
if (!GameInit())
{
return E_FAIL;
}
return S_OK;
}
VOID Direct3DRender()
{
g_pDirect3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
if (SUCCEEDED(g_pDirect3DDevice->BeginScene()))
{
GameRender();
g_pDirect3DDevice->EndScene();
g_pDirect3DDevice->Present(NULL, NULL, NULL, NULL);
}
}
VOID Direct3DClean()
{
GameClean();
g_pD3DXFont->Release();
g_pD3DXFont = NULL;
g_pDirect3DDevice->Release();
g_pDirect3DDevice = NULL;
g_pDirect3D->Release();
g_pDirect3D = NULL;
}
bool GameInit()
{
if (FAILED(D3DXCreateBox(g_pDirect3DDevice, 2.0f, 2.0f, 2.0f, &g_cube, NULL)))
{
return false;
}
if (FAILED(D3DXCreateTeapot(g_pDirect3DDevice, &g_teapot, NULL)))
{
return false;
}
if (FAILED(D3DXCreateSphere(g_pDirect3DDevice, 1.5f, 25, 25, &g_sphere, NULL)))
{
return false;
}
if (FAILED( D3DXCreateTorus(g_pDirect3DDevice, 0.5f, 1.2f, 25, 25, &g_torus, NULL)))
{
return false;
}
D3DMATERIAL9 mtrl;
ZeroMemory(&mtrl, sizeof(mtrl));
mtrl.Ambient = D3DXCOLOR(0.5f, 0.5f, 0.7f, 1.0f);
mtrl.Diffuse = D3DXCOLOR(0.6f, 0.6f, 0.6f, 1.0f);
mtrl.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 0.3f);
mtrl.Emissive = D3DXCOLOR(0.3f, 0.0f, 0.1f, 1.0f);
g_pDirect3DDevice->SetMaterial(&mtrl);
LightSet(1);
g_pDirect3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
g_pDirect3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);
g_pDirect3DDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
g_pDirect3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
//g_pDirect3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
return true;
}
void GameRender()
{
MatrixSet();
if (::GetAsyncKeyState(0x31) & 0x8000F)
{
g_pDirect3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
}
if (::GetAsyncKeyState(0x32) & 0x8000F)
{
g_pDirect3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
}
if (::GetAsyncKeyState(0x51) & 0x8000f)
{
LightSet(1);
}
if (::GetAsyncKeyState(0x57) & 0x8000f)
{
LightSet(2);
}
if (::GetAsyncKeyState(0x45) & 0x8000f)
{
LightSet(3);
}
D3DXMatrixRotationY(&R, timeGetTime()/1440.0f);
D3DXMatrixTranslation(&g_WorldMatrix[0], 3.0f, -3.0f, 0.0f);
g_WorldMatrix[0] = g_WorldMatrix[0] * R;
g_pDirect3DDevice->SetTransform(D3DTS_WORLD, &g_WorldMatrix[0]);
g_cube->DrawSubset(0);
D3DXMatrixTranslation(&g_WorldMatrix[1], -3.0f, -3.0f, 0.0f);
g_WorldMatrix[1] = g_WorldMatrix[1] * R;
g_pDirect3DDevice->SetTransform(D3DTS_WORLD, &g_WorldMatrix[1]);
g_teapot->DrawSubset(0);
D3DXMatrixTranslation(&g_WorldMatrix[2], 3.0f, 3.0f, 0.0f);
g_WorldMatrix[2] = g_WorldMatrix[2] * R;
g_pDirect3DDevice->SetTransform(D3DTS_WORLD, &g_WorldMatrix[2]);
g_torus->DrawSubset(0);
D3DXMatrixTranslation(&g_WorldMatrix[3], -3.0f, 3.0f, 0.0f);
g_WorldMatrix[3] = g_WorldMatrix[3] * R;
g_pDirect3DDevice->SetTransform(D3DTS_WORLD, &g_WorldMatrix[3]);
g_sphere->DrawSubset(0);
}
void GameClean()
{
g_teapot->Release();
g_teapot = NULL;
g_cube->Release();
g_cube = NULL;
g_sphere->Release();
g_sphere = NULL;
g_torus->Release();
g_torus = NULL;
}
void MatrixSet()
{
D3DXMATRIX matWorld, Rx, Ry, Rz;
D3DXMatrixIdentity(&matWorld);
D3DXMatrixRotationX(&Rx, D3DX_PI * timeGetTime() / 1000.0f);
D3DXMatrixRotationY(&Ry, D3DX_PI * timeGetTime() / 1000.0f / 2.0f);
D3DXMatrixRotationZ(&Rz, D3DX_PI * timeGetTime() / 1000.0f / 3.0f);
matWorld = Rx * Ry * Rz * matWorld;
g_pDirect3DDevice->SetTransform(D3DTS_WORLD, &matWorld);
D3DXMATRIX matView;
D3DXVECTOR3 vEye(0.0f, 0.0f, -20.0f);
D3DXVECTOR3 vAt(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vUp(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&matView, &vEye, &vAt, &vUp);
g_pDirect3DDevice->SetTransform(D3DTS_VIEW, &matView);
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4.0f, 1.0f, 1.0f, 1000.0f);
g_pDirect3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
D3DVIEWPORT9 vp;
vp.X = 0;
vp.Y = 0;
vp.Width = WNDWIDTH;
vp.Height = WNDHEIGHT;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
g_pDirect3DDevice->SetViewport(&vp);
}
void LightSet(int nLight)
{
switch (nLight)
{
case 1:
{
D3DLIGHT9 light;
ZeroMemory(&light, sizeof(light));
light.Type = D3DLIGHT_POINT;
light.Ambient = D3DXCOLOR(0.6f, 0.6f, 0.6f, 1.0f);
light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
light.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1.0f);
light.Position = D3DXVECTOR3(0.0f, 100.0f, 0.0f);
light.Attenuation0 = 1.0f;
light.Attenuation1 = 0.0f;
light.Attenuation2 = 0.0f;
light.Range = 300.0f;
g_pDirect3DDevice->SetLight(0, &light);
break;
}
case 2:
{
D3DLIGHT9 light;
ZeroMemory(&light, sizeof(light));
light.Type = D3DLIGHT_DIRECTIONAL;
light.Ambient = D3DXCOLOR(0.6f, 0.6f, 0.6f, 1.0f);
light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
light.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1.0f);
light.Direction = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
g_pDirect3DDevice->SetLight(0, &light);
break;
}
case 3:
{
D3DLIGHT9 light;
ZeroMemory(&light, sizeof(light));
light.Type = D3DLIGHT_SPOT;
light.Ambient = D3DXCOLOR(0.6f, 0.6f, 0.6f, 1.0f);
light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
light.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1.0f);
light.Position = D3DXVECTOR3(100.0f, 100.0f, 100.0f);
light.Direction = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
light.Attenuation0 = 1.0f;
light.Attenuation1 = 0.0f;
light.Attenuation2 = 0.0f;
light.Range = 300.0f;
light.Falloff = 0.1f;
light.Phi = D3DX_PI / 3.0f;
light.Theta = D3DX_PI / 6.0f;
g_pDirect3DDevice->SetLight(0, &light);
break;
}
}
g_pDirect3DDevice->LightEnable(0, TRUE);
g_pDirect3DDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(36, 36, 36));
}
这上一个例子里面的GetAsyncKeyState()函数调用错误,这个例子修改了~
上一篇: Direct3D
下一篇: hutool工具中的雪花算法