SDL窗口仅渲染其后面的内容

时间:2015-10-19 06:29:39

标签: opengl sdl-2 freepascal lazarus

我使用标准SDL2库有以下Pascal代码。所有代码都有效,图像位于正确的目录中,并且在极少数情况下将加载所需的图像。然而,在99%的时间里,它只显示了窗口内容的静态图片。

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.

1 个答案:

答案 0 :(得分: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.