主角登场——显示表面

显示在屏幕上的图像只不过是以某种格式存储在内存中的有色象素组成的矩阵,或是调色板化的或是RGB模式的。DirectDraw中有两种显示表面:主显示表面 和 从显示表面。
 
主显示表面直接对应于被显示卡光栅化的实际显存,且任何时候都是可见的。
 
从显示表面是比较灵活的,可以是任意大小,驻留在VRAM或者系统内存中的数据块。一般为了达到显示平滑的效果,总是会创建一个或两个从显示表面,他们和主显示表面有同样的色彩深度和几何分布。这称为双缓冲或者三缓冲。
 
那么怎么创建一个和你的显示模式同样大小的简单主显示表面呢?步骤如下:
  1. 填充一个DDSURFACEDESC2的数据结构,描述你所希望创建的显示表面。
  2. 调用IDIRECTDRAW7::CreateSurface()来创建显示表面。

对于DDSURFACEDESC2结构,我们只需要填充里面的部分成员。代码如下:

LPDIRECTDRAWSURFACE7  lpddsprimary = NULL;
DDSURFACEDESC2 ddsd; 

memset(&ddsd, 0, sizeof(ddsd) ) ;  

ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS; 
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;   

lpdd7->CreateSurface(&ddsd, &lpddsprimary, NULL); 

对于不同的显示表面的创建,只需要修改DDSURFACEDESC2结构。具体可以查阅DirectX SDK。

接下来要做的就是对这个显示表面关联调色板(因为我们这里所讨论的是256色的情况,也是初学者容易开始的模式)。

代码如此简单:

lpddsprimary->SetPalette(lpddpal); 

这都要感谢DirectDraw的设计精良,给我们带来了如此简单的代码。

有了以上的一切,我们下来就可以到真正激动人心的时候了。我们可以干什么?来点看得见的东西——绘制象素

在此之前,我想对整个过程做一个小小的回顾:我们要绘制象素,需要先做些什么呢?首先必须建立DirectDraw对象,设置协作级别,设定一个显示模式,并创建至少一个主显示表面,然后你需要为他关联一个调色板(256色模式的情况)。对,就是那么简单。

我们要绘制象素,也就是写表面,就必须要先获得表面的控制权,并且告诉DirectX不能有其他的进程来访问。这也很容易,DirectDraw提供了加锁的功能。

代码也如此简单:

memset(&ddsd, 0, sizeof(ddsd)); 
ddsd.dwSize = sizeof(ddsd);  
lpddsprimary->Lock(NULL,  // destination rect to lock
                                &ddsd,       // address of struct to receive info
                                DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,
         NULL); 

这篇文章一开始就说了,表面就是一个内存块,而我们又知道内存块就要有一个我们可以操作的指针。那么我们在加锁之后如果来操作表面呢?其实我们在执行加锁的参数ddsd中就已经为我们准备好了这些。ddsd.lpSurface 和 ddsd.lPitch,其中一个就是所锁表面的首指针,另外一个是以字节为单位的行宽,那么我们要对所锁表面的(x,y)(第y行x列)进行像素绘制就变得如此简单了。

代码如下:

UCHAR* buffer = (UCHAR*)(ddsd.lpSurface);  
int memPitch = (int)(ddsd.lPitch);
buffer[x+y*memPitch] = indexNumber;  // for instance 10

以上是8位索引值的情况,对于16位的真RGB值情况稍微有些不同,但是只要真正理解了Pitch和C++中的数组内存操作,写起来也不麻烦,如果有问题可以在我的共享空间留言,大家一起探讨。

现在,在学会了对表面进行像素绘制以后假设我们已经绘制(对数组赋值)好了所锁表面的所有像素,就需要对显示表面解锁。

代码如下:

lpddsprimary->Unlock(NULL);

又是那么简单:)

最后再补充一点,就是在Lock和Unlock方法调用中的第一个NULL都表示对整个表面加锁解锁,也可以传递一个RECT的指针来锁一个定制的表面。

再啰嗦一句,创建了那么多的资源,在你的程序结束以前别忘了清理(Release())他们。

By Lu Jun

80后男,就职于软件行业。习于F*** GFW。人生48%时间陪同电子设备和互联网,美剧迷,高清视频狂热者,游戏菜鸟,长期谷粉,临时果粉,略知摄影。

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.