2015-10-19 38 views
1

使用標準SDL2庫,我有以下Pascal代碼。所有代碼都是有效的,圖像位於正確的目錄中,非常罕見的情況下,所需的圖像將會加載。然而,在99%的時間內,它只顯示其背後的窗口內容的靜態圖片。SDL Window僅顯示其後的內容

program project1; 

{$mode objfpc}{$H+} 

uses 
    {$IFDEF UNIX}{$IFDEF UseCThreads} 
    cthreads, 
    {$ENDIF}{$ENDIF} 
    Classes, sysutils, SDL2, SDL2_image 
    { you can add units after this }; 

const 
    SWIDTH = 709; 
    SHEIGHT = 488; 
var 
    Window: PSDL_Window; 
    ScreenSurface, Symbol: PSDL_Surface; 
begin 
    WriteLn(GetCurrentDir); 
    if SDL_Init(SDL_INIT_VIDEO) < 0 then halt; 
    SDL_Init(SDL_INIT_EVERYTHING); 
    Window:= SDL_CreateWindow('Symbol Test', SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SWIDTH, SHEIGHT, SDL_WINDOW_SHOWN); 
    ScreenSurface:= SDL_GetWindowSurface(Window); 
    IMG_Init(IMG_INIT_PNG); 
    Symbol:= IMG_Load('symbol.png'); 
    SDL_BlitSurface(Symbol, nil, ScreenSurface, nil); 
    SDL_UpdateWindowSurface(Window); 
    SDL_Delay(5000); 
    SDL_FreeSurface(Symbol); 
    SDL_FreeSurface(ScreenSurface); 

    SDL_DestroyWindow(Window); 
    SDL_Quit(); 
end. 
+0

可能與vsync相關。嘗試在循環中顯示多次,直到5秒過去,或禁用加速([SDL_HINT_FRAMEBUFFER_ACCELERATION](http://wiki.libsdl.org/SDL_HINT_FRAMEBUFFER_ACCELERATION))。你也不應該釋放'ScreenSurface',但它與你的問題無關。 http://stackoverflow.com/questions/32500491/sdl-renderer-presentvsync-inconsistently-displays可能會有幫助,如果你在啓用啓用OS/WM,雖然它沒有提供明確的解決方案。 – keltar

+0

@keltar:太棒了!你是對的,這是VSync的問題。我現在修復了它,更新內部的輪詢事件循環是我必須做的。非常感謝你! – Mark

回答

0

感謝keltar在評論中指出這是一個VSync相關的錯誤。通過將更新過程從事件隊列中移出而不是在延遲之前靜態地進行一次,一切正常。以下是更新的代碼供參考:

program project1; 

{$mode tp}{$H+} 

uses 
    {$IFDEF UNIX}{$IFDEF UseCThreads} 
    cthreads, 
    {$ENDIF}{$ENDIF} 
    Classes, sysutils, SDL2, SDL2_image 
    { you can add units after this }; 

const 
    SWIDTH = 709; 
    SHEIGHT = 488; 
var 
    Window: PSDL_Window; 
    ScreenSurface, Symbol: PSDL_Surface; 
    e: TSDL_Event; 
begin 
    WriteLn(GetCurrentDir); 
    if SDL_Init(SDL_INIT_VIDEO) < 0 then halt; 
    SDL_Init(SDL_INIT_EVERYTHING); 
    Window:= SDL_CreateWindow('Symbol Test', SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SWIDTH, SHEIGHT, SDL_WINDOW_SHOWN); 
    ScreenSurface:= SDL_GetWindowSurface(Window); 
    IMG_Init(IMG_INIT_PNG); 
    Symbol:= IMG_Load('symbol.png'); 
    SDL_BlitSurface(Symbol, nil, ScreenSurface, nil); 
    while true do 
    begin 
    while SDL_PollEvent(@e) <> 0 do 
    begin 
     if e.type_ = SDL_KEYDOWN then WriteLn(e.key.keysym.scancode); 
     SDL_UpdateWindowSurface(Window); 
    end; 
    end; 

    SDL_DestroyWindow(Window); 
    SDL_Quit(); 
end.