SDL_RenderPresent实现

问题描述

SDL Wiki提到SDL_RenderPresent()

SDL的呈现功能在后缓冲区上运行;也就是说,调用诸如SDL_RenderDrawLine()之类的渲染函数不会直接在屏幕上放置一行,而是会更新后备缓冲区。这样,您就组成了整个场景,并将组成的后缓冲区作为完整图片呈现给屏幕。因此,当使用SDL的渲染API时,会完成所有针对该框架的绘图,然后每帧调用一次此功能以将最终的绘图呈现给用户每次出现后都应将后缓冲视为无效;不要假设先前的内容将在帧之间存在。强烈建议您在开始每个新帧的绘制之前调用SDL_RenderClear()初始化后缓冲区,即使您打算覆盖每个像素也是如此。

为什么后缓冲区无效?我想通过仅重绘需要要重绘的渲染目标部分来优化渲染性能。如果后缓冲区无效,该怎么办? Win32 API允许重绘渲染目标的某些部分。为什么不使用SDL?

解决方法

当您调用present时,SDL发送要显示的后缓冲区并将其交换出去,因此新的后缓冲区是垃圾,您必须再次重绘它,出于性能方面的考虑。

如果您不修改整个屏幕,我想您可以做的是尝试通过使用自己的后缓冲来最大程度地减少绘图调用,然后按照以下方式进行呈现:

// we'll use this texture as our own backbuffer
SDL_Texture *buffer = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB888,SDL_TEXTUREACCESS_TARGET,w,h); 
SDL_SetRenderTarget(renderer,buffer); // all the draw calls go to buffer instead of the sdl backbuffer
SDL_RenderCopy(renderer,some_texture,src_rect,dst_rect); // for example this would draw to buffer
SDL_SetRenderTarget(renderer,NULL); // we set the renderer back so we can draw to the SDL backbuffer
SDL_RenderCopy(renderer,buffer,dst_rect); // copy our own backbuffer in one call
SDL_RenderPresent(renderer); 

通过此操作,您可以最小化绘图调用,因为您将更新自己的后缓冲区,然后呈现该缓冲区,而不是每次都重新绘制整个屏幕。