一个简单的DDraw应用程序
阅读排行榜
评论排行榜
一个简单的DDraw应用程序
方煜宽
2011.05.13
上次谈到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;
}
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;
}

程序运行效果:

转载请保留下面链接
http://www.cnblogs.com/fangyukuan/archive/2011/05/13/2045951.html
一个简单的DDraw应用程序的更多相关文章
- 一个简单的DDraw应用程序2
//------------------------------------------------------------------------- // 文件名 : 6_1.cpp// 创建者 : ...
- 一个简单的P2P传输程序
写了一个简单的P2P传输程序,在P2P的圈子中传输文件,不过为了简便,这个程序没有真正的传输文件,只是简单的判断一下文件的位置在哪里.这个程序可以处理当有一个peer闪退的情况,在这种情况下,剩下的p ...
- IOS开发之小实例--使用UIImagePickerController创建一个简单的相机应用程序
前言:本篇博文是本人阅读国外的IOS Programming Tutorial的一篇入门文章的学习过程总结,难度不大,因为是入门.主要是入门UIImagePickerController这个控制器,那 ...
- iOS开发UI篇—使用嵌套模型完成的一个简单汽车图标展示程序
iOS开发UI篇—使用嵌套模型完成的一个简单汽车图标展示程序 一.plist文件和项目结构图 说明:这是一个嵌套模型的示例 二.代码示例: YYcarsgroup.h文件代码: // // YYcar ...
- 一个简单的MDI示范程序(Delphi)
http://www.cnblogs.com/pchmonster/archive/2012/01/07/2316012.html 最为一个巩固之前有关窗体和对象的有关知识,下面就建立一个简单的MDI ...
- Linux内核监控模块-1-驱动模块(LKM)开发(以一个简单的hello world程序为例)
在上面一篇中介绍到,监控模块要做成一个驱动模块(或者说是可加载模块,LKM),动态的加载到Linux内核中.那么这篇就简单的介绍一下怎样做一个这样的驱动模块. 以简单的hello world程序为 ...
- C++ 容器的综合应用的一个简单实例——文本查询程序
C++ 容器的综合应用的一个简单实例——文本查询程序 [0. 需求] 最近在粗略学习<C++ Primer 4th>的容器内容,关联容器的章节末尾有个很不错的实例.通过实现一个简单的文本查 ...
- Cocoa练习01:一个简单的Todo list程序
写一个简单的todo list程序,界面如下图: 在TextField区域输入文字,点击Add按钮会将文字显示在下面的TableView列表中.TableView列表有2列,第一列是文字的输入时间:第 ...
- 一个简单的python爬虫程序
python|网络爬虫 概述 这是一个简单的python爬虫程序,仅用作技术学习与交流,主要是通过一个简单的实际案例来对网络爬虫有个基础的认识. 什么是网络爬虫 简单的讲,网络爬虫就是模拟人访问web ...
随机推荐
- 简单的实现QQ通信功能(五)
第五部分:聊天界面的设计及代码 一:效果图及界面设计 1. 效果图: 2. 界面设计: (1)左上角显示朋友的头像和“某某正在和某某聊天”. (2)中间的聊天窗口用了一个ListView,视图用详细信 ...
- modelsim remote
远程桌面登陆我的台式机上的账号,然后运行modelsim 出现该问题: Unable to checkout a viewer license necessary for use of the Mod ...
- 第九篇:web之前端之web上传文件的方式
前端之web上传文件的方式 前端之web上传文件的方式 本节内容 web上传文件方式介绍 form上传文件 原生js实现ajax上传文件 jquery实现ajax上传文件 form+iframe构 ...
- nofollow标签如何使用
“nofollow”的意思是不传递权重,向网站站长提供了一种方式,即告诉搜索引擎“不要追踪此网页上的链接”或“不要追踪此特定链接”. nofllow的形式 1.<meta name=" ...
- C# if,ifelse语句
1,if语句的判断是根据布尔表达式的值. if语句主要有两种方式,如下 Code(1)if(boolean) do (2)if(boolean){ do } 一般大家都是用第二种方法,因为第一种方法只 ...
- [ lucene高级 ] 研讨如何进行Lucene的分布式应用
http://www.cnblogs.com/huangfox/archive/2010/10/15/1852206.html Lucene是个高度优化的倒转索引搜索引擎.它将倒转的索引存储在定制的文 ...
- Opencv读取视频一闪而过情况分析
在参加一个软件比赛需要用opencv对视频的处理,也碰到了一些问题. 最常见的就是视频一闪而过了,在网上查了好久都没解决, 最后重装在配置环境变量时发现的. 现在我来终结一下估计是比较全的了. 先说明 ...
- temporary
private void OnAttendeeConnected(object pObjAttendee) { IRDPSRAPIAttendee pAttendee = pObjAttendee a ...
- LINQ2EF-LINQ2SQL-LINQ笔记
例1:In SQL: AND dep_all_code LIKE '" + depAll + "' AND dep_code in (SELECT DISTINCT DEP3 FR ...
- 使用RequireJS优化Web应用前端
require.js官网:http://requirejs.org/docs/download.html 一篇不错的文章:http://www.csdn.net/article/2012-09-27/ ...