3D窗口创建工程下载链接:点击打开链接
我前面在我DirectX 2D 游戏的开发的博客里写过关于DirectX 2D游戏窗口的创建,当然那个2D并不是DirectX Draw 的2D,而是运用DirectX Sprite组件,实现2D效果,而3D 游戏需要的窗口创建方法,跟2D基本差不多,不一样的地方有,但是很少,但是,为了帮助一下新手,我还是尽可能 的说一下,当然,不会比我前一篇,DirectX 2D 窗口创建详细
我们要做的就是定义一个接口指针,把它传给某个函数,函数使我们的接口指针有意义,接着我们使用接口,就这么简单。定义完这个接口指针后,使用Direct3DCreate9这个函数来创建一个D3D接口
g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
D3DCAPS9 caps;
ZeroMemory(&caps,sizeof(caps));
g_pD3D->GetDeviceCaps(
D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps);
3.创建D3D 显示模式结构体,获取当前显卡模式
D3DDISPLAYMODE d3ddm;
ZeroMemory(&d3ddm,sizeof(d3ddm));
g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,
&d3ddm);
struct D3DPRESENT_PARAMETERS{
UINT BackBufferWidth;
UINT BackBufferHeight;
D3DFORMAT BackBufferFormat;
UINT BackBufferCount;
D3DMULTISAMPLE_TYPE MultiSampleType;
DWORD MultiSampleQuality;
D3DSWAPEFFECT SwapEffect;
HWND hDeviceWindow;
BOOL Windowed;
BOOL EnableAutoDepthStencil;
D3DFORMAT AutoDepthStencilFormat;
DWORD Flags;
UINT FullScreen_RefreshRateInHz;
UINT PresentationInterval;
};
真正的带有赋予实参的代码为
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed = true; //窗口模式
////-------全屏模式的写法:---------
//d3dpp.Windowed = false;
//d3dpp.BackBufferWidth = d3ddm.Width;
//d3dpp.BackBufferHeight = d3ddm.Height;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.BackBufferCount = 1;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
//是否开启自动深度模板缓冲
d3dpp.EnableAutoDepthStencil = true;
//当前自动深度模板缓冲的格式
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
BackBufferWidth和BackBufferHeight:后备缓冲的宽度和高度。在全屏模式下,这两者的值必需符合显卡所支持的分辨率。例如(800,600),(640,480)。
BackBufferFormat:后备缓冲的格式。这个参数是一个D3DFORMAT枚举类型,它的值有很多种,例如D3DFMT_R5G6B5,这说明后备缓冲的格式是每个像素16位,其实红色(R)占5位,绿色(G)占6位,蓝色(B)占5位,为什么绿色会多一位呢?据说是因为人的眼睛对绿色比较敏感。DX9只支持16位和32位的后备缓冲格式,24位并不支持。如果对这D3DFORMAT不熟悉的话,可以把它设为D3DFMT_UNKNOWN,这时候它将使用桌面的格式。
BackBufferCount:后备缓冲的数目,范围是从0到3,如果为0,那就当成1来处理。大多数情况我们只使用一个后备缓冲。使用多个后备缓冲可以使画面很流畅,但是却会造成输入设备响应过慢,还会消耗很多内存。
MultiSampleType和MultiSampleQuality:前者指的是全屏抗锯齿的类型,后者指的是全屏抗锯齿的质量等级。这两个参数可以使你的渲染场景变得更好看,但是却消耗你很多内存资源,而且,并不是所有的显卡都支持这两者的所设定的功能的。在这里我们分别把它们设为D3DMULTISAMPLE_NONE和0。
SwapEffect:交换缓冲支持的效果类型,指定表面在交换链中是如何被交换的。它是D3DSWAPEFFECT枚举类型,可以设定为以下三者之一:D3DSWAPEFFECT_DISCARD,D3DSWAPEFFECT_FLIP,D3DSWAPEFFECT_COPY。如果设定为D3DSWAPEFFECT_DISCARD,则后备缓冲区的东西被复制到屏幕上后,后备缓冲区的东西就没有什么用了,可以丢弃(discard)了。如果设定为D3DSWAPEFFECT_FLIP,则表示在显示和后备缓冲之间进行周期循环。设定D3DSWAPEFFECT_COPY的话,我也不太清楚有什么作用*^_^*。一般我们是把这个参数设为D3DSWAPEFFECT_DISCARD。
hDeviceWindow:显示设备输出窗口的句柄
Windowed:如果为FALSE,表示要渲染全屏。如果为TRUE,表示要渲染窗口。渲染全屏的时候,
BackBufferWidth和BackBufferHeight的值就得符合显示模式中所设定的值。
EnableAutoDepthStencil:如果要使用Z缓冲或模板缓冲,则把它设为TRUE。
AutoDepthStencilFormat:如果不使用深度缓冲,那么这个参数将没有用。如果启动了深度缓冲,那么这个参数将为深度缓冲设定缓冲格式(和设定后备缓冲的格式差不多)
Flags:可以设置为0或D3DPRESENTFLAG_LOCKABLE_BACKBUFFER。不太清楚是用来做什么的,看字面好像是一个能否锁定后备缓冲区的标记。
FullScreen_RefreshRateInHz:显示器的刷新率,单位是HZ,如果设定了一个显示器不支持的刷新率,将会不能创建设备或发出警告信息。为了方便,一般设为D3DPRESENT_RATE_DEFAULT就行了。
PresentationInterval:如果设置为D3DPRENSENT_INTERVAL_DEFAULT,则说明在显示一个渲染画面的时候必要等候显示器刷新完一次屏幕。例如你的显示器刷新率设为80HZ的话,则一秒内你最多可以显示80个渲染画面。另外你也可以设置在显示器刷新一次屏幕的时间内显示1到4个画面。如果设置为D3DPRENSENT_INTERVAL_IMMEDIATE,则表示可以以实时的方式来显示渲染画面,虽然这样可以提高帧速(FPS),但是却会产生图像撕裂的情况。
HRESULT CreatDevice(
UINT Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3DDevice9** ppReturnedDeviceInterface
};
实际调用的代码为
g_pD3D->CreateDevice(
D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,
g_hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,&g_pDevice);
g_pDevice->SetRenderState(D3DRS_ZENABLE,true);
6.开始渲染
HRESULT Clear(
DWORD Count,
const D3DRECT *pRects,
DWORD Flags,
D3DCOLOR Color,
float Z,
DWORD Stencil
);
HRESULT Present(
const RECT *pSourceRect,
const RECT *pDestRect,
HWND hDestWindowOverride,
const RGNDATA *pDirtyRegion
);
然后再在之间加入BegineScene()和EndScene()即可
实例代码如下:
g_pDevice->Clear(
0, //清空矩形的数量
nullptr, //清空矩形的临接信息
D3DCLEAR_TARGET, //要清空颜色缓冲区
D3DCOLOR_XRGB(123,123,234), //清成什么颜色
1.0f, //深度缓冲区的初始值
0 //模板缓冲区的初始值
);
g_pDevice->BeginScene(); //获取绘制权限
//---------------------------------------
// 渲染代码
//---------------------------------------
g_pDevice->EndScene(); //结束绘制
//前后台缓冲区交换的"源动力"
g_pDevice->Present(nullptr, nullptr, 0, nullptr);
}
总而言之,这个3D环境和2D 环境的区别在哪呢,
1. d3dpp 多设置两个属性,分别是开启深度模板缓冲,和设置深度模板缓冲
2.多了使用SetRanderStates()函数设置渲染状态
3.多了检测硬件代码能力这一步,虽然这一步不是必须的,
4.没了,其它和3D 环境搭建一模一样