2015-09-28 51 views
1

过去几个月,我一直在夜间和周末在SDL上开展一个项目。我目前正试图让菜单系统正常工作。目前,我正在使用SDL_TTF来绘制文本。至于我的问题,当我尝试绘制一些纹理到另一个纹理时,我看到一些奇怪的行为。为什么我无法在SDL2中绘制纹理?

奇怪的是,当我绘制它时,使用SDL_TEXTUREACCESS_TARGET(就像它在文档中所做的那样)创建的目标纹理不绘制任何东西,但不返回任何错误。但是,如果我使用SDL_TEXTUREACCESS_STATICSDL_TEXTUREACCESS_STREAM,由于访问属性而设置呈现目标时,它会返回错误,但绘制得很好。在做了一些挖掘之后,我听到了一些关于英特尔驱动程序中的错误的信息(我在使用英特尔图形处理器的Macbook上),所以我想知道这是不是我搞砸了,以及如何修复它。或者,如果这不是我的错,我仍然想知道发生了什么,以及它是否会在不同平台上执行不同的操作,以及我如何解决它。

这里是我的代码,去除不必要的部分后:后来

renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); 

,当我去渲染到画布上:

创建渲染

TTF_Font *fnt = loadFont(fontName.c_str(), fontSize); 

在这里我解析出一些属性,并使用TTF_SetFontStyle()和clr设置文本颜色。

SDL_Texture *canvas; 
canvas = SDL_CreateTexture(rendy, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, contentRect.w, contentRect.h) 
SDL_SetRenderTarget(rendy, canvas); 

int pos = 0; 
for (list<string>::iterator itr = lines.begin(); itr != lines.end(); itr++){ 
    SDL_Surface *temp; 
    temp = TTF_RenderText_Blended(fnt, src.c_str(), clr); 

    SDL_Texture *line; 
    line = SDL_CreateTextureFromSurface(rendy, temp); 
    int w,h; 
    SDL_QueryTexture(line, NULL, NULL, &w, &h); 

    SDL_Rect destR; 

    //Assume that we're left justified 
    destR.x = 0; 
    destR.y = pos; 
    destR.w = w; 
    destR.h = h; 

    SDL_RenderCopy(rendy, line, NULL, &destR); 
    SDL_DestroyTexture(line); 
    SDL_FreeSurface(temp); 
    pos += TTF_FontLineSkip(fnt); 
} 

//Clean up 
SDL_SetRenderTarget(rendy, NULL); 

canvas返回到调用函数,所以它可以被缓存,直到这个文本框被修改。该功能通过为整个盒子提供纹理,在其上绘制背景纹理,然后在该顶部绘制该图像并保留整个事物而起作用。

该代码看起来是这样的:

(东西绘制背景,这使得罚款)

SDL_Texture *sum = SDL_CreateTexture(rendy, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, globalRect.w, globalRect.h); 

SDL_SetTextureBlendMode(sum, SDL_BLENDMODE_BLEND); 
SDL_SetRenderTarget(rendy, sum); 

string lPad = getAttribute(EL_LEFT_PADDING); 
string tPad = getAttribute(EL_TOP_PADDING); 
int paddingL = strtol(lPad.c_str(), NULL, 10); 
int paddingT = strtol(tPad.c_str(), NULL, 10); 

SDL_Rect destR; 
SDL_Rect srcR; 
srcR.x = 0; 
srcR.y = 0; 
srcR.w = globalRect.w; //globalRect is the size size of the whole button 
srcR.h = globalRect.h; 
destR.x = 0; 
destR.y = 0; 
destR.w = globalRect.w; 
destR.h = globalRect.h; 

SDL_RenderCopy(rendy, bgTexture, NULL, &destR); 
int maxX = contentRect.w; 
fgTexture = getFGImage(rendy); //The call to the previous part 

int w, h; 
SDL_QueryTexture(fgTexture, NULL, NULL, &w, &h); 

int width, height; 
getTextSize(&width, &height, maxX); 

srcR.x = 0; 
srcR.y = 0; 
srcR.w = width; 
srcR.h = height; 
destR.x = paddingL; 
destR.y = paddingT; 
destR.w = globalRect.w; 
destR.h = globalRect.h; 

SDL_RenderCopy(rendy, fgTexture, NULL, &destR); 
SDL_DestroyTexture(fgTexture); 
SDL_DestroyTexture(bgTexture); 


return sum; 

总和返回到另一个函数做绘图。

在此先感谢!

更新 所以,我已经想通了,只当我有不正确的访问设置吸引的原因是,由于函数返回错误值,渲染目标从未设为纹理,所以它只是画在屏幕上。我还通过编写一个函数AuditTexture来检查我的所有纹理,函数AuditTexture检查渲染器是否支持纹理的纹理格式,打印访问属性的字符串描述并打印尺寸。我现在知道它们的所有纹理格式都被支持,两行是静态的,canvas和sum是渲染目标,并且它们都没有尺寸为零。

+0

'if((line = SDL_CreateTextureFromSurface(rendy,temp)':缺少一些括号 –

回答

1

事实证明,我已经将渲染目标设置为复合材质纹理,然后调用我的函数,在绘制文本之前将渲染目标设置为文本纹理。然后当我从函数返回时,渲染目标仍然是文本纹理而不是复合文本纹理,所以我基本上将文本绘制在自身上,而不是绘制在背景上。

聪明人的一句话:永远不要假设某些事情已经为你照顾,特别是在c或C++中。