#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"winmm.lib")
//声明
const int width = 800;
const int height = 600;
IDirect3DDevice9* Device = 0;
D3DDEVTYPE deviceType = D3DDEVTYPE_HAL;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
//函数开始
int WINAPI/*基本调用_stdcall*/ WinMain(HINSTANCE hInstance,/*当前运行程序的实例句柄*/
HINSTANCE hPrevInstance,/*前一个句柄,一般都是NULL*/
LPSTR lpCmdLine,/*命令行参数,以空终止的字符串*/
int nCmdShow /*显示方式*/)
{
//声明一个窗口类结构体
WNDCLASS wc = { 0 }; //WNDCLASSEX比WNDCLASS多两个参数
//wc.cbSize = sizeof(PWNDCLASSEX);//表示该结构体的字节数大小
wc.style = CS_HREDRAW | CS_VREDRAW; // 窗口的风格样式 水平大小或垂直大小变化发生重绘
wc.lpfnWndProc = WndProc;//窗口的回调函数,响应事件的系统触发函数
wc.cbClsExtra = 0; //窗口类附加内存
wc.cbWndExtra = 0; //窗口的附加内存
wc.hInstance = hInstance; //指定包含窗口过程的程序的实例句柄
wc.hIcon = LoadIcon(0,/*程序句柄加载系统图标第一个参数为NULL,加载用户图标第一个参数为实例句柄*/
IDI_APPLICATION/*系统图标,或用户图标路径字符串*/);//窗口类的图标资源句柄
wc.hCursor = LoadCursor(0, IDC_ARROW);//箭头光标用法同上
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//背景画刷句柄
wc.lpszMenuName = 0; //指定菜单资源的名字,字符串形式
wc.lpszClassName = "Direct3D9App";//自定义的窗口类名字
//wc.hIconSm = 0;//托盘中应用程序的小图标
if (!RegisterClass(&wc))
{
::MessageBox(0, TEXT("RegisterClass() - FAILED"), 0, 0);
return 0;
}
HWND hwnd = 0;
hwnd = CreateWindow("Direct3D9App",//对应窗口类的名称
"过程性窗口的创建", //指定创建的窗口名字
WS_MAXIMIZEBOX, //创建窗口的样式
CW_USEDEFAULT, //水平位置
CW_USEDEFAULT, //竖直位置
width,//宽
height, //高
0 /*父窗口的句柄*/,
0 /* 菜单资源句柄 */,
hInstance, //程序实例句柄
0 /*WM_CREATE消息lParam数据指针*/);
if (!hwnd)
{
::MessageBox(0, TEXT("CreateWindow() - FAILED"), 0, 0);
return 0;
}
::ShowWindow(hwnd, SW_SHOW);
::UpdateWindow(hwnd);
//初始化DirectX
HRESULT hr = 0;
IDirect3D9* d3d9 = 0;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
if (!d3d9)
{
::MessageBox(0, TEXT("Direct3DCreate9() - FAILED"), 0, 0);
return false;
}
D3DCAPS9 caps;
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);
int vp = 0;
if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = width;//后备缓冲表面的宽度
d3dpp.BackBufferHeight = height;//后备缓冲表面的高度
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;//后备缓冲表面的像素格式
d3dpp.BackBufferCount = 1;//后备缓冲表面的数量
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;//全屏抗锯齿的类型
d3dpp.MultiSampleQuality = 0;//全屏抗锯齿的质量等级
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;//指定表面在交换链中是如何被交换
d3dpp.hDeviceWindow = hwnd;//与设备相关的窗口句柄,想在哪个窗口绘制就写那个窗口的句柄
d3dpp.Windowed = true;//true为窗口模式,false则为全屏模式
d3dpp.EnableAutoDepthStencil = true;//设为true,D3D将自动创建深度/模板缓冲
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;//深度/模板缓冲的格式
d3dpp.Flags = 0; //一些附加特性,设为0或者D3DPRESENTFLAG类型的一个成员,一个表面能够被锁定,降低程序的性能,一个深度/模板缓冲调用present后会被删除,提升程序性能
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;//刷新频率
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;//交换方式(D3DPRESENT_INTERVAL_IMMEDIATE立即交换,D3DPRESENT_INTERVAL_DEFAULT 等于刷新频率)
hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT, // 指定对象要表示的物理显示设备
deviceType, // 设备类型
hwnd, // 设备的窗口句柄
vp, // 采用硬件顶点处理或者软件顶点处理
&d3dpp, // 初始化好的D3DPRESENT_PARAMETERS实例
&Device); // 返回创建的设备
if (FAILED(hr))
{
// try again using a 16-bit depth buffer
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
deviceType,
hwnd,
vp,
&d3dpp,
&Device);
if (FAILED(hr))
{
d3d9->Release(); // done with d3d9 object
::MessageBox(0, TEXT("CreateDevice() - FAILED"), 0, 0);
return 0;
}
}
else{
//开始设置参数
}
d3d9->Release(); // done with d3d9 object
//消息循环
MSG msg = { 0 };
float lastTime = (float)timeGetTime();
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
float curTime = (float)timeGetTime();
float timeDelta = (curTime - lastTime)*0.001f;
if (Device)
{
Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
//开始显示
Device->Present(0, 0, 0, 0);
}
lastTime = curTime;
}
}
UnregisterClass("Direct3D9App",wc.hInstance);
return 0;
}
LRESULT CALLBACK WndProc(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
::PostQuitMessage(0);
break;
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
::DestroyWindow(hwnd);
break;
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}