- 填充一个DDSURFACEDESC2的数据结构,描述你所希望创建的显示表面。
- 调用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())他们。