我正在尝试将Qt库与SDL应用程序集成。我想将QPixmap转换为SDL_Surface,然后显示该表面。我怎样才能做到这一点?我找不到任何好的例子。
到目前为止,我已经管理了以下代码:
Uint32 rmask = 0x000000ff;
Uint32 gmask = 0x0000ff00;
Uint32 bmask = 0x00ff0000;
Uint32 amask = 0xff000000;
SDL_FillRect(screen, NULL, SDL_MapRGBA(screen->format, 255, 255, 255, 255));
const QImage *qsurf = ...;
SDL_Surface *surf = SDL_CreateRGBSurfaceFrom((void*)qsurf->constBits(), qsurf->width(), qsurf->height(), 32, qsurf->width() * 4, rmask, gmask, bmask, amask);
SDL_BlitSurface(surf, NULL, screen, NULL);
SDL_FreeSurface(surf);
SDL_Flip(screen);
这是有效的,但唯一的问题是,每次我的基于QImage的表面都被绘制时,底层区域不会被清除,透明部分会在几帧的过程中“淡化”为实体。
我确实有SDL_FillRect
我会想象清除屏幕,但它似乎没有这样做。 screen
是主要的SDL表面。
答案 0 :(得分:0)
我最初的重绘问题是因为我的源图像实际上没有得到正确清理。哎呀。一旦我修好了,我的口罩就错了;没有让我在脑海中点击SDL如何使用这些。最终的工作代码如下:
这是将QImage转换为SDL_Surface的函数:
/*!
* Converts a QImage to an SDL_Surface.
* The source image is converted to ARGB32 format if it is not already.
* The caller is responsible for deallocating the returned pointer.
*/
SDL_Surface* QImage_toSDLSurface(const QImage &sourceImage)
{
// Ensure that the source image is in the correct pixel format
QImage image = sourceImage;
if (image.format() != QImage::Format_ARGB32)
image = image.convertToFormat(QImage::Format_ARGB32);
// QImage stores each pixel in ARGB format
// Mask appropriately for the endianness
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
Uint32 amask = 0x000000ff;
Uint32 rmask = 0x0000ff00;
Uint32 gmask = 0x00ff0000;
Uint32 bmask = 0xff000000;
#else
Uint32 amask = 0xff000000;
Uint32 rmask = 0x00ff0000;
Uint32 gmask = 0x0000ff00;
Uint32 bmask = 0x000000ff;
#endif
return SDL_CreateRGBSurfaceFrom((void*)image.constBits(),
image.width(), image.height(), image.depth(), image.bytesPerLine(),
rmask, gmask, bmask, amask);
}
我绘图功能的核心:
// screen == SDL_GetVideoSurface()
// finalComposite == my QImage that SDL will convert and display
SDL_FillRect(screen, NULL, SDL_MapRGBA(screen->format, 255, 255, 255, 255));
SDL_Surface *surf = QImage_toSDLSurface(finalComposite);
SDL_BlitSurface(surf, NULL, screen, NULL);
SDL_FreeSurface(surf);
SDL_Flip(screen);