如何在SDL_Overlay上blit文本表面?

时间:2013-05-21 02:37:25

标签: sdl

我是sdl的新手。这是我的问题:我使用sdl_ttf.dll创建文本表面。 像这样     TTF_Font* myFont = TTF_OpenFont(szFontPath, text.m_iFontSize);     SDL_Surface *textSurface = TTF_RenderUNICODE_Blended(myFont, (const     Uint16*)text.m_wstrFilePath.c_str(), textColor);

这很好用,如果我在用于播放视频的屏幕上进行blit,则texturface是可以的。     SDL_BlitSurface(textSurface , null, screen, offset); 但问题是屏幕上的文字每隔3/4秒就会闪烁,即使我设置了 屏幕与SDL_DOUBLEBUF和SDL_HWSURFACE,它将无济于事。所以它走了另一条路。我决定在显示之前在屏幕上显示文本。我使用这个功能:

blitSurface2YUV(text, vp->bmp, &rectOffset); // vp-> bmp是sdl_overlay 显示它:SDL_DisplayYUVOverlay(vp-> bmp,& rcRView); // rcView是屏幕的偏移量

“blitSurface2YUV”在这里定义:

   int blitSurface2YUV(SDL_Surface *src, SDL_Overlay *dst, SDL_Rect *dstrect)
   {
  Uint8 r, g, b;
  int y1,u1,v1;
  int y,x;
  int height = src->h < dstrect->h ? src->h: dstrect->h;
  int width =  src->w < dstrect->w ? src->w: dstrect->w;
  int uv_off = 0;
  Uint32 pixel;

  if(dst->format != SDL_YV12_OVERLAY)
    return 1;

  for(y = 0; y < height; ++y)
  {
    for(x = 0; x < width; ++x)
    {
        switch(src->format->BitsPerPixel)
        {
        case 8:
            pixel = *((Uint8*)src->pixels + y*src->pitch + x);
            break;
        case 16:
            pixel = *((Uint16*)src->pixels + y*src->pitch/2 + x);
            break;
        case 32:
            pixel = *((Uint32*)src->pixels + y*src->pitch/4 + x);
            break;
        default:
            return -1;
        }
        SDL_GetRGB(pixel, src->format, &r, &g, &b);
        rgb2yuv(r, g, b, &y1, &u1, &v1);

        memset(dst->pixels[0] + (dstrect->y + y) * dst->pitches[0] + (dstrect->x + x), 
            (Uint8)y1, 1);

        if((x%2 == 0 ) && (y%2 == 0 ))
        {
            memset(dst->pixels[1] + (uv_off + dstrect->y /2) * dst->pitches[1] + (dstrect->x/2 + x/2), 
                (Uint8)v1, 1);
            memset(dst->pixels[2] + (uv_off + dstrect->y /2) * dst->pitches[2] + (dstrect->x/2 + x/2), 
                (Uint8)u1, 1);
        }
    }
    if(y%2 == 0)++uv_off;
}
return 0;
}

这可以解决眨眼问题。但是屏幕上的文字有黑色背景,应该是空的。

有人可以告诉我这是什么问题吗?

2 个答案:

答案 0 :(得分:0)

这不是一个真正的答案,但对于评论来说肯定太长了。

我认为你正试图解决错误的问题。您最初的问题是,在屏幕表面上调用TTF_RenderUNICODE_Blended时,使用SDL_BlitSurface生成的文字会以一定间隔“闪烁”。这是假设可以工作,并且已经在我的所有SDL项目中工作。

这意味着渲染循环或文本都有问题,如果您可以发布更多关于此的代码,那将会有所帮助!

答案 1 :(得分:0)

您可以将其添加到循环中。并且黑色像素不会处理。

if(pixel == 0 )
    continue;

这是更正的功能。

int blitSurface2YUV(SDL_Surface *src, SDL_Overlay *dst, SDL_Rect *dstrect)
{
Uint8 r, g, b;
int y1,u1,v1;
int y,x;
int height = src->h < dstrect->h ? src->h: dstrect->h;
int width =  src->w < dstrect->w ? src->w: dstrect->w;
int uv_off = 0;
Uint32 pixel;

if(dst->format != SDL_YV12_OVERLAY)
    return 1;

for(y = 0; y < height; ++y)
{
    for(x = 0; x < width; ++x)
    {
        switch(src->format->BitsPerPixel)
        {
        case 8:
            pixel = *((Uint8*)src->pixels + y*src->pitch + x);
        break;
        case 16:
            pixel = *((Uint16*)src->pixels + y*src->pitch/2 + x);
        break;
        case 32:
            pixel = *((Uint32*)src->pixels + y*src->pitch/4 + x);
        break;
            default:
            return -1;
        }
        if(pixel == 0 )
            continue;
        SDL_GetRGB(pixel, src->format, &r, &g, &b);
        rgb2yuv(r, g, b, y1, u1, v1);

        memset(dst->pixels[0] + (dstrect->y + y) * dst->pitches[0] + (dstrect->x + x), 
            (Uint8)y1, 1);

        if((x%2 == 0 ) && (y%2 == 0 ))
        {
        memset(dst->pixels[1] + (uv_off + dstrect->y /2) * dst->pitches[1] + (dstrect->x/2 + x/2), 
            (Uint8)v1, 1);
        memset(dst->pixels[2] + (uv_off + dstrect->y /2) * dst->pitches[2] + (dstrect->x/2 + x/2), 
            (Uint8)u1, 1);
        }
    }
    if(y%2 == 0) ++uv_off;
}
return 0;
}