下面就该用 DirectX 8 来写字了。(●^o^●)
MS/DOS 下一行就办了的程序,现在都长成这样。(^_^;
忍着点儿,慢慢往后学。(f^_^)
跟以前的版本比起来, DirectX 8 还算是托了 Common 文件夹下那4个文件的福,大幅简化了源程序哩。
程序的执行过程如下:
1.
创建窗口;
2.
初始化 DirectDraw ;
3.
创建 Sueface(表面) 储存字符串 "Hello DirectX 8 !" ;
4.
进入消息循环;
5.
循环中反复描绘 "Hello DirectX 8 !" ;
6.
按任意键退出。
下面是 DirectDraw 的 global 区域。
Display 和储存字符串的 Sueface(用于描绘的内存区域),
g_bActive 是 DirectDraw 初始化成功的标志。
CDisplay*
g_pDisplay
= NULL;
CSurface*
g_pTextSurface= NULL;
BOOL
g_bActive
= FALSE;
下面是初始化 DirectDraw 的代码。
若初始化失败就显示错误信 息并返回;
创建储存文本的 Sueface(用于描绘的内存区域) 并以点阵图的形式储存 "Hello DirectX 8 !" ;
RGB(0,0,0)、RGB(255,255,0) 分别是背景色和前景色,R(红)、G(绿)、B(蓝)在 0~255 的范围内分别指定。这里设定背景色为黑色、文字色(前景色)为黄色。
HRESULT InitDirectDraw(HWND hWnd)
{
HRESULT
hr;
g_pDisplay = new CDisplay();
if (FAILED(hr= g_pDisplay-CreateFullScreenDisplay(hWnd, 640, 480, 16)))
{
ERMSG("This display card does not support 640x480x16.");
return hr;
}
// Create a surface, and draw text to it.
if (FAILED(hr= g_pDisplay-CreateSurfaceFromText(&g_pTextSurface,
NULL,"Hello DirectX 8 !",RGB(0,0,0),RGB(255,255,0))))
return hr;
return S_OK;
}
下面是 Message Loop(消息循环) 。
用 DisplayFrame() 逐帧描绘。
while(TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (0 == GetMessage(&msg, NULL, 0, 0))
return (int)msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if (g_bActive)
{
if (FAILED(DisplayFrame()))
{
SAFE_DELETE(g_pDisplay);
ERMSG("Displaying the next frame failed. The sample will now exit.");
return FALSE;
}
}
else
WaitMessage();
}
}
下面是描绘代码。
用 Clear() 清空 DisplaySurface ;
用 Blt() 描绘已被转换为点阵图的字符串;
用 Present() 换帧。
HRESULT DisplayFrame()
{
HRESULT hr;
// Fill the back buffer with black, ignoring errors until the flip
g_pDisplay-Clear(0);
// Blt all the sprites onto the back buffer.
g_pDisplay-Blt(0, 0, g_pTextSurface, NULL);
// We are in fullscreen mode, so perform a flip and return
if (FAILED(hr= g_pDisplay-Present())) return hr;
return S_OK;
}
下面说明创建工程的步骤:
1.
新建一个 Win32 Application 空白工程,命名为 "Hello"。
2.
向工程中新建一个 C++ Source File ,命名为 "hello" ,向其中键入篇末附带的源程序。
3.
选择菜单 [Project|工程]-[Settings...|设定] 打开[Project Settings|工程设定] 面板,点击 [Link|链接] 标签,向 [Object/library modules|对象、库模块] 栏内添加下面四个库文件:
dxguid.lib
ddraw.lib
dxerr8.lib
winmm.lib
(文件名之间用半角空格分隔)
4.
点击 [C/C++] 标签,设定 include 文件的路径(参见 §04. 移动样品到另外的文件夹):
5.
新建 Common 文件夹并向其中添加下面4个文件:
ddutil.h
dxutil.h
ddutil.cpp
dxutil.cpp
(参见 §04. 移动样品到另外的文件夹)
6.
编译并执行!
源程序:
/******************************************************/
/*★ 显示 Hello DirectX 8 !
2001-01-02
前田 稔 ★*/
/******************************************************/
#define
STRICT
#include
#include
#include
#include
"ddutil.h"
// Defines, constants, and global variables
#define SAFE_DELETE(p)
{ if (p) { delete (p);
(p)=NULL; } }
#define SAFE_RELEASE(p) { if (p) { (p)-Release(); (p)=NULL; } }
#define ERMSG(x)
MessageBox(hWnd,x,"DirectDraw Program",MB_OK);
CDisplay*
g_pDisplay
= NULL;
CSurface*
g_pTextSurface= NULL;
BOOL
g_bActive
= FALSE;
// Function-prototypes
LRESULT
CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
HRESULT
WinInit(HINSTANCE hInst, int nCmdShow, HWND* phWnd);
HRESULT
InitDirectDraw(HWND hWnd);
VOID
FreeDirectDraw();
HRESULT
DisplayFrame();
//★ Windows Main
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int nCmdShow)
{
MSG
msg;
HWND
hWnd;
if (FAILED(WinInit(hInst, nCmdShow, &hWnd)))
return FALSE;
if (FAILED(InitDirectDraw(hWnd)))
{
if (g_pDisplay)
g_pDisplay-GetDirectDraw()-SetCooperativeLevel(NULL, DDSCL_NORMAL);
ERMSG("DirectDraw init failed. The sample will now exit.");
return FALSE;
}
while(TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (0 == GetMessage(&msg, NULL, 0, 0))
return (int)msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if (g_bActive)
{
if (FAILED(DisplayFrame()))
{
SAFE_DELETE(g_pDisplay);
ERMSG("Displaying the next frame failed. The sample will now exit.");
return FALSE;
}
}
else
WaitMessage();
}
}
}
//★ WinInit()
HRESULT WinInit(HINSTANCE hInst, int nCmdShow, HWND* phWnd)
{
WNDCLASS wc;
HWND
hWnd;
// Register the Window Class
wc.lpszClassName = TEXT("Hello DirectX 8 !");
wc.lpfnWndProc
= MainWndProc;
wc.style
= CS_VREDRAW | CS_HREDRAW;
wc.hInstance
= hInst;
wc.hIcon
= LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor
= LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName
= NULL;
wc.cbClsExtra
= 0;
wc.cbWndExtra
= 0;
if (RegisterClass(&wc)==0)
return E_FAIL;
// Create and show the main window
hWnd = CreateWindowEx(0, TEXT("Hello DirectX 8 !"), TEXT("DirectDraw TEXT View"),
WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL);
if (hWnd==NULL)
return E_FAIL;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
*phWnd = hWnd;
return S_OK;
}
//★ InitDirectDraw()
HRESULT InitDirectDraw(HWND hWnd)
{
HRESULT
hr;
g_pDisplay = new CDisplay();
if (FAILED(hr= g_pDisplay-CreateFullScreenDisplay(hWnd, 640, 480, 16)))
{
ERMSG("This display card does not support 640x480x16.");
return hr;
}
// Create a surface, and draw text to it.
if (FAILED(hr= g_pDisplay-CreateSurfaceFromText(&g_pTextSurface,
NULL,"Hello DirectX 8 !",RGB(0,0,0),RGB(255,255,0))))
return hr;
return S_OK;
}
//★ FreeDirectDraw()
VOID FreeDirectDraw()
{
SAFE_DELETE(g_pTextSurface);
SAFE_DELETE(g_pDisplay);
}
//★ MainWndProc()
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_KEYDOWN:
PostMessage(hWnd, WM_CLOSE, 0, 0);
return 0L;
case WM_SIZE:
// Check to se