我需要对每一个帧进行截图,我需要非常高的性能(我正在使用freeGlut)。我想出来的是在glutIdleFunc(thisCallbackFunction)里面可以这样做
GLubyte *data = (GLubyte *)malloc(3 * m_screenWidth * m_screenHeight);
glReadPixels(0, 0, m_screenWidth, m_screenHeight, GL_RGB, GL_UNSIGNED_BYTE, data);
// and I can access pixel values like this: data[3*(x*512 + y) + color] or whatever它确实有效,但我有一个很大的问题,它真的很慢。当我的窗口是512x512时,当只呈现多维数据集时,它的运行速度不会超过每秒90帧,如果没有这两行,它将以6500 FPS运行!如果我们将它与irrlicht图形引擎进行比较,我就可以做到这一点。
// irrlicht code
video::IImage *screenShot = driver->createScreenShot();
const uint8_t *data = (uint8_t*)screenShot->lock();
// I can access pixel values from data in a similar manner here和512x512窗口运行在400 FPS,即使一个巨大的网格(地震3地图)加载!考虑到我正在使用openGL作为irrlicht内部的驱动程序。在我缺乏经验的人看来,glReadPixels似乎在将每个像素数据从一个地方复制到另一个地方,而(uint8_t*)screenShot->lock()只是在复制指向已经存在的数组的指针。我可以使用freeGlut做类似于后者的事情吗?我希望它比irrlicht快。
请注意,irrlicht也使用openGL (嗯,它还提供了directX和其他选项,但在我前面给出的示例中,我使用了openGL,顺便说一下,与其他选项相比,它是最快的)
发布于 2016-10-02 21:43:00
OpenGL方法用于管理呈现管道。在本质上,当显卡向观众显示图像时,下一帧的计算正在进行。当您调用glReadPixels;图形卡等待当前帧完成时,读取像素,然后开始计算下一个帧。因此,管道会陷入停滞,变成连续的。
如果您可以持有两个缓冲区,并告诉显卡将数据读入这些缓冲区中,以交换每个帧;那么您可以延迟从缓冲区1帧读取数据,但不会阻塞管道。这叫做双重缓冲。你也可以做三重缓冲与2帧,迟读,等等。
这里有一个比较老的网页描述了这种现象和实现:pbo.html。
此外,还有很多关于框架缓冲区和渲染成网络纹理的教程。其中一个在这里:http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/
https://stackoverflow.com/questions/39821850
复制相似问题