You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 10:37:42