DDraw绘图
微软已经提供了GDI+绘图方式,但是GDI+绘图较慢,另外微软提供了效率更高的DirectDraw绘图方式。DirectDraw提供硬件加速功能。
首先需要确保电脑上的Ddraw硬件加速功能已经打开,安装DirectX March 2009之后,可以在【开始】菜单->运行 Dxdiag 命令,检查是否打开硬件加速。如图1:

如果DirectDraw加速未启用,需要更新驱动。
开始使用DirectDraw编写程序,需要引入ddraw.h头文件,并把ddraw.lib添加到工程里。
DirectDrawCreate(NULL, &m_lpDirectDraw, NULL) 用于创建一个DirectDraw对象,通过该对象用来创建主表面和离屏表面。
DirectDraw有两种表面,主表面和离屏表面。主表面是现实跟用户的,离屏便面相对于一个内存块,可以进行图像处理,可以将离屏表面的图像拷贝到主表面,这样就将新的图像显示给用户了。
// 创建主表面
DDSURFACEDESC dds;
ZeroMemory(&dds, sizeof(DDSURFACEDESC));
dds.dwSize = sizeof(DDSURFACEDESC);
dds.dwFlags = DDSD_CAPS;
dds.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hr = m_lpDirectDraw->CreateSurface(&dds, &m_PrimarySurface, NULL);
以上代码用来创建一个主表面,覆盖整个屏幕,dds.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE 用来描述该表面为主表面;
// 创建备用表面
ZeroMemory(&dds, sizeof(DDSURFACEDESC));
dds.dwSize = sizeof(DDSURFACEDESC);
dds.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
dds.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
dds.dwWidth = m_ClientRect.Width();
dds.dwHeight = m_ClientRect.Height();
hr = m_lpDirectDraw->CreateSurface(&dds, &m_SecondSurface, NULL);
dds.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN 用来创建备用表面。由于本例子中,是一个CDialog窗体,所以需要创建裁剪器,将图像区域限制在一个CStatic上。
hr = m_lpDirectDraw->CreateClipper(0, &m_Clipper, NULL);
if (FAILED(hr)) return FALSE;
hr = m_Clipper->SetHWnd(NULL, m_Static.m_hWnd);
if (FAILED(hr)) return FALSE;
hr = m_PrimarySurface->SetClipper(m_Clipper);
CreateClipper用于创建裁剪器,SetHWnd设置显示区域的Handle。
备用表面创建之后需要刷一层背景色,例子中用RGB(100, 100, 100)填充背景色。然后再拷贝图像到备用表面上。
// 填充备用表面背景色
DDBLTFX bltfx;
ZeroMemory(&bltfx, sizeof(DDBLTFX));
bltfx.dwSize = sizeof(DDBLTFX);
bltfx.dwFillColor = RGB(100, 100, 100);
hr = m_SecondSurface->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx);
下面将会使用StretchBlt拷贝图像到备用表面,再用Blt把备用表面的图像拷贝到主表面上。这时候显示的图像会被更新。
hr = m_SecondSurface->GetDC(&hdc);
CDC* pDC = CDC::FromHandle(hdc);
pDC->SetStretchBltMode(COLORONCOLOR);
::StretchBlt(hdc, 0, 0, m_ClientRect.Width(), m_ClientRect.Height(), m_image.GetDC(), 0, 0, m_image.GetWidth(),
m_image.GetHeight(), SRCCOPY);
m_image.ReleaseDC();
m_SecondSurface->ReleaseDC(hdc);
m_PrimarySurface->Blt(m_ClientRect, m_SecondSurface, NULL, DDBLT_WAIT, NULL);
在开发MFC客户端程序时,通常都会遇到窗体闪烁的问题,这是因为窗体先刷一层背景色(默认为白色)再刷控件图像,由于背景色和图像反差太大,所以有闪烁的感觉,如果使用备用表面绘图,再拷贝到主表面上能有效避免闪烁。因备用表面上绘图、绘背景色不会影响到主表面显示。除非把备用表面的图像拷贝到主表面上。
如果图像缩小显示的时候需要调用SetStretchBltMode(COLORONCOLOR) 否则会像素堆积,导致图像失真。
将图像从备用表面拷贝到主表面时需要设置显示区域的屏幕坐标。否则绘图位置会有偏差。
工程如下:http://files.cnblogs.com/ityujian/TestDDraw.zip
DDraw绘图的更多相关文章
- ddraw 视频下绘图 不闪烁的方法
我们假设是在在RGB视频上绘图(直线,矩形等),一般採用双缓冲区继续,使用内存MemoryDC,来实现画的图形在视频上显示不闪烁的功能,可是我们知道用RGB显示视频都是使用GDI进行渲染,这样非常耗C ...
- 一个简单的DDraw应用程序
阅读排行榜 1. C/C++ 笔试.面试题目大汇总(72915) 2. [STL]list基础(21718) 3. COM笔记-CoCreateInstance(14842) 4. C/C++ ...
- Canvas绘图之平移translate、旋转rotate、缩放scale
画布操作介绍 画布绘图的环境通过translate(),scale(),rotate(), setTransform()和transform()来改变,它们会对画布的变换矩阵产生影响. 函数 方法 描 ...
- 用html5的canvas和JavaScript创建一个绘图程序
本文将引导你使用canvas和JavaScript创建一个简单的绘图程序. 创建canvas元素 首先准备容器Canvas元素,接下来所有的事情都会在JavaScript里面. <canvas ...
- echarts+php+mysql 绘图实例
最近在学习php+mysql,因为之前画图表都是直接在echart的实例demo中修改数据,便想着两相结合练习一下,通过ajax调用后台数据画图表. 我使用的是echart3,相比较第二版,echar ...
- html5 canvas常用api总结(二)--绘图API
canvas可以绘制出很多奇妙的样式和美丽的效果,通过几个简单的api就可以在画布上呈现出千变万化的效果,还可以制作网页游戏,接下来就总结一下和绘图有关的API. 绘画的时候canvas相当于画布,而 ...
- HTML5_04之SVG绘图
1.关于Canvas绘制图像: 问题:需要绘制多张图片时,必须等待所有图片加载完成才能开始绘制:而每张图片都是异步请求,彼此没有先后顺序,哪一张先加载完成完全无法预测: 方案: var progres ...
- HTML5 学习总结(四)——canvas绘图、WebGL、SVG
一.Canvas canvas是HTML5中新增一个HTML5标签与操作canvas的javascript API,它可以实现在网页中完成动态的2D与3D图像技术.<canvas> 标记和 ...
- AR创意分享:儿童涂鸦遇上程序绘图
第一节 临摹 小明经常临摹同桌小美的画作. 美术课上,老师表扬了小美的新作. 图1.1 小美的作品<蒙娜·毛虫的微笑> 临,是照着原作画:摹,是用薄纸张蒙在原作上面画. 第二节 借画 小明 ...
随机推荐
- Android水平(横向)翻页列表,类似水平GridVIew
Android水平(横向)翻页列表,类似于水平方向的GridView,行列自定义,但要翻页切换,考虑加载性能,当Item数据很多时加载和翻页要流畅,翻页时要有动画效果,效果图如下: 实现方式: 1:翻 ...
- linux驱动系列之ubuntu快捷键(转)
Ubuntu快捷键-终端快捷键 1.关于终端的快捷键: Tab:tab键是比较常用的一个快捷键,它的作用是补全文件名或者路径.举例 来说,输入”cd /ho”在按一下tab键,终端里就会显示 ...
- 3140:[HNOI2013]消毒 - BZOJ
题目描述 Description 最近在生物实验室工作的小 T 遇到了大麻烦. 由于实验室最近升级的缘故,他的分格实验皿是一个长方体,其尺寸为 a*b*c,a.b.c均为正整数.为了实验的方便,它被划 ...
- centos7 下载eclipse的镜像站点
这里吐槽一下,由于两天前centos被我农崩溃了(系统更新的锅),所以所有的开发环境又得重来一次. 其实,之前去eclipse的官网下载就很慢,打开官网也很慢,然后你会发现下下来的安装程序(只有40多 ...
- Hibernate简介2
一.主配置 ◆查询缓存,同下面讲的缓存不太一样,它是针对HQL语句的缓存,即完全一样的语句再次执行时可以利用缓存数据.但是,查询缓存在一个交易系统(数据变更频繁,查询条件相同的机率并不大)中可能会起反 ...
- [转载]jQuery 1.9 移除了 $.browser 的替代方法获取浏览器类型
jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support . 在更新的 2.0 版本中,将不再支持 IE 6/7/8. ...
- 团体程序设计天梯赛-练习集L1-015. 跟奥巴马一起画方块
L1-015. 跟奥巴马一起画方块 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 美国总统奥巴马不仅呼吁所有人都学习编程,甚至 ...
- The 7th Zhejiang Provincial Collegiate Programming Contest->Problem G:G - Wu Xing
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3328 至今未看懂题意,未编译直接提交,然后 A了.莫名AC总感觉怪怪的. ...
- hdu 4192
dfs全排列 加 模拟计算 #include <iostream> #include <cstdio> #include <cstdlib> #include ...
- Java 内存结构备忘录
本文详细描述了 Java 堆内存模型,垃圾回收算法以及处理内存泄露的最佳方案,并辅之以图表,希望能对理解 Java 内存结构有所帮助.原文作者 Sumith Puri,本文系 OneAPM 工程师编译 ...