32BPP窗口模式下24位位图的像素操作(1)

刚学习了几天DirectDraw,书中作者示例多是8位调色板的全屏程序,而且是读取8位位图,可以很方便的使用SetDisplayMode来改变显示模式,按字节写入像素。而在窗口模式中,现在普遍的32BPP和使用24位位图就没有那么方便了,而且书中没有很完整的示例。

使用窗口模式的DirectDraw主要有以下几个问题:

1.24位位图的像素格式到32位像素格式的转换

2.不能使用Flip,需要使用Blt从离屏表面来复制到主显示表面。

3.确定真正的用户窗口。

4.剪裁。

后3个问题书中给了很好的示例,但是对于第1点,像素操作没有说的太多,作者的意思是不要立刻陷于技术细节。但是在今天我想独立写一个窗口的DD程序时确实遇到像素操作上的问题。

0.本来我是这样想的

24位位图数据区[RR][GG][BB] ……

映射在32位BPP的每个像素时在前面的A位补零即可:[00][RR][GG][BB]

但却出现了颜色怎么都不对的情况。

1.24位位图的数据区是如何存放的

位图的14Bytes+40Bytes+4*nBytes的三个头就不说了。直接用_lread或者ReadFile读入Microsoft相应的结构就OK了。因为颜色不对,所以我用UltraEdit查看了一个我画的全紫色的24位位图,数据区如下:

[FF][00][80] ……

查了一下颜色表,等于是:

[BB][GG][RR]。

可以发现,顺序与RGB正相反。

2.显示表面的像素格式

于是修改程序,在显示表面也反序写入:

[BB][GG][RR][AA] ……

试验成功。

3.用法

使用宏,生成一个DWORD:

_RGB32BIT(0, 128, 0, 255) 等价于 00 80 00 FF。

由于是littleendian,所以这个DWORD在内存的表示顺序是 [FF][00][80][00]。

使用下面的语句就可以在(x,y)上进行相应对24位位图的着色:

4.补充

上面的代码只适用于位图像素宽度为4的倍数的情况,而当位图像素个数不是4的倍数则会在每行补适当的0,所以在计算索引时要有相应的改动,下面的代码实现了将按bmp中倒行排序的buffer转成正常顺序,并且计算了补零,读取一个BITMAP24的示例。

你可能感兴趣的:(数据结构,Microsoft)