最简单的DirectX
写一个窗口:
包括信息处理函数、WinMain函数
点击查看代码
//允许按下ESC键退出应用程序
//关键是第二个参数, 这个参数是获取到的消息标识
//这个函数不用自己调用, 赋值给窗体后会自动调用这个函数
//每个窗口都有一个消息处理函数
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)//处理消息
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
}
//将不处理的函数交给系统默认处理
return DefWindowProc(hWnd, msg, wParam, lParam);
}
//程序入口点
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst, LPSTR cmdLine, int show)
{
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
hInst, NULL, NULL, NULL, NULL,
"AppClass", NULL };
RegisterClassEx(&wc);
// 创建应用程序的窗口
HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME,
WS_OVERLAPPEDWINDOW,
100, 100, 640, 480, NULL, NULL,
hInst ,NULL);
//显示窗口
ShowWindow(hWnd, SW_SHOWDEFAULT);
//更新窗口
UpdateWindow(hWnd);
//进入消息循环
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//对屏幕做点什么
}
}
//注销我们的窗口。
UnregisterClass("AppClass", wc.hInstance);
}
InitializeD3D初始化
bool InitializeD3D(HWND hWnd, bool fullscreen)
//窗口句柄hWnd 标识窗口是否全屏的标识符fullscreen。
{
D3DDISPLAYMODE displayMode;
//创建D3D对象。
g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
if(g_D3D == NULL) return false;
//获取桌面显示模式。
if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
return false;
//建立用于创建D3DDevice的结构
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;
//渲染后台缓存的格式
//得到所要用到的桌面格式
//CreateDevice()函数主要负责创建Direct3D设备对象,该对象用于向屏幕渲染图形。
if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_D3DDevice)))
{
return false;
}
return true;
}
补充
BcakBufferCount是想要用于渲染的后台缓存总数。
MultiSampleType、MultiSampleQuality和SwapEffect处理交换效果。
hDeviceWindow是窗口句柄
Windowed标识符用于指定创建的窗口是否是全屏窗口。
EnableAutoDepthStencil标识符用于设置是否用Direct3D管理缓存深度以及模板缓存。AutoDepthStencilFormat将深度和模板缓存设置为BackBufferFormat可以使用的相同值之一。
变量FullScreen_RefreshRateInHz存储显示器的刷新率。
PresentationInterval处理可以显示的交换链的后台缓存的最大次数。
交换链主要让程序有多个窗口在桌面上同时显示(每个渲染自己的窗口)
初始化阶段的CreateDevice()函数中创建的设备对象可以完成Direct3D中的渲染工作。
渲染屏幕开始先要清屏为指定的颜色,告知Direct3D将要开始绘制新场景,渲染想要渲染的物体,完成屏幕渲染,在屏幕上显示渲染结果。
RenderScene渲染屏幕
void RenderScene()
{
//开始先清除后台缓存。
//调用Direct3D设备对象的Clear()函数
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
//一旦完成清除工作,渲染函数将调用设备对象的BeginScene()函数,在Direct3D中启动一个新场景。
g_D3DDevice->BeginScene();
//一旦渲染完要渲染的物体,就调用设备对象的EndScene()函数结束渲染。
g_D3DDevice->EndScene();
//在屏幕上显示渲染结果。
g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}
补充
Clear()函数的参数包括:
要清除的矩形数目(0代表清除整个屏幕)、
定义想要清除的屏幕区域矩形链表(NULL代表整个屏幕)、标识要清除内容的标识符、清除后的颜色、要设定的深度值、设定模板缓存值。
对标识符参数而言,D3DCLEAR_DEFAULT清除所有的渲染目标,D3DCLEAR_STENCIL清除模板缓存,而D3DCLEAR_ZBUFFER清除深度缓存。
在Direct3D中渲染任何图形前,都必须先调用BeginScene()函数。
每个BeginScene()函数必须有一个与之对应的EndScene()函数。
调用设备对象的Present()函数可以完成显示。Present()函数的参数可以全部设为NULL(空)。
在Direct3D中,会发现通常要在退出程序前释放系统使用的内存,从而避免内存泄漏。
所有要释放的内存都可以通过调用对象的Release()函数释放。
Release()函数会减少对象的引用计数。如果引用计数降为0,那么系统就可以安全地从内存中删除对象。如果对单个对象有多个引用,那么必须牢记对所有的对象都要调用Release()函数,否则将不会释放内存。
如果创建了对象,那么最终就要释放该对象。
点击查看代码
void Shutdown()
{
if(g_D3DDevice != NULL) g_D3DDevice->Release();
if(g_D3D != NULL) g_D3D->Release();
g_D3DDevice = NULL;
g_D3D = NULL;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)