📄 chapter3.txt
字号:
if (FAILED(hr)) {
Complain(hwnd, hr, "CreateDevice(SysMouse)");
return FALSE;
}
CreateDevice方式有三个参数:第一个是全局独有标志符GUID_SysMouse,这里表明为鼠标;第二个是IDirectInputDevice接口指针类型,如果这个调用成功,它就指向可用的鼠标;一般不使用COM聚合体,第三个参数为NULL。
然后,设置鼠标信息的格式:
hr = g_pMouse->SetDataFormat(&c_dfDIMouse);
if (FAILED(hr)) {
Complain(hwnd, hr, "SetDataFormat(SysMouse, dfDIMouse)");
return FALSE;
}
设置鼠标行为:
hr = g_pMouse->SetCooperativeLevel(hwnd,
DISCL_EXCLUSIVE | DISCL_FOREGROUND);
//后面的两个标志符实现了前台运行时对输入设备的独占
if (FAILED(hr)) {
Complain(hwnd, hr, "SetCooperativeLevel(SysMouse)");
return FALSE;
}
要使用事件通告(event notification)来发觉鼠标的动作并将经过缓冲的鼠标输入读进来,这都需要进行一些设置。首先,创建一个事件,将它与鼠标联系起来。当发生硬件中断时,就可以告诉鼠标设备对象有新的数据来到。
// HANDLE g_hevtMouse; // 全局变量
g_hevtMouse = CreateEvent(0, 0, 0, 0);
if (g_hevtMouse == NULL) {
Complain(hwnd, GetLastError(), "CreateEvent");
return FALSE;
}
hr = g_pMouse->SetEventNotification(g_hevtMouse);
if (FAILED(hr)) {
Complain(hwnd, hr, "SetEventNotification(SysMouse)");
return FALSE;
}
现在您需要设定缓冲区大小。在此之前要初始化一个DIPROPDWORD结构,这当中很多数量是无关紧要的,关键是最后一个,dwData,它决定了缓冲区中可容纳项目的数量。
#define DINPUT_BUFFERSIZE 16
DIPROPDWORD dipdw =
{
// the header
{
sizeof(DIPROPDWORD), // diph.dwSize
sizeof(DIPROPHEADER), // diph.dwHeaderSize
0, // diph.dwObj
DIPH_DEVICE, // diph.dwHow
},
// the data
DINPUT_BUFFERSIZE, // dwData
};
接着按照您希望改变的属性的标志符,将头地址传送给IDirectInputDevice::SetProperty方式:
hr = g_pMouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);
if (FAILED(hr)) {
Complain(hwnd, hr, "Set buffer size(SysMouse)");
return FALSE;
}
至此,设置结束。然后开始根据程序的要求操作鼠标。
第八节 Direct3D
Direct3D提供了与硬件无关的的3D视频硬件操作方式。您可以在两种模式(立即模式和保留模式)中选择其中之一使用。
立即模式较保留模式是一个低层的3D API,后者建构于前者之上。立即模式适合于开发高品质的多媒体应用程序,它在底层与加速硬件进行通讯。保留模式应用于对3D场景进行实时的操纵。
对3D场景的操作是基于矩阵和多边形的运算,这是创建和管理3D的基础知识,在很多资料中均可获得。
使用立即模式可以选择通过调用DrawPrimitive方式或利用执行缓冲区。对于初学者一般从调用DrawPrimitive方式。不过,千万不要认为两者有优劣之分。在熟悉了Direct3D后,使用哪个方法取决于您应用程序的要求。前者的方法与其它COM雷同;在利用执行缓冲区的方法时,要创建DirectDraw和Direct3D对象,设置渲染状态,填充执行缓冲区等。
无论哪种模式,应用程序与硬件的通讯都很类似。正如下图所示。由于Direct3D相当于DirectDraw对象的一个接口,这里的HAL被表示为DirectDraw/Direct3D HAL。
对保留模式的操作是通过使用一些对象来实现的。Direct3D和DirectDraw是紧密联系在一起的。一个DirectDraw对象将DirectDraw和Direct3D状态封装起来,通过IDirectDraw::QueryInterface方式将IDirect3D接口转换为DirectDraw对象。
有一个很重要的概念是z缓冲区。它决定了将很多显示内容如何覆盖和裁剪。如果没有z缓冲区,保留模式无法给覆盖层排序。没有指定z顺序的覆盖层被缺省设定为0,处于最底层。一共可以有四十亿个覆盖层(应该够用了吧!),z顺序为2的层将可能遮掩了z顺序为1的层的某些内容。记住,不能有两个层的z顺序相同。
关于3D场景,还有诸如材资、光源等概念,在此不再一一聱述。
第九节 Vc++中引入Direct SDK
一旦安装了SDK,就得马上通知Visual C++ SDK的位置。默认状态下,SDK安装在dxsdk目录下。头文件放在dxsdk/inc目录下,库文件放在dxsdk/lib目录下。
可利用下述两种方法之一通知visual C++ SDK的位置。一种方法是在使用文件时给出完整的文件路径;另一种法是将这些目录加到Visual C++的搜索路径中。第二种方法更好一些,可以通过Tools[Options]Directories对话框实现。
增加dxsdk/lib目录的方法大体上同增加dxsdk/inc目录的方法相同。
如果你获得了一个含有比Visual C++的DirectX SDK新的版本,您需要将DirectX SDK目录置于常规的Visual C++目录上面。否则就得使用旧版本。(Visual C++从上至下查找目录)
根据我们已经讨论过的内容,你应该能够编辑DirectX程序了。然而还有最后一个潜在的障碍。除非INITGUID符号已经被定义,否则在DirectX GUIDs下调用Query-Interface()函数的程序同DirectX2 SDK的链接会失败。INITGUID符号只能由一个源文件定义,并且必须出现在#include语句之前,如下列代码所示:
#define INITGUID
#include〈ddraw.h〉
//…other includes…
对于DirectX3及以上版本,这种解决方法都是有效的,但还有一个更好的方法,即将dxguid.lib文件链接到你的工程上(Build[Settings]Link对话框),以替代INITGUID符号的定义。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -