sdl_filillrect():不支持曲面格式或分割错误

SDL_FiillRect(): Unsupported surface format or Segmentation fault

本文关键字:格式 曲面 分割 错误 不支持 filillrect sdl      更新时间:2023-10-16

我有一个小的SDL2程序来创建一个白色窗口。效果很好。但是,当我尝试用函数SDL_CreateRenderer()创建SDL_Renderer时,函数SDL_FillRect()突然失败,出现以下错误:SDL_FillRect():不支持的表面格式。有时,该函数不返回错误,但会产生分割错误!!

下面是我的初始化函数的代码,它是我的程序的第一个函数:

SDL_Surface     *screenSurface  = NULL;
SDL_Window      *window         = NULL;
SDL_Renderer    *renderer       = NULL; 
bool initialize() {
  if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS) < 0) {
    cout << "SDL could not initialize: " << SDL_GetError() << endl;
    return false;                                                               
  }                                                                             
  window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS);
  if (window == NULL) {                                                         
    cout << "Window error: " << SDL_GetError() << endl;
   return false;                                                               
  }
  if ((screenSurface = SDL_GetWindowSurface(window)) == NULL) {
    cout << "GetWindowSurface() error: << endl;
    return false;
  }
  /*
  ** here, I create my SDL_Renderer. The function returns non NULL
  ** However, if the code is present, SDL_FilRect() fails
  ** if the code is not preset, SDL_FillRect works.
  */ 
  if ((renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED)) == NULL) {
    cout << "Renderer error: " << SDL_GetError() << endl;
    return false;                                                               
  }
  /*
  ** Here, SDL_FillRect sometimes works depending on SDL_CreateRenderer
  ** getUint32Color() is only a custom function that map an enum with Uint32 values
  */
  if (SDL_FillRect(screenSurface, NULL, getUint32Color(WHITE)) < 0) {           
    cout << "SDL_FillRect error: " << SDL_GetError() << endl;
   return false;
  }
  return true;                                                                  
}

你知道吗?

您应该避免使用SDL_GetWindowSurface(),因为表面可能会失效。

相反,如果你绝对想要缓慢的"软件"渲染:

surface = SDL_CreateRGBSurface(0, W, H, 32, 0x00FF, 0x0000FF, 0x000000FF, 0xFF);
SDL_Texture *texture = SDL_CreateTexture(rendered, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, W, H);
void update_screen() {
    SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
    SDL_RenderClear(renderer);
    SDL_RenderCopy(renderer, texture, NULL, &dest); // src texture, dest
    SDL_RenderPresent(renderer);
}

但正如@Ivan所说,使用2D加速渲染功能要快得多。你应该使用SDL_RenderFillRect()来代替SDL_FillRect()。

您正在使用窗口的表面,并尝试在同一窗口上使用渲染器。这是不允许的。来自SDL_GetWindowSurface的文档:

您不能将此与3D或此窗口上的渲染API结合使用。

我猜,创建渲染器会立即使表面中的某些内容无效。