我渲染的所有东西都应该有两种不同的分辨率:一种是动态的,根据用户的窗口设置,一次是通过网络流式传输的。
现在我们使用双PBO方法在渲染循环结束时有效地从GPU读取像素。一旦我们得到像素,我们将它们加载到纹理中,缩放它并再次读回像素。
但也许可以告诉OpenGL在同一渲染循环中以2种不同的分辨率渲染图片?
答案 0 :(得分:1)
现在我们使用双PBO方法在渲染循环结束时有效地从GPU读取像素。一旦我们得到像素,我们将它们加载到纹理中,缩放它并再次读回像素。
最糟糕的情况:您通过外围总线的瓶颈将像素数据推送两次。使用PBO,您可以使用glCopyBufferSubData
从GL_PIXEL_PACK_BUFFER转移到GL_PIXEL_UNPACK_BUFFER,然后从那里转换为纹理。但这不是很优雅,也为优化留出了空间。
所以这就是你应该做的事情:使用FBO渲染成一个足够大的纹理,以满足屏幕显示分辨率和存储的流宽高比。假设您的屏幕显示为1920×500,但您的流是1280×720,那么您将创建一个1920×1080纹理,将其附加到FBO并渲染到该。然后在屏幕上显示图片,渲染纹理,顶部和底部以1:1的方式裁剪到主帧缓冲区。
对于流渲染到连接到FBO的1280×720渲染缓冲区。但是要小心,你必须缩小规模并生成mipmap是相当慢的(glGenerateMipmaps的质量也是恕我直言,在许多实现中并不是最好的)。因此,您应该实现适当的下采样片段着色器。你几乎不会超过8倍。所以你的下采样内核会相当简单;基于傅里叶变换的下采样也会起作用。使用它渲染到所述渲染缓冲区并使用glReadPixels(可能通过PBO)回读图像以进行流式传输。要从glReadPixels中获得最佳性能,必须指定一个回读格式,该格式与读取的缓冲区的内部格式完全匹配。屏幕缓冲区系统很棘手,但自定义渲染缓冲区很简单。
但也许可以告诉OpenGL在同一渲染循环中以2种不同的分辨率渲染图片?
不,不是真的。虽然最近的OpenGL确实支持多个视口,但是一个基元总是被光栅化到一个视口。视口决定了从NDC空间到像素空间的映射,因此它们与结果图像分辨率紧密耦合。
这样做绝对没有任何好处。如果可能的话,这意味着每个片段操作必须完成两次。这将是浪费时间。以更高的分辨率渲染然后对结果进行缩减采样要容易得多。