Linux下OpenGL窗口调整触发resize函数无限循环问题求助
解决GLUT在Linux下resize无限循环导致段错误的问题
问题根源
你碰到的这个问题,核心在于GLUT平台实现的差异:
- Linux常用的freeglut中,调用
glutReshapeWindow时,哪怕目标尺寸和当前窗口完全一致,系统依然会触发glutReshapeFunc回调。这就导致你的resize函数里调用glutReshapeWindow,会再次触发自身,形成无限递归,栈被撑爆后就出现了Segmentation fault。 - 而Mac的GLUT实现做了优化:当检测到目标尺寸和当前窗口相同时,会跳过触发
resize回调,所以不会出现循环问题。
至于你打印的w和h已经是预设值还会触发——因为每次调用glutReshapeWindow,系统都会生成一个窗口尺寸变化的事件,回调收到的参数就是你设置的预设值,但这个触发动作不会停止,直到栈溢出。
快速修复方案
在resize函数里增加尺寸判断,只有当传入的尺寸和预设值不一致时,才调用glutReshapeWindow,这样就能打破循环:
void resize(int w, int h){ if (w != WINDOW_WIDTH || h != WINDOW_HEIGHT) { glutReshapeWindow(WINDOW_WIDTH, WINDOW_HEIGHT); } }
额外性能优化建议
另外,你的display函数每次重绘都会重新读取文件、计算节点位置,这会产生大量重复计算,拖慢程序运行。建议把这些初始化逻辑移到主函数中,只执行一次:
// 全局变量(也可以用结构体封装来避免全局变量) Matrix* distanceMatrix = NULL; PalleteNodePosition* nodesPositions = NULL; int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode ( GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); glutInitWindowPosition(100, 100); glutCreateWindow(APP_NAME); glClearColor(0.0, 0.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, 50.0, 0.0, 50.0, 0.0, 0.1); // 初始化数据,仅执行一次 distanceMatrix = fromFile(inputFileName); printf("Finish input parsing...\n"); nodesPositions = calculateNodesPositions(distanceMatrix); printf("Finish calculating nodes position on screen...\n"); glutDisplayFunc(display); glutReshapeFunc(resize); glutMainLoop(); } void display() { glClear( GL_COLOR_BUFFER_BIT); drawNodes(nodesPositions, distanceMatrix->width); drawLink(10, 10, 18, 18); glFlush(); }
这样既解决了resize的循环问题,又大幅提升了程序的运行效率。
内容的提问来源于stack exchange,提问作者João Lucas Gouveia
相关产品推荐
相关产品推荐

