2015-09-28 42 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++中。