2012-10-17 200 views
2

我无法实现以下行为。我想从底部调整窗口大小,而不会渲染渲染场景或改变其位置。调整GLUT窗口的大小而不调整内容大小?

enter image description here

我使用C++的OpenGL GLUT

void resize(int w, int h) 
{ 
    float ratio = G_WIDTH/G_HEIGHT; 
    glViewport(0, 0, (h-(w/ratio))>0? w:(int)(h*ratio), (w-(h*ratio))>0? h:(int)(w/ratio)); 
} 
+1

请勿使用过量。没有它,这是微不足道的 - 只需设置最大的视口大小,并且不要超过这个大小。 –

+0

你需要更新视口和投影矩阵,查看我的答案。 –

回答

1
ratio = wantedWidth/wantedHeight 
glViewport(0, 0, 
     (height-(width/ratio))>0? width:(int)(height*ratio), 
    (width-(height*ratio))>0? height:(int)(width/ratio); 

会做到这一点,它使比值始终窗口的高度/宽度之间的相同,同时还尝试使用可用窗口的最大尺寸。

编辑:把它总是左上角。

+0

很接近!它做了效果,但为了水平调整大小。 – Jonas

+0

你的意思是上面的代码在垂直调整大小时不能正确调整大小,但是水平地很好? – SinisterMJ

+0

是的,就是这样。 – Jonas

3

在GLUT调整大小场景函数中,默认情况下视口可能设置为窗口大小。我会尝试只是改变这是你想要的(固定)大小:

相反的:

void windowReshapeFunc(GLint newWidth, GLint newHeight) 
{ 
    glViewport(0, 0, newWidth, newHeight); 
    .. etc... 
} 

这样做:

void windowReshapeFunc(GLint newWidth, GLint newHeight) 
{ 
    glViewport(0, 0, 400, 600); 
    .. etc... 
} 

或者任何大小你想要的。该窗口仍将调整大小,但这些场景将始终呈现给(现在固定的)视口。

2

如果使用的是正交透视使用这样的:

#include <GL/glut.h> 

int x0, y0 = 0; 
int ww, hh = 0; 

void updateCamera() 
{ 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(x0, x0+ww, y0, y0+hh, -1, 1); 
    glScalef(1, -1, 1); 
    glTranslatef(0, -hh, 0); 
} 

void reshape(int w, int h) 
{ 
    ww = w; 
    hh = h; 
    glViewport(0, 0, w, h); 
    updateCamera(); 
} 

void display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    glBegin(GL_TRIANGLES); 
    glColor3f(0.0, 0.0, 1.0); glVertex2i(0, 0); 
    glColor3f(0.0, 1.0, 0.0); glVertex2i(200, 200); 
    glColor3f(1.0, 0.0, 0.0); glVertex2i(20, 200); 
    glEnd(); 
    glFlush(); 
    glutPostRedisplay(); 
} 

int mx = 0; 
int my = 0; 
int dragContent = 0; 

void press(int button, int state, int x, int y) 
{ 
    mx = x; 
    my = y; 
    dragContent = button == GLUT_LEFT_BUTTON && state == GLUT_DOWN; 
} 

void move(int x, int y) 
{ 
    if(dragContent) 
    { 
     x0 -= x - mx; 
     y0 += y - my; 
     mx = x; 
     my = y; 
     updateCamera(); 
    } 
} 

int main(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutCreateWindow("Resize window without resizing content + drag content"); 
    glutDisplayFunc(display); 
    glutReshapeFunc(reshape); 
    glutMouseFunc(press); 
    glutMotionFunc(move); 
    glutMainLoop(); 
    return 0; 
} 

可以使用左鼠标拖动内容(三角形)。

+0

我可以使用Glut甚至WIN API来防止水平调整大小吗? – Jonas

+0

不确定为什么你需要窗口具有固定的宽度。但我想用WIN API,可以在窗口大小调整时设置窗口宽度。 –

1

下面是我找到的解决方案,我认为它工作得很好。

我写我的重塑方法如下,这与glutReshapeFunc(reshape)在我的主要方法进行注册:

void reshape(int width, int height) { 
    glViewport(0, 0, width, height); 
    aspect = ((double) width)/height; 

每当我重新绘制的场景,我使用这个调用来设置相机:

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
gluPerspective(45.0, aspect, 1.0, 100.0); // 45 degrees fovY, correct aspect ratio 
// then remember to switch back to GL_MODELVIEW and call glLoadIdentity 

这让我把窗口当作一个窗口进入我的场景,而不用缩放或移动场景。我希望这是你正在寻找的!