1.1.DirectX基本简介
DirectX是微软开发的多媒体应用程序接口(API)(包括图形,声音,输入,网络)。Direct代表直接的意思,X代表很多部分,DirectX就是一系列的DLL(动态连接库)。
微软的DirectX软件开发工具包(SDK)提供了一套优秀的应用程序编程接口(APIs),这个编程接口可以提供给你开发高质量、实时的应用程序所需要的各种资源。DirectX技术的出现将极大的有助于发展下一代多媒体应用程序和电脑游戏。
1.2.DirectX的设备无关性
微软开发DirectX,其最主要的目的之一是促进在Windows操作系统上的游戏和多媒体应用程序的发展。在DirectX出现以前,主要的游戏开发平台是MS-DOS,游戏开发者们为了使他们的程序能够适应各种各样的硬件设备而绞尽脑汁。自从有了DirectX,游戏开发者们便可以获益于Windows平台的设备无关性,而又不失去直接访问硬件的特性。DirectX主要的目的就是提供象MS-DOS一样简洁的访问硬件的能力,来实现并且提高基于MS-DOS平台应用软件的运行效果,并且为个人电脑硬件的革新扫除障碍。
另一方面,微软公司开发DirectX是为了在当前或今后的计算机操作系统上提供给基于Windows平台的应用程序以高表现力、实时的访问硬件的能力。DirectX在硬件设备和应用程序之间提供了一套完整一致的接口,以减小在安装和配置时的复杂程度,并且可以最大限度的利用硬件的优秀特性。通过使用DirectX所提供的接口,软件开发者可以尽情的利用硬件所可能带来的高性能,而不用烦恼于那些复杂而又多变的硬件执行细节。
1.3.DirectX和应用程序的关系
DirectX介于硬件和Windows应用程序之间,能够主动探测硬件的性能,当可以用硬件完成时,就直接通过硬件工作,如果硬件不支持,就通过软件模拟实现。如下图(HAL是硬件抽象层,HEL是硬件仿真层/软件模拟层)
1.4.DirectX的发展历程
每一代DirectX都向下兼容,支持之前的版本。
1.5.DirectXSDK和DirectX组件
在开发中,DX分为两个部分,一个是运行库,通过DX编译出来的程式必须要有运行库的支持,另外一个是开发库,也就是常说的SDK,这部分是在编译DX程序中是必需的。
DirectXSDK,英文原意:DirectXSoftwareDevelopmentKit,是微软所开发出的一套主要用在设计多媒体、2D、3D游戏及程序的API,其中包含了各类与制作多媒体功能相关的组件(Componet),各个组件提供了许多处理多媒体的接口与方法。本教程使用DirectX9.0SDK。
DirectX组件包括以下部分DirectDraw、Direct3D、DirectSound、DirectMusic、DirectInput、DirectPlay、DirectSetup、DirectShow。
1.5.1.DirectXGraphics
视频处理和图形渲染,帮助我们完成2D和3D图像的绘制处理,在7.0之后的版本中,原先负责二维图形的DirectDraw已经停止更新,D3D同时肩负起二维和三维的图形绘制的任务。
1.5.2.DirectXAudio
音频处理,帮助我们完成音效和音乐的播放和处理。包括主要针对波形音频进行播放处理的DirectSound,多用于处理游戏中的音效部分。以及DirectMusic,用来播放MIDI音乐,用来实现游戏中的背景音乐。
1.5.3.DirectInput
该系统处理一切设备输入,包括鼠标,键盘,摇杆,手柄,滚球等等。现在其还支持力反馈设备(由机电传动设备和力传感器组成,让你能感觉真实的力的设备)。
1.5.4.DirectPlay
DirectX的网络部分。它使你能够通过使用Internet、调制解调器、直接电缆连接或其他任何未来的连接媒介建立抽象连接。DirectPlay允许在对网络一无所知的情况下建立连接。无需写驱动,用sockets或类似的东西。此外,DirectPlay支持游戏进行中的聊天概念和玩家用以聚集和游戏的游戏大厅概念。
1.5.5.DirectSetup/AutoPlay
允许一个程序从你的应用程序所在客户机上安装DirectX并在插入CD光盘后直接启动你的游戏的准DirectX组件。DirectSetup是个小的函数集。这个函数集合在客户机上加载DirectX的运行时文件,并在注册表中注册这些文件。AutoPlay是标准CD子系统,其寻找CD盘根目录下的AUTOPLAY.INF文件。如果找到该文件,AutoPlay便执行文件中的批处理命令。
1.5.6.DirectShow
DirectShow是一个windows平台上的流媒体框架,提供了高质量的多媒体流采集和回放功能。它支持多种多样的媒体文件格式,包括ASF、MPEG、AVI、MP3和WAV文件,同时支持使用WDM驱动或早期的VFW驱动来进行多媒体流的采集。DirectShow整合了其它的DirectX技术,能自动地侦测并使用可利用的音视频硬件加速,也能支持没有硬件加速的系统。
DirectShow大大简化了媒体回放、格式转换和采集工作。但与此同时,它也为用户自定义的解决方案提供了底层流控制框架,从而使用户可以自行创建支持新的文件格式或其它用途的DirectShow组件。
1.5.7.Windows编程的命名约定
一直以来,最流行的变量命名约定是所谓的匈牙利表示法(HungarianNotation).最初由Microsoft的CharlesSimonyi提出,并且在Microsoft内部使用了许多年。
匈牙利命名法是在变量名前习惯地加一个字母来帮助标识变量的类型。例如,在hPrevInstance中的“h”表示这个hPrevInstance是HINSTANCE类型或HANDLE类型。同样,在nCmdShow中的“n”代表它是一个整型量。
下面列出匈牙利命名法中常用的小写字母的前缀
前缀 |
类型 |
示例 |
b |
BOOL |
bFlag |
by |
BYTE |
byBuffer |
chr |
char |
chrAlpha |
w |
WORD |
wSpeed |
dw |
DWORD |
dwHitList |
i |
Int |
iTmp |
n |
Intorshort |
nCmdShow |
l |
long |
lPitch |
f |
float |
fSpeed |
d |
double |
dDirection |
p |
Pointer |
pArray |
v |
D3DVECTOR3 |
vLight |
s |
String |
sQuestion |
sz |
Stringterminatedby0 |
szQuestion |
h |
Handle |
hResult |
I |
COMinterface |
IDirect3D |
m_ |
ClassMember |
m_pFloorVertices |
c |
Constant |
cText |
Windows应用程序
1.6.基本的Windows应用程序运行流程
1.7.Windows应用程序编程的基本方法
通常情况下,要建立一个基本的Windows程序,都必须经历以下步骤:
1.8.建立更好的消息循环
在之前学习Windows编程时,我们在建立消息循环时,通常使用GetMessage函数来读取消息,如下:
while (GetMessage (&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
但是实际上我们在做DirectX的应用时,一般不采用GetMessage函数,而是采用PeekMessage来建立消息循环。
这是因为采用PeekMessage的方法效率会高一些。这与这两个函数的实现有关。这两个函数在有消息向程序传递时,执行的过程是相似的,主要区别是在没有消息的时候,GeMessage会让程序进入Sleep状态,而PeekMessage则返回程序一个NULL值,那么程序可以比较高效的利用系统的空闲时间。
如下面的代码:
MSG msg; BOOL bMessage; PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); while(msg.message != WM_QUIT) { bMessage = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); if(bMessage) { TranslateMessage(&msg); DispatchMessage(&msg); } else { //No message to process, so render the current scene Render(); }
基本Windows程序窗口
下面是程序的完整代码:
源代码的下载地址:http://download.****.net/source/2899382
/* * File : WinForm.cpp * Description : Create a simple windows form application * Author : GuoShaoHao * E-mail : [email protected] * Date : 2010/12/06 * * CopyRight @ South China Institute of Software Engineering,.GZU * */ #include <windows.h> //----------------------------------------------------------------------------- // Name: MsgProc() // Desc: 窗口消息句柄 //----------------------------------------------------------------------------- LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_DESTROY: PostQuitMessage( 0 ); return 0; } return DefWindowProc( hWnd, msg, wParam, lParam ); } //----------------------------------------------------------------------------- // Name: WinMain() // Desc: 应用程序入口 //----------------------------------------------------------------------------- INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT ) { // 注册窗口类 WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, "WinForm", NULL }; RegisterClassEx( &wc ); // 创建应用程序窗口 HWND hWnd = CreateWindow( "WinForm", "基本的Windows程序", WS_OVERLAPPEDWINDOW, 100, 100, 640, 480, GetDesktopWindow(), NULL, wc.hInstance, 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( "WinForm", wc.hInstance ); return 0; }