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

如何在FreeGLUT中调整子窗口大小并保持宽高比?

解决FreeGLUT主窗口缩放时子窗口同步缩放并保持宽高比的问题

FreeGLUT不会自动随主窗口缩放调整子窗口的位置与尺寸,你需要在主窗口的reshape回调中手动计算子窗口的新参数并更新,同时保留子窗口自身的宽高比处理逻辑。以下是修改后的完整代码:

#include <GL/glut.h>

using namespace std;

// 全局变量存储窗口句柄和初始比例
int mainWindow, subWindow;
int mainInitWidth = 512, mainInitHeight = 512;
float subXRel = 50.0f / mainInitWidth;
float subYRel = 50.0f / mainInitHeight;
float subWidthRel = 412.0f / mainInitWidth;
float subHeightRel = 412.0f / mainInitHeight;

void display(void);
void mainReshape(int width, int height);
void subReshape(int width, int height);
void drawGrid(void);

const float gridSize = 20;

void drawGrid()
{
    //vertical grid lines
    glColor3f(1, 1, 0);
    glLineStipple(1, 0xAAAA);
    glEnable(GL_LINE_STIPPLE);

    glBegin(GL_LINES);

    for (int i = 0; i <= 100; i += gridSize) {
        glVertex2f(i, -100);
        glVertex2f(i, 100);
    }

    //horizontal grid lines
    for (int i = -100; i <= 100; i += gridSize) {
        glVertex2f(0, i);
        glVertex2f(100, i);
    }

    glEnd();
    glDisable(GL_LINE_STIPPLE);
}

void display() {
    glClear(GL_COLOR_BUFFER_BIT);
    drawGrid();
    glutSwapBuffers();
}

void mainReshape(int width, int height) {
    // 处理主窗口的视口与投影,保持宽高比
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    float aspectRatio = static_cast<float>(width) / static_cast<float>(height);
    if (aspectRatio > 1.0) {
        gluOrtho2D(-10 * aspectRatio, 110 * aspectRatio, -110, 110);
    } else {
        gluOrtho2D(-10, 110, -110 / aspectRatio, 110 / aspectRatio);
    }
    glMatrixMode(GL_MODELVIEW);

    // 按初始比例计算子窗口的新位置和尺寸
    int subX = static_cast<int>(width * subXRel);
    int subY = static_cast<int>(height * subYRel);
    int subWidth = static_cast<int>(width * subWidthRel);
    int subHeight = static_cast<int>(height * subHeightRel);

    // 切换到子窗口上下文,更新其位置和大小
    glutSetWindow(subWindow);
    glutPositionWindow(subX, subY);
    glutReshapeWindow(subWidth, subHeight);
    // 切回主窗口上下文
    glutSetWindow(mainWindow);
}

void subReshape(int width, int height) {
    // 子窗口自身的宽高比保持逻辑
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    float aspectRatio = static_cast<float>(width) / static_cast<float>(height);
    if (aspectRatio > 1.0) {
        gluOrtho2D(-10 * aspectRatio, 110 * aspectRatio, -110, 110);
    } else {
        gluOrtho2D(-10, 110, -110 / aspectRatio, 110 / aspectRatio);
    }
    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitWindowSize(mainInitWidth, mainInitHeight);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);

    mainWindow = glutCreateWindow("Main Window");
    glutDisplayFunc(display);
    glutReshapeFunc(mainReshape);

    subWindow = glutCreateSubWindow(mainWindow, 50, 50, 412, 412);
    glutDisplayFunc(display);
    glutReshapeFunc(subReshape);

    glutMainLoop();
    return 0;
}

关键修改说明:

  • 全局变量存储比例:记录主窗口初始尺寸和子窗口的相对位置、大小比例,确保主窗口缩放时子窗口能保持原有的相对布局。
  • 主窗口重塑回调:在处理完自身的视口和投影后,计算子窗口的新位置与尺寸,通过glutSetWindow切换到子窗口上下文,调用glutPositionWindow和glutReshapeWindow更新参数。
  • 子窗口独立重塑回调:保留子窗口自身的宽高比处理逻辑,确保子窗口缩放时内部内容不会变形。

内容的提问来源于stack exchange,提问作者user45687895135482

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:45:06