#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"winmm.lib")
#include "windows.h"
#include <d3d9.h>
#include <d3dx9math.h>
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
//顶点结构
struct CUSTOMVERTEX
{
FLOAT x,y,z,rhw;
DWORD colour;
};
//全局变量
HWND hWnd;
HINSTANCE hInst;
IDirect3D9* g_pD3D;
IDirect3DDevice9* g_pD3DDevice;
IDirect3DVertexBuffer9* g_pVertexBuffer;
//窗口函数
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//D3D函数
HRESULT InitialiseD3D(HWND hWnd); //初始化D3D
HRESULT InitialiseVertexBuffer(); //初始化顶点缓存
void Render(); //渲染
void CleanUp(); //程序结束,清理内存
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"3D";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(L"3D", L"3D窗口", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_CREATE: //初始化
InitialiseD3D(hWnd);
InitialiseVertexBuffer();
case WM_PAINT: //渲染
hdc = BeginPaint(hWnd, &ps);
Render();
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
CleanUp(); //清理资源
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
HRESULT InitialiseD3D(HWND hWnd)
{
g_pD3D=Direct3DCreate9(D3D_SDK_VERSION);
if(g_pD3D==NULL){
return E_FAIL;
}
D3DDISPLAYMODE d3ddm;
if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm))){
return E_FAIL;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=D3DSWAPEFFECT_COPY;
d3dpp.BackBufferFormat=d3ddm.Format;
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,&g_pD3DDevice))){
return E_FAIL;
}
return S_OK;
}
HRESULT InitialiseVertexBuffer()
{
VOID* pVertices;
CUSTOMVERTEX cvVertices[] =
{
{300.0f,50.0f,0.5f,1.0f,D3DCOLOR_XRGB(255,0,0)},
{500.0f,350.0f,0.5f,1.0f,D3DCOLOR_XRGB(0,255,0)},
{100.0f,350.0f,0.5f,1.0f,D3DCOLOR_XRGB(0,0,255)},
{500.0f,50.0f,0.5f,1.0f,D3DCOLOR_XRGB(255,0,0)},
{700.0f,350.0f,0.5f,1.0f,D3DCOLOR_XRGB(0,255,0)},
{300.0f,350.0f,0.5f,1.0f,D3DCOLOR_XRGB(0,0,255)}
};
if(FAILED(g_pD3DDevice->CreateVertexBuffer(6 * sizeof(CUSTOMVERTEX),0,
D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&g_pVertexBuffer,NULL))){
return E_FAIL;
}
if(FAILED(g_pVertexBuffer->Lock(0,sizeof(cvVertices),(VOID**)& pVertices,0))){
return E_FAIL;
}
memcpy(pVertices,cvVertices,sizeof(cvVertices));
g_pVertexBuffer->Unlock();
return S_OK;
}
void Render()
{
if(g_pD3DDevice==NULL){
return;
}
g_pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
g_pD3DDevice->BeginScene();
g_pD3DDevice->SetStreamSource(0,g_pVertexBuffer,0,sizeof(CUSTOMVERTEX));
g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,2);
g_pD3DDevice->EndScene();
g_pD3DDevice->Present(0,0,0,0);
}
void CleanUp()
{
g_pVertexBuffer->Release();
g_pD3DDevice->Release();
g_pD3D->Release();
}