简体   繁体   English

SDL2纹理有什么意义?

[英]What is the point of an SDL2 Texture?

I'm kind of stuck on the logic behind an SDL2 texture. 我有点坚持SDL2纹理背后的逻辑。 To me, they are pointless since you cannot draw to them. 对我来说,它们毫无意义,因为你无法吸引他们。

In my program, I have several surfaces (or what were surfaces before I switched to SDL2) that I just blitted together to form layers. 在我的计划,我有几个面(或哪些表面之前,我切换到SDL2),我只是图混合在一起,形成层。 Now, it seems, I have to create several renderers and textures to create the same effect since SDL_RenderCopy takes a texture pointer. 现在,似乎我必须创建几个渲染器和纹理来创建相同的效果,因为SDL_RenderCopy采用纹理指针。

Not only that, but all renderers have to come from a window, which I understand, but still fouls me up a bit more. 不仅如此, 所有渲染器都必须来自一个窗口,我明白这一点,但仍然会让我更加严重。

This all seems extremely bulky and slow. 这一切看起来都非常庞大和缓慢。 Am I missing something? 我错过了什么吗? Is there a way to draw directly to a texture? 有没有办法直接绘制纹理? What are the point of textures, and am I safe to have multiple (if not hundreds) of renderers in place of what were surfaces? 纹理有什么意义,我可以安全地使用多个(如果不是数百个)渲染器来代替表面吗?

SDL_Texture objects are stored as close as possible to video card memory and therefore can easily be accelerated by your GPU. SDL_Texture对象尽可能靠近视频卡内存存储,因此可以通过GPU轻松加速。 Resizing, alpha blending, anti-aliasing and almost any compute-heavy operation can harshly be affected by this performance boost. 调整大小,alpha混合,消除锯齿以及几乎任何计算繁重的操作都会受到这种性能提升的严重影响。 If your program needs to run a per-pixel logic on your textures, you are encouraged to convert your textures into surfaces temporarily. 如果您的程序需要在纹理上运行逐像素逻辑,则建议您暂时将纹理转换为曲面。 Achieving a workaround with streaming textures is also possible. 也可以使用流纹理实现变通方法。

Edit : Since this answer recieves quite the attention, I'd like to elaborate my suggestion. 编辑 :由于这个答案得到了很多关注,我想详细说明我的建议。

If you prefer to use Texture -> Surface -> Texture workflow to apply your per-pixel operation, make sure you cache your final texture unless you need to recalculate it on every render cycle. 如果您更喜欢使用Texture -> Surface -> Texture工作流来应用每像素操作,请确保缓存最终纹理,除非您需要在每个渲染周期重新计算它。 Textures in this solution are created with SDL_TEXTUREACCESS_STATIC flag. 使用SDL_TEXTUREACCESS_STATIC标志创建此解决方案中的纹理。

Streaming textures (creation flag is SDL_TEXTUREACCESS_STREAMING ) are encouraged for use cases where source of the pixel data is network, a device, a frameserver or some other source that is beyond SDL applications' full reach and when it is apparent that caching frames from source is inefficient or would not work. 对于像素数据的来源是网络,设备,帧服务器或超出SDL应用程序的完全覆盖范围以及显而易见的来自源的缓存帧的用例,鼓励使用流纹理(创建标志为SDL_TEXTUREACCESS_STREAMING )效率低下或不起作用。

It is possible to render on top of textures if they are created with SDL_TEXTUREACCESS_TARGET flag. 如果使用SDL_TEXTUREACCESS_TARGET标志创建纹理,则可以在纹理顶部进行渲染。 This limits the source of the draw operation to other textures although this might already be what you required in the first place. 这将绘制操作的来源限制为其他纹理,尽管这可能已经是您首先需要的。 "Textures as render targets" is one of the newest and least widely supported feature of SDL2. “纹理作为渲染目标”是SDL2最新和最不受支持的功能之一。

Nerd info for curious readers: 好奇的读者的书呆子信息:

Due to the nature of SDL implementation, the first two methods depend on application level read and copy operations, though they are optimized for suggested scenarios and fast enough for realtime applications. 由于SDL实现的性质,前两种方法依赖于应用程序级别的读取和复制操作,尽管它们针对建议的方案进行了优化,并且对于实时应用程序来说足够快。

Copying data from application level is almost always slow when compared to post-processing on GPU. 与GPU上的后处理相比,从应用程序级复制数据几乎总是很慢。 If your requirements are more strict than what SDL can provide and your logic does not depend on some outer pixel data source, it would be sensible to allocate raw OpenGL textures painted from you SDL surfaces and apply shaders (GPU logic) to them. 如果您的要求比SDL提供的要求更严格且您的逻辑不依赖于某些外部像素数据源,那么分配从您的SDL表面绘制的原始OpenGL纹理并将着色器 (GPU逻辑)应用于它们将是明智的。

Shaders are written in GLSL, a language which compiles into GPU assembly. 着色器是用GLSL编写的,这是一种编译成GPU组件的语言。 Hardware/GPU Acceleration actually refers to code parallelized on GPU cores and using shaders is the prefered way to achieve that for rendering purposes. 硬件/ GPU加速实际上是指在GPU核心上并行化的代码,并且使用着色器是实现渲染目的的首选方法。

Attention! 注意! Using raw OpenGL textures and shaders in conjunction with SDL rendering functions and structures might cause some unexpected conflicts or loss of flexibility provided by the library. 将原始OpenGL纹理和着色器与SDL渲染函数和结构结合使用可能会导致库提供一些意外冲突或失去灵活性。

TLDR; TLDR; It is faster to render and operate on textures than surfaces although modifying them can sometimes be cumborsome. 渲染和操作纹理比表面更快,尽管修改它们有时会很麻烦。

Through creating a SDL2 Texture as a STREAMING type, one can lock and unlock the entire texture or just an area of pixels to perform direct pixel operations. 通过将SDL2纹理创建为STREAMING类型,可以锁定和解锁整个纹理或仅锁定像素区域以执行直接像素操作。 One must create prior a SDL2 Surface, and link with lock-unlock as follows: 必须先创建一个SDL2 Surface,并使用lock-unlock进行链接,如下所示:

SDL_Surface surface = SDL_CreateSurface(..);
SDL_LockTexture(texture, &rect, &surface->pixels, &surface->pitch);
// paint into surface pixels
SDL_UnlockTexture(texture);

The key is, if you draw to texture of larger size, and the drawing is incremental ( eg data graph in real time ) be sure to only lock and unlock the actual area to update. 关键是,如果你绘制到更大尺寸的纹理,并且绘图是增量的(例如实时数据图),请务必仅锁定和解锁要更新的实际区域。 Otherwise the operations will be slow, with heavy memory copying. 否则操作将很慢,大量内存复制。

I have experienced reasonable performance and the usage model is not too difficult to understand. 我经历了合理的表现,使用模式也不难理解。

In SDL2 it is possible to render off-screen / render directly to a texture. 在SDL2中,可以直接渲染屏幕/渲染到纹理。 The function to use is: 使用的功能是:

int SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture);

This only works if the renderer enables SDL_RENDERER_TARGETTEXTURE. 这仅在渲染器启用SDL_RENDERER_TARGETTEXTURE时有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM