我是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;
}
这可以解决眨眼问题。但是屏幕上的文字有黑色背景,应该是空的。
有人可以告诉我这是什么问题吗?
答案 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;
}