一个简单的DDraw应用程序

转载 2015年07月08日 10:28:18

上次谈到DDraw是一个组件。组件由接口组成。

DDraw总共由五个接口组成: 

IUnknown:所有com接口都必须从这里继承的。(请看相关文章COM笔记-QueryInterface函数

IDirectDraw:使用DDraw必须创建的主接口对象。

IDirectDrawSurface:创建、控制和显示的实际显示表面。分主显示表面和从显示表面

IDirectDrawPalette:创建、加载和控制调色板,以及将它关联到显示表面。

IDirectDrawClipper:剪切DDraw光栅和位图操作到一些可见显示表面的子集。

 

  

 

这些接口怎么配合起来成为一个DDraw应用程序的: 

1.  创建DDraw对象并使用QueryInterface()来得到 一个IDirectDraw7接口,或是直接用DirectDrawCreateEx()创建一个DDraw7接口。用这个接口来设置协作级别和视频模式。

2.  使用IDirectDrawSurface7接口至少创建 一个主显示表面用以绘图。(如果每个像素为8位或更少我们会用到一个调色板)

3.  用IDirectDrawPalette接口创建 一个调色板。(注意如果像素高于8位,如16位、24位,32位,没有调色板,现在主流2D游戏多数是16色)

4.  如果DDraw应用程序要使用窗口,或者要减少位图以免溢出DDraw显示表面的可见边界,我们至少需要合建一个剪裁器并将其尺寸设置为可见窗口的范围。如下图

 

5.  最后就是在表面上绘图了。

下面开始介绍一个最简单的DDraw应用程序: 

创建DDraw对象:

用来DirectDrawCreateEx来直接创建DDraw对象,声明如下:

  

HRESULT WINAPI DirectDrawCreateEx(
  GUID FAR *lpGUID,              // 视频显卡驱动的GUID,NULL表示系统默认的硬件
  LPVOID *lplpDD,                // 这是返回的接口
  REFIID iid,                    // 请求接口相对应的ID
  IUnknown FAR *pUnkOuter        // 总是高为NULL
);

  

设置协作级别:

对DDraw来说,我们唯一关心的是视频显示设备,有两种情况:全屏模式和窗口模式。

用SetCooperativeLevel来设置DDraw的协作级别。声明如下:

HRESULT SetCooperativeLevel(HWND hWnd,     // 窗口句柄,一般使用主窗口句柄
                           DWORD dwFlags);    // 控制标志

dwFlags控制标志,它直接影响DDraw与Windows之间协作方式。

SetCooperativeLevel()的控制标记 

描述

DDSCL_ALLOWMODEX

允许使用Mode X (320x200,240,400) 显示模式.公当设置DDSCL_EXCLUSIVE和DDSCL_FULLSCREEN时生效

DDSCL_ALLOWREBOOT

允许在排他(全屏)模式下检测到Ctrl+Alt+Del

DDSCL_EXCLUSIVE

请求排他级别。此标记需要与DDSCL_FULLSCREEN标记同时作用

DDSCL_FPUSETUP

表示调用 程序希望配置FPU以得到最佳的Direct3D性能(禁用度和异常),这样Direct3D不需要每次都明确地FPU。更多信息,请在DirectX SDK中查询“DDraw协作级别和FPU数度”

DDSCL_FULLSCREEN

表示使用全屏模式。其他应用程序的GDI将不能写屏,此标记必须与DDSCL_EXCLUSIVE标记同时使用。

DDSCL_MULTITHREADED

请求对于多线程安全的DDraw行为。

DDSCL_NORMAL

表示应用程序是一个通常的Windows应用程序。这个标记不能与DDSCL_ALLOWMODEX, DDSCL_EXCLUSIVE, 或 DDSCL_FULLSCREEN标记一起使用。

DDSCL_NOWINDOWCHANGES

表示不允许DDraw激活时最小化或还原应用程序窗口。

上面写了一大堆标记,其实大多数情况是下面两种情况。

全屏模式:DDSCL_FPUSETUP | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT

窗口模式:DDSCL_NORMAL

下面例子:

因为是用于学习,没有把框架搞得太复杂,全写在一个cpp里了。

关于怎么写一个GUI应用程序,可以查看《一个简单的windows GUI应用程序

http://www.cnblogs.com/fangyukuan/archive/2010/08/31/1814159.html

源代码下载

//------------------------------------------------------------------------- // 文件名 : 6_1.cpp // 创建者 : 方煜宽 // 邮箱 : fangyukuan@gmail.com // 创建时间 : 2010-12-1 23:37 // 功能描述 : 一个简单的DDraw应用程序 // 注意在工程中把ddraw.lib包含进去 // ------------------------------------------------------------------------- #define INITGUID #include<windows.h> #include <ddraw.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); HWND main_window_handle = NULL; // 主窗口句柄 LPDIRECTDRAW7 lpdd = NULL;   // DDraw 对象 int Game_Init(void *parms = NULL, int num_parms = 0) { // 创建ddraw对象 if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL))) return(0); // 窗口模式(设置协作级别) lpdd->SetCooperativeLevel(main_window_handle, DDSCL_NORMAL); return 1; } ///////////////////////////////////////////////////////////// int Game_Shutdown() { if (lpdd) { lpdd->Release(); lpdd = NULL; } return 1; }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { HWND hwnd; MSG msg; TCHAR lpszClassName[] = TEXT("kuan"); WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = ::LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = ::LoadCursor(NULL,IDC_ARROW); wc.hbrBackground = (HBRUSH)::GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = lpszClassName; RegisterClass(&wc); // WS_OVERLAPPEDWINDOW 可以改变窗口大小 // WS_OVERLAPPED 不可以改变窗口大小 // WS_POPUP 全屏 hwnd = CreateWindow(lpszClassName, TEXT("fangyukuan"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 300,80,800,600, NULL, NULL, hInstance, NULL); main_window_handle = hwnd; // ::ShowWindow(hwnd,SW_SHOWNORMAL); // ::UpdateWindow(hwnd); // while(::GetMessage(&msg,NULL,0,0)) // { // ::TranslateMessage(&msg); // ::DispatchMessage(&msg); // } Game_Init(); while(TRUE) { if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) break; ::TranslateMessage(&msg); ::DispatchMessage(&msg); } } Game_Shutdown(); return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: { ::MessageBeep(0); } break; case WM_DESTROY: ::PostQuitMessage(0); break; default: return ::DefWindowProc(hwnd,message,wParam,lParam); } return 0; }

 程序运行效果:

 

相关文章推荐

一个简单的DDraw应用程序

方煜宽 2011.05.13 上次谈到DDraw是一个组件。组件由接口组成。 DDraw总共由五个接口组成:  IUnknown:所有com接口都必须从这里继承的。(请看相关文章COM笔记-Q...

一个简单的Login 应用程序

  • 2013-04-07 23:53
  • 147KB
  • 下载

数据库表表面上存在索引和防错机制,然而一个简单的查询就会耗费很长时间。Web应用程序或许在开发环境中运行良好,但在产品环境中表现同样糟糕。如果你是个数据库管理员,你很有可能已经在某个阶段遇到上述情况。

人们一直在推动MySQL发展到它的极限。这里是100条调节和优化MySQL安装的技巧。一些技巧是针对特定的安装环境的,但这些思路是通用的。我已经把他们分成几类,来帮助你掌握更多MySQL的调节和优化技...

java一个简单的应用程序

  • 2007-04-24 15:03
  • 31KB
  • 下载

一个简单的 Silverlight 4 应用程序(MEF+ MVVM+ WCF RIA Services)第三部分

注:本文是Weidong Shen先生在CodeProject上的文章,为了学习方便,进行了全文翻译,后续将以此程序示例为蓝本,写出自已的实用LOB程序来,在此向Weidong Shen先生表示感谢,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)