简体   繁体   English

在C ++中从头开始创建DirectDraw Surface

[英]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设置正确的位深度,在dwRBitMaskdwGBitMaskdwBBitMaskdwRGBBitCount 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM