如何在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
相关产品推荐
相关产品推荐

