我想从一个已经在OpenGL中渲染的GLUT窗口中屏幕抓取图像。在显示回调的一侧,我插入了以下代码:
display() {
drawTriangle(); //Renders the image
if(shouldDisplay) {
shouldDisplay=0;
bytes = width*height*3; //Color space is RGB
buffer = (GLubyte *)malloc(bytes); //buffer is global var for now
glFinish();
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer);
}
glutSwapBuffers();
}
这段代码运行后,malloc开始失败。ENOMEM失败,错误12。我对操作系统或GLUT了解不够,无法理解为什么会发生这种情况。我只尝试在一台3 GB的机器上分配17K。我使用的是Windows XP和Visual Studio c++ 2010 Express。
该代码在末尾缺少一个free(buffer)
,因此每次重绘都会消耗越来越多的内存,直到进程耗尽内存和/或地址空间(后者仅在32位系统上,因为64位地址空间很难在合理的时间内被少量分配耗尽)。
在调用glReadPixels之前尝试glPixelStorei(GL_PACK_ALIGNMENT, 1);
让我重新解释一下这个蹩脚的回答。我认为堆正在被丢弃,可能是由于丢失 free()和连续分配,可能是由于glReadPixels覆盖您的目标缓冲区。
大多数帧缓冲区至少是32位/双字对齐的,这表明,正如这里的注释所说,w*h*4字节可能只是匹配内部表示。
将对齐方式设置为1字节(如另一个答案所说)对我来说也很好。