【发布时间】:2016-10-02 21:23:45
【问题描述】:
我需要在每一帧拍摄截图,并且我需要非常高的性能(我正在使用 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
即使加载了巨大的网格(Quake 3 地图),512x512 窗口也能以 400 FPS 的速度运行!考虑到我在 irrlicht 中使用 openGL 作为驱动程序。在我没有经验的眼中,glReadPixels 似乎将每个像素数据从一个地方复制到另一个地方,而(uint8_t*)screenShot->lock() 只是复制一个指向已经存在的数组的指针。我可以使用 freeGlut 做类似于后者的事情吗?我希望它比 irrlicht 更快。
请注意,irrlicht 也使用 openGL(它也提供了 directX 和其他选项,但在我上面给出的示例中,我使用了 openGL,顺便说一下,与其他选项相比,它是最快的)
【问题讨论】:
-
查找像素缓冲区对象,让您异步执行。
-
如果您将该代码放在空闲函数中,它可能每帧调用不止一次。此外,如果你从不释放你分配的数据,你就会泄漏内存。
-
@RetoKoradi 好吧,不,我不会在每次调用
idle时都执行这些行。data在构造函数中只分配一次,我一遍又一遍地使用它。现在我正在研究 PBO....
标签: c++ performance opengl screenshot freeglut