SDL2纹理的意义是什么
What is the point of an SDL2 Texture?
我有点拘泥于SDL2纹理背后的逻辑。对我来说,它们是毫无意义的,因为你无法吸引它们。
在我的程序中,我有几个曲面(或者在我切换到SDL2之前是的曲面),我只是将它们闪电式地组合在一起以形成层。现在看来,我必须创建几个渲染器和纹理来创建相同的效果,因为SDL_RenderCopy
需要一个纹理指针。
不仅如此,所有渲染器都必须来自一个窗口,我理解这一点,但仍然会让我更加困惑。
这一切看起来都非常庞大和缓慢。我是不是错过了什么?有没有一种方法可以直接绘制到纹理?纹理的意义是什么?用多个(如果不是数百个的话)渲染器代替表面是否安全?
SDL_Texture
对象存储在尽可能靠近视频卡内存的位置,因此可以通过GPU轻松加速。调整大小、alpha混合、抗锯齿以及几乎任何计算量大的操作都可能受到此性能提升的严重影响。如果您的程序需要在纹理上运行每像素逻辑,我们鼓励您暂时将纹理转换为曲面。使用流式纹理也可以实现一种变通方法。
编辑:既然这个答案很受关注,我想详细谈谈我的建议。
如果您更喜欢使用Texture -> Surface -> Texture
工作流来应用每像素操作,请确保缓存最终纹理,除非您需要在每个渲染周期重新计算它。此解决方案中的纹理是使用SDL_TEXTUREACCESS_STATIC
标志创建的。
对于像素数据的来源是网络、设备、帧服务器或SDL应用程序无法完全访问的其他来源的用例,以及从来源缓存帧显然效率低下或无法工作的用例,鼓励使用流式纹理(创建标志为SDL_TEXTUREACCESS_STREAMING
)。
如果使用SDL_TEXTUREACCESS_TARGET
标志创建纹理,则可以在纹理之上进行渲染。这将绘制操作的来源限制为其他纹理,尽管这可能已经是您最初需要的了。"纹理作为渲染目标"是SDL2的最新功能之一,也是最不受广泛支持的功能之一。
好奇读者的Nerd信息:
由于SDL实现的性质,前两种方法取决于应用程序级的读取和复制操作,尽管它们针对建议的场景进行了优化,并且对于实时应用程序来说足够快。
与GPU上的后处理相比,从应用程序级别复制数据几乎总是很慢。如果您的要求比SDL所能提供的要求更严格,并且您的逻辑不依赖于某些外部像素数据源,则明智的做法是分配从SDL曲面绘制的原始OpenGL纹理,并对其应用着色器(GPU逻辑)。
着色器是用GLSL编写的,GLSL是一种编译成GPU程序集的语言硬件/GPU加速实际上是指在GPU内核上并行化的代码,使用着色器是实现渲染目的的首选方式。
注意!将原始OpenGL纹理和着色器与SDL渲染函数和结构结合使用可能会导致一些意外的冲突或失去库提供的灵活性
TLDR 它比曲面更快地渲染和操作纹理,尽管修改纹理有时会很麻烦。
通过将SDL2纹理创建为STREAMING类型,可以锁定和解锁整个纹理或仅一个像素区域,以执行直接的像素操作。必须先创建SDL2 Surface,并按如下方式链接锁定解锁:
SDL_Surface surface = SDL_CreateSurface(..);
SDL_LockTexture(texture, &rect, &surface->pixels, &surface->pitch);
// paint into surface pixels
SDL_UnlockTexture(texture);
关键是,如果绘制到较大尺寸的纹理,并且绘制是增量的(例如实时数据图),请确保只锁定和解锁要更新的实际区域。否则操作会很慢,复制内存会很重。
我已经体验到了合理的性能,使用模型也不太难理解。
在SDL2中,可以在屏幕外渲染/直接渲染到纹理。要使用的功能是:
int SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture);
仅当渲染器启用SDL_renderer_TARGETTEXTURE时,此选项才有效。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "using namespace std;"在C++的作用是什么?
- 是什么导致 glTexSubImage1D() - 加载纹理时在此示例中出现GL_INVALID_VALUE错误?
- 在版本 440 核心中绘制具有纹理的立方体的顶点和片段着色器应该是什么
- cocos2d-x每次我需要精灵或只是改变它的纹理时,制作精灵的最佳做法是什么
- 将QImage绑定到纹理以在QOpenGLWidget中显示视频的正确方法是什么
- SDL2纹理的意义是什么
- OpenGL纹理ID的范围是什么?