DirectX的初始化
Direct3D的初始化步骤如下:
1、 创建D3D对象,即通过Direct3DCreate9(D3D_SDK_VERSION)函数创建IDirect3D9对象;该对象用于设备枚举:获取系统中可用的每块图形卡的性能、显示模式、格式等信息。
2、 通过D3D对象创建D3D设备对象,即调用IDirect3D9的成员函数CreateDevice来创建。(在此之前要初始化一些参数)
3、 最后就可以根据D3D设备对象来进行绘制我们想要的场景了
4、 程序结束应该释放这两个对象,先释放设备对象,然后释放D3D对象,因为设备对象由D3D对象创建。
说明:先创建D3D对象,然后通过D3D对象创建D3D设备对象的好处是,D3D对象可以进行设备枚举,如检测设备的性能,使创建的D3D设备对象在执行图形渲染时能够充分利用硬件的处理功能。
初始化代码如下:
#include <windows.h>
#include <tchar.h>
#include <d3dx9.h>#pragma comment(lib,"D3D9.lib")//函数声明
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);//窗口过程
bool InitD3D(HINSTANCE hInstance);
void Cleanup();
void Render(); //绘制//窗口相关全局变量
const TCHAR g_szWindowTitleName[] = _T("InitDirect3D"); //窗口标题
const TCHAR g_szWindowClassName[] = _T("WindowClass"); //窗口类名
int g_cxWindow = 600; //窗口宽
int g_cyWindow = 480; //窗口高//Direct3D全局变量
IDirect3D9 * g_pD3d = nullptr; //Direct3D对象指针
IDirect3DDevice9 * g_pDevice = nullptr; //Direct3D设备对象指针int WINAPI _tWinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPTSTR lpCmdLine,int nShowCmd)
{if (!InitD3D(hInstance)){MessageBox(NULL, _T("初始化D3D失败"), NULL, MB_OK);return 0;}MSG msg;memset(&msg, 0, sizeof(msg));while (true){if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){if (msg.message == WM_QUIT)break;TranslateMessage(&msg);DispatchMessage(&msg);}else{Render(); //5 绘制}}Cleanup(); //6 清理资源return msg.wParam;
}LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{switch (uMsg){case WM_KEYDOWN:if (wParam == VK_ESCAPE)DestroyWindow(hWnd);return 0;case WM_DESTROY:PostQuitMessage(0);return 0;}return DefWindowProc(hWnd, uMsg, wParam, lParam);
}bool InitD3D(HINSTANCE hInstance)
{WNDCLASS wndClass; //初始化窗口类结构体wndClass.cbClsExtra = 0;wndClass.cbWndExtra = 0;wndClass.style = CS_HREDRAW | CS_VREDRAW;wndClass.hInstance = hInstance;wndClass.hbrBackground = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);wndClass.lpfnWndProc = WndProc;wndClass.lpszClassName = g_szWindowClassName;wndClass.lpszMenuName = NULL;BOOL bRet;bRet = RegisterClass(&wndClass); //注册窗口类if (!bRet){MessageBox(NULL, _T("Register window class fail"), NULL, MB_OK);return FALSE;}HWND hWnd;hWnd = CreateWindow(g_szWindowClassName,//创建窗口g_szWindowTitleName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,g_cxWindow,g_cyWindow,NULL,NULL,hInstance,NULL);if (!hWnd){MessageBox(NULL, _T("Create Window FAil"), NULL, MB_OK);return FALSE;}ShowWindow(hWnd, SW_SHOW);UpdateWindow(hWnd);//init Direct3Dg_pD3d = Direct3DCreate9(D3D_SDK_VERSION); //1、创建D3D对象if (!g_pD3d){MessageBox(NULL, _T("创建D3D对象失败!"), NULL, MB_OK);return false;}D3DCAPS9 caps; //2、检查设备能力,硬件是否支持顶点运算g_pD3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);int cap;if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)cap = D3DCREATE_HARDWARE_VERTEXPROCESSING; //用硬件方式处理顶点运算elsecap = D3DCREATE_SOFTWARE_VERTEXPROCESSING; //用软件方式处理顶点运算D3DPRESENT_PARAMETERS d3dpp; //3、初始化D3DPRESENT_PARAMETERS结构体memset(&d3dpp, 0, sizeof(D3DPRESENT_PARAMETERS));d3dpp.EnableAutoDepthStencil = true;d3dpp.AutoDepthStencilFormat = D3DFMT_D16;d3dpp.Windowed = true;d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;HRESULT hr;hr = g_pD3d->CreateDevice(D3DADAPTER_DEFAULT, //4、创建D3D设备对象D3DDEVTYPE_HAL,hWnd,cap,&d3dpp,&g_pDevice);if (FAILED(hr)){MessageBox(NULL, _T("创建D3D设备对象失败!"), NULL, MB_OK);return false;}return true;
}void Cleanup()
{if (g_pDevice){ g_pDevice->Release(); g_pDevice = nullptr; }if (g_pD3d){ g_pD3d->Release(); g_pD3d = nullptr; }
}void Render()
{g_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 200, 0), 1.f, 0);HRESULT hr;hr = g_pDevice->BeginScene();if (SUCCEEDED(hr)){//......renderg_pDevice->EndScene();}g_pDevice->Present(nullptr, nullptr, NULL, nullptr);
}
运行效果如下:
下面对以上用的函数及其结构体类型进行说明:
1、IDirect3D9::GetDeviceCaps
该函数的功能是获取设备的相关信息
函数原型如下:
HRESULT GetDeviceCaps([in] UINT Adapter,[in] D3DDEVTYPE DeviceType,[out] D3DCAPS9 *pCaps
);
参数说明:
Aapter:显卡的序号,一般为D3DADAPTER_DEFAULT表示用主显卡适配器
DeviceType:D3DDEVTYPE枚举类型,决定显卡的类型,通常用D3DDEVTYPE_HAL或D3DDEVTPYE_REF
pCaps:D3DCAPS9类型的指针,接受设备相关的信息
2、struct D3DCAPS9
代表了硬件设备的公开能力,通常用其成员DevCaps与D3DDEVCAPS_HWTRANSFORMANDLIGHT进行按位与操作来判断硬件是否支持变换和光照
3、struct D3DPRESENT_PARAMETERS
创建D3D设备对象时需要使用的结构体参数,原型及其说明如下:
typedef struct D3DPRESENT_PARAMETERS {UINT BackBufferWidth; //后台缓存的宽度和高度,如果为窗口模式且该变量设置为0时,则系统自动使用窗口客户区域的宽度和高度作为后台缓存的宽度和高度(如果hDeviceWindow为NULL,则为焦点窗口);UINT BackBufferHeight; //如果为全屏模式,则必须为枚举显示模式找到的宽度和高度D3DFORMAT BackBufferFormat; //后台缓存的格式,该值必须是渲染目标格式之一(可以通过CheckDeviceType来获得,也可以用GetDisplayMode来获取当前格式);在窗口模式下,如果将值设置为D3DFMT_UNKNOWN,则系统用当前的显示模式的格式,从而可以避免调用GetDisplayModeUINT BackBufferCount; //后台缓存的格式,其值的范围在0到D3DPRESENT_BACK_BUFFERS_MAX之间,0被处理为1,如果不能创建指定数量的后台缓存,那么系统会自动填充能被创建的后台缓存个数D3DMULTISAMPLE_TYPE MultiSampleType; //多重采样的类型,用于反锯齿。该值必须设置为D3DMULTISAMPLE_NONE,除非SwapEffect被设置为D3DSWAPEFFECT_DISCARDDWORD MultiSampleQuality; //采样的质量水平,该值的有效范围为0到CheckDeviceMultiSampleType函数返回值之间。值太大则会失败D3DSWAPEFFECT SwapEffect; //指定后台缓存如何赋值到前台缓存,在窗口模式下,如果设置为D3DSWAPEFFECT_FLIP,则会创建一个额外的后台缓存,在提交的时候用来拷贝将成为前台缓存的缓存。通常设置为D3DSWAPEFFECT_DISCARDHWND hDeviceWindow; //设备窗口句柄,决定了后台缓存在屏幕的位置和大小。对于全屏模式,这是一个顶层窗口的句柄;对于窗口模式,这个句柄将标识了默认目标窗口,如果为NULL,则用焦点窗口(焦点窗口即为在创建D3D设备对象时,对函数IDirect3D9::CreateDevice指定的第三个参数)BOOL Windowed; //决定是否为窗口模式BOOL EnableAutoDepthStencil; //决定是否让Direct3D深度缓存,当设备创建时,自动创建深度模版缓存D3DFORMAT AutoDepthStencilFormat; //深度模版缓存的格式,这个格式必须有效DWORD Flags; //附加特性,通常设置为0UINT FullScreen_RefreshRateInHz; //全屏模式下显示适配器刷新屏幕的频率,通常指定为:D3DPRESENT_RATE_DEFAULT;对于窗口模式必须指定为0UINT PresentationInterval; //指定交换链的后台缓存提交到前台缓存的最大频率,通常设置为D3DPRESENT_INTERVAL_IMMEDIATE(立即提交)、D3DPRESENT_INTERVAL_DEFAULT(由Direct3D选择提交频率,同长等于刷新频率)
} D3DPRESENT_PARAMETERS, *LPD3DPRESENT_PARAMETERS;
4、IDirect3D9::CreateDevice
创建一个D3D设备对象,函数原型如下:
HRESULT CreateDevice([in] UINT Adapter,[in] D3DDEVTYPE DeviceType,[in] HWND hFocusWindow,[in] DWORD BehaviorFlags,[in, out] D3DPRESENT_PARAMETERS *pPresentationParameters,[out, retval] IDirect3DDevice9 **ppReturnedDeviceInterface
);
Adapter:显卡号,一般用D3DADAPTER_DEFAULT
DeviceType:设备类型
hFocusWindow:焦点窗口,在全屏模式下必须指定问顶层窗口;在窗口模式下,该值可以为NULL,如果D3DPRESENT_PARAMETERS的窗口句柄成员设置为非空值的话。
BehaviorFlags:组合一个或多个值来空置设备的创建行为,如:D3DCREATE_HARDWARE_VERTEXPROCESSING、D3DCREATE_SOFTWARE_VERTEXPROCESSING 顶点的处理方式。
pPresentationParameters:D3DPRESENT_PARAMETERS结构体变量
ppReturnedDeviceInterface:返回D3D设备对象的指针
5、IDirect3DDevice9::Clear
可以清除视口的颜色缓存、深度缓存、和模版缓存
HRESULT Clear([in] DWORD Count,[in] const D3DRECT *pRects,[in] DWORD Flags,[in] D3DCOLOR Color,[in] float Z,[in] DWORD Stencil
);
Count:矩形数组中矩形的个数,可以为0
pRects:矩形数组的指针
Flags:可以组合一个或多个标记D3DCLEAR_STENCIL、D3DCLEAR_TARGET、D3DCLEAR_ZBUFFER
Color:渲染目标被清除的目标颜色
Z:清除深度缓存到指定的值,范围为0-1
Stencil:清除模版缓存为指定的值
注意:如果清除渲染目标的模版缓存或深度缓存,而没有关联深度缓存的话,该函数将调用失败;当清楚模版缓存,而深度缓存没有包含模版数据时,函数调用也会失败!
6、IDirect3DDevice9::BeginScene
开始绘制
7、IDirect3DDevice9::EndScene
结束绘制
8、IDirect3DDevice9::Present
在后台缓存中绘制完图形后,调用该函数将在后台缓存中绘制的内容提交到前台显示,这样绘制的图形就显示在屏幕上了。
HRESULT Present([in] const RECT *pSourceRect,[in] const RECT *pDestRect,[in] HWND hDestWindowOverride,[in] const RGNDATA *pDirtyRegion
);
pSourceRect:该值必须设置为NULL,除非对D3DPRESENT_PARAMETERS结构体变量的成员SwapEffect设置其值为D3DSWAPEFFECT_COPY;该参数表示被提交的源矩形区域,如果为NULL,表示整个源表面,如果矩形区域超过了源表面的大小,那么矩形将被裁剪到源表面大小
pDestRect:该值必须设置为NULL,除非对D3DPRESENT_PARAMETERS结构体变量的成员SwapEffect设置其值为D3DSWAPEFFECT_COPY;该参数表示目标矩形区域,如果为NULL,则表示整个客户区,如果矩形区域超过了客户区的大小,那么矩形将被裁剪到客户区域的大小
hDestWindowOverride:目标矩形区域的窗口句柄,如果为NULL,则用D3DPRESENT_PARAMETERS中的窗口句柄成员
pDirtyRegion:该值必须为NULL,除非对D3DPRESENT_PARAMETERS结构体变量的成员SwapEffect设置其值为D3DSWAPEFFECT_COPY;该参数主要用于优化提交,包含了多个矩形,以表示一个区域。通常设置为NULL
DirectX的初始化相关推荐
- 魔兽3无法启动此程序因为计算机中丢失,魔兽争霸3没法启动 总提示directx没法初始化...
出现这种错误的原因主要有三种: 1.DirectX版本过低,运行魔兽争霸需要DirectX8.1或者更高版本:(WIN7系统可以忽视) 2.DirectDraw加速.Dierct3D加速.AGP纹理加 ...
- 【Visual C++】游戏开发笔记三十三 浅墨DirectX提高班之二 化腐朽为神奇:DirectX初始化四步曲
这篇文章里,我们将迈出精通DirectX的第一步,先了解典型Direct3D程序的书写流程,然后学习COM接口的对象的一些思想,然后按照"四步曲"的思路,系统地学习DirectX的 ...
- 【Visual C++】游戏开发笔记三十三 浅墨DirectX提高班之二 化腐朽为神奇:DirectX初始化四步曲...
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/zhmxy555/article/details/8197792 作者:毛星云(浅墨) ...
- 【Visual C++】游戏开发笔记三十三 浅墨DirectX提高班之二 化腐朽为神奇 DirectX初始化四步曲
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8197792 作者:毛星云(浅 ...
- DirectX 开发demon
DirectX学习笔记(一) 一.前言 学习DirectX的初衷是为了做游戏,为了开发游戏引擎.我在之前其实学习过一段时间的DirectX,但是由于后来一些其他原因将DirectX的学习搁置到了一边. ...
- DirectSound的应用
假设仅仅使用PlaySound()这个API函数来表现声音效果的话,那么就无法表现出声音的混音效果,由于PlaySound在播放还有一个声音时,必定会导致现有声音的停止.因此,使用 PlaySound ...
- [Cocos2d-x For WP8]Hello world
[Cocos2d-x For WP8]Hello world Cocos2d-x For WP8使用C++开发,使用cocos2d-xv0.13同样的接口,Cocos2d-x For WP8的相关项目 ...
- 魔兽3无法启动此程序因为计算机中丢失,win10运行war3出错无法启动怎么办_win10系统war3不能启动如何解决...
war3魔兽世界是一款备受玩家们喜爱的游戏之一,但是近日有win10系统用户要在电脑中运行war3的时候,却出错了,无法启动该游戏,要怎么解决这样的问题呢,针对win10系统war3不能启动这个问题, ...
- DirectSound应用
只是使用的假设PlaySound()这个API函数来显示的声音效果,然后,然后,它不会出现在混合声音,因为PlaySound还有播放期间声音,这将不可避免地导致现有声音停止. 因此,使用 PlaySo ...
最新文章
- 安全36计 你需要了解的那些安全术语
- enum2str做为queryValue时的问题
- oracle+事务开始+结束,Oracle事务和对象上集(视图、索引)
- ansible(1)——安装
- ElasticSearch 知识点整理(深入)
- LINQ中的Lambda表达式
- [leetcode] 7. 整数反转
- SQL Server存储过程同时返回分页结果集和总数
- Chart.js报告
- Qt warning : 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
- androidid什么时候会变_高瓷绿松石是什么意思?为何绿松石的瓷度要比颜色重要?...
- uva 10247 - Complete Tree Labeling(dp)
- python mqtt publish_mqtt异步publish方法
- android+x86+远程桌面,Chrome远程桌面和Android模拟器
- 【前后端常见的登录方式】
- 我 stormzhang 来报道了!
- 国内无代码开发平台功能对比
- 如何写hive的udf函数?
- (心得三)java俄罗斯方块小游戏编写心得
- Cordys BOP 4平台开发入门实战演练——会签流程建模开发