Libgdx: 渲染方法
Libgdx: the render method
我不明白 render 方法是如何工作的。
根据我在网上阅读/在 youtube 教程上看到的内容,我了解到 render 方法是一个循环函数,您可以使用它来保持游戏更新和读取用户的输入。当您想在屏幕上绘制某些内容时,您可以使用此方法进行操作,并在绘制任何内容之前清除屏幕。
但是如果我想画一些静止的东西,在渲染方法之外绘制它不是更好吗(这样计算机就不必多次清屏重绘)?
我错过了什么?
您不能在 render 方法之外进行绘制,因为它是在 OpenGL 线程上调用的方法。您无法从其他线程绘制到 OpenGL。
如果您的整个屏幕经常静止超过几毫秒(纸牌游戏等游戏可能就是这种情况),您可以使用 Gdx.graphics.setContinuousRendering(false)
禁用屏幕的持续刷新。这将节省能源,因为 GPU 和 CPU 将不必那么努力地工作。 See here 获取使用说明。
至于为什么通常不这样做:
将“帧缓冲区”想象成内存中的位图图像,可以绘制到屏幕上然后显示在屏幕上。大多数移动渲染都是通过双缓冲完成的。这意味着当一个缓冲区被绘制到(后台缓冲区)时,在前一帧绘制到的前台缓冲区将直接渲染到屏幕上。它们每帧来回交换以加快渲染速度。
图形的工作方式是绘制的每个项目都会修改绘制项目的帧缓冲区中像素的颜色。项目可能被遮盖或半透明,这些将改变其背后像素的颜色。一旦在前面绘制并修改它们,这些像素的原始颜色就会丢失
因此,即使屏幕上的某些项目是静态的,如果屏幕上有其他项目移动或改变颜色,并且它们与静态项目重叠(在 或 behind), 你仍然需要在每次有任何变化时重新绘制整个屏幕。
如果屏幕的一个区域是静态的并且从不与动态对象重叠,并且动态对象完全包含在一个矩形内,您可以设置一个视口,将绘图限制在动态区域并避免清除整个屏幕.但是,GPU 专门设计用于高效清除整个屏幕。因为双缓冲,如果你不清除整个屏幕,实际上可能会损害性能,因为如果你不清除它,屏幕的内容必须在前缓冲区和后缓冲区之间复制,然后才能开始绘制下一帧。
另一种策略是,如果您有一个非常复杂且需要 GPU 绘制的静态对象,因为它有很多层或复杂的着色器,您可以将它绘制到屏幕外帧缓冲区对象(FrameBuffer class in libGDX) 一次,然后像精灵一样在每一帧上将 FrameBuffer 的纹理渲染到屏幕上。
我不明白 render 方法是如何工作的。
根据我在网上阅读/在 youtube 教程上看到的内容,我了解到 render 方法是一个循环函数,您可以使用它来保持游戏更新和读取用户的输入。当您想在屏幕上绘制某些内容时,您可以使用此方法进行操作,并在绘制任何内容之前清除屏幕。
但是如果我想画一些静止的东西,在渲染方法之外绘制它不是更好吗(这样计算机就不必多次清屏重绘)?
我错过了什么?
您不能在 render 方法之外进行绘制,因为它是在 OpenGL 线程上调用的方法。您无法从其他线程绘制到 OpenGL。
如果您的整个屏幕经常静止超过几毫秒(纸牌游戏等游戏可能就是这种情况),您可以使用 Gdx.graphics.setContinuousRendering(false)
禁用屏幕的持续刷新。这将节省能源,因为 GPU 和 CPU 将不必那么努力地工作。 See here 获取使用说明。
至于为什么通常不这样做:
将“帧缓冲区”想象成内存中的位图图像,可以绘制到屏幕上然后显示在屏幕上。大多数移动渲染都是通过双缓冲完成的。这意味着当一个缓冲区被绘制到(后台缓冲区)时,在前一帧绘制到的前台缓冲区将直接渲染到屏幕上。它们每帧来回交换以加快渲染速度。
图形的工作方式是绘制的每个项目都会修改绘制项目的帧缓冲区中像素的颜色。项目可能被遮盖或半透明,这些将改变其背后像素的颜色。一旦在前面绘制并修改它们,这些像素的原始颜色就会丢失
因此,即使屏幕上的某些项目是静态的,如果屏幕上有其他项目移动或改变颜色,并且它们与静态项目重叠(在 或 behind), 你仍然需要在每次有任何变化时重新绘制整个屏幕。
如果屏幕的一个区域是静态的并且从不与动态对象重叠,并且动态对象完全包含在一个矩形内,您可以设置一个视口,将绘图限制在动态区域并避免清除整个屏幕.但是,GPU 专门设计用于高效清除整个屏幕。因为双缓冲,如果你不清除整个屏幕,实际上可能会损害性能,因为如果你不清除它,屏幕的内容必须在前缓冲区和后缓冲区之间复制,然后才能开始绘制下一帧。
另一种策略是,如果您有一个非常复杂且需要 GPU 绘制的静态对象,因为它有很多层或复杂的着色器,您可以将它绘制到屏幕外帧缓冲区对象(FrameBuffer class in libGDX) 一次,然后像精灵一样在每一帧上将 FrameBuffer 的纹理渲染到屏幕上。