[英]Creating DirectDraw Surface from scratch in c++
I'm trying to convert a 2d array to a DDS and saving it to a file. 我正在尝试将2d数组转换为DDS并将其保存到文件中。 Array is full of Color structs (each having a red, green, blue and alpha component). 数组充满了颜色结构(每个都有红色,绿色,蓝色和alpha分量)。 Once I get the array to the correct format, I'm sure the saving it to file part won't be a problem. 一旦将数组设置为正确的格式,就可以确定将其保存到文件部分不会有问题。
I'm fine with either using a lib for this (as long as its license allows me to use it in a closed source project and works on both Linux and Windows) or doing it manually, if I can find a nice resource explaining how to do it. 我可以为此使用一个库(只要它的许可证允许我在一个封闭的源项目中使用它并且可以在Linux和Windows上运行)就可以了,或者可以手动进行,如果我能找到一个很好的资源来解释如何做吧。
If anyone can point me in the right direction, I'd really appreciate it. 如果有人能指出正确的方向,我将非常感激。
In DirectDraw you can create a surface from the data in memory, by setting up certain fields in the DDSURFACEDESC
structure and passing it to the CreateSurface
method of the IDirectDraw
interface. 在DirectDraw中,可以通过在DDSURFACEDESC
结构中设置某些字段并将其传递给IDirectDraw
接口的CreateSurface
方法,从内存中的数据创建表面。
First you need to tell DirectDraw which fields of the DDSURFACEDESC
structure contain the correct information by setting the dwFlags
field to the following set of flags: DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_LPSURFACE | DDSD_PITCH
首先,您需要通过将dwFlags
字段设置为以下标志集来告诉DirectDraw DDSURFACEDESC
结构的哪些字段包含正确的信息: DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_LPSURFACE | DDSD_PITCH
DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_LPSURFACE | DDSD_PITCH
DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_LPSURFACE | DDSD_PITCH
. DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_LPSURFACE | DDSD_PITCH
。
Oh, and this only works for system-memory surfaces, so it's probably needed to add the DDSCAPS_SYSTEMMEMORY
flag in the ddsCaps.dwCaps
field (if DirectDraw won't do it by default). 哦,这仅适用于系统内存表面,因此可能需要在ddsCaps.dwCaps
字段中添加DDSCAPS_SYSTEMMEMORY
标志(如果DirectDraw默认情况下不这样做)。
Then you specify the address of the beginning of your pixel data array in the lpSurface
field. 然后,在lpSurface
字段中指定像素数据数组的开始地址。 If your buffer is continuous, just set the lPitch
to 0. Else you set the correct pitch there (the distance in bytes between the beginnings of two subsequent scanlines). 如果您的缓冲区是连续的,则只需将lPitch
设置为0。否则,您可以在此处设置正确的音高(两个后续扫描线的起点之间的距离,以字节为单位)。
Set the correct pixel format in ddpfPixelFormat
field, with correct bit depth in dwRGBBitCount
and RGB masks in dwRBitMask
, dwGBitMask
and dwBBitMask
. 在ddpfPixelFormat
字段中设置正确的像素格式,在ddpfPixelFormat
设置正确的位深度,在dwRBitMask
, dwGBitMask
和dwBBitMask
中dwRGBBitCount
RGB掩码。
Then set the lXPitch
to the number of bytes your pixel has (3 for RGB). 然后将lXPitch
设置为像素的字节数(对于RGB为3)。 It depends on the pixel format you use. 这取决于您使用的像素格式。
Then pass the filled structure into CreateSurface
and see if it works. 然后将填充的结构传递到CreateSurface
,看看它是否有效。
When you create the surface this way, keep in mind that DirectDraw will not manage its data buffer himself, and won't free this memory once you call Release
on your surface. 当您以这种方式创建表面时,请记住DirectDraw不会自己管理其数据缓冲区,并且一旦在表面上调用Release
,就不会释放该内存。 You need to free this memory yourself when it's no longer used by the surface. 当表面不再使用它时,您需要自己释放此内存。
If you want this pixel data to be placed in video memory, on the other hand, you need to create an offscreen surface in a usual way and then lock it, copy your pixels to its own buffer in video memory (you'll find its address in the lpSurface
field, and remember to take lPitch
in count!), and then unlock it. 另一方面,如果要将这些像素数据放置在视频内存中,则需要以通常的方式创建一个屏幕外表面,然后将其锁定,将像素复制到视频内存中自己的缓冲区中(您会找到它的地址lpSurface
字段中,请记住输入lPitch
!),然后将其解锁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.