代码之家  ›  专栏  ›  技术社区  ›  foobarfuzzbizz

在OpenGL中,如何调整窗口的大小?

  •  10
  • foobarfuzzbizz  · 技术社区  · 14 年前

    如何正确绘制形状,而不考虑窗口大小?

    5 回复  |  直到 6 年前
        1
  •  18
  •   HolyBlackCat    6 年前

    您肯定不想让对象的大小显式地依赖于窗口大小。

    正如genpfault所建议的,只要窗口大小改变,就调整投影矩阵。

    调整窗口大小时的操作:

    1. glViewport(0, 0, width, height)
      
    2. 调整剪刀矩形 (如果你有 GL_SCISSOR_TEST 已启用)

      glScissor(0, 0, width, height)
      
    3. 调整投影矩阵

      如果是传统的(固定功能管道)OpenGL,可以通过以下方式进行:

      glFrustum(left * ratio, right * ratio, bottom, top, nearClip,farClip)
      

      glOrtho(left * ratio, right * ratio, bottom, top, nearClip,farClip)
      

      gluOrtho2D(left * ratio, right * ratio, bottom, top)
      

      left, right, bottom top 都是平等的 ratio=width/height )

        2
  •  5
  •   genpfault    14 年前

    如果您使用的是glupperspective()之类的工具,只需使用窗宽/高比:

    gluPerspective(60, (double)width/(double)height, 1, 256);
    
        3
  •  3
  •   Dustin Biser    12 年前

    您应该设置某种窗口处理程序函数,每当调整OpenGL窗口的大小时都会调用该函数。当aspectRatio>1,当aspectRatio<=1分开。不这样做可能会导致几何图形在屏幕调整大小后落在屏幕之外。

    void windowResizeHandler(int windowWidth, int windowHeight){
        const float aspectRatio = ((float)windowWidth) / windowHeight;
        float xSpan = 1; // Feel free to change this to any xSpan you need.
        float ySpan = 1; // Feel free to change this to any ySpan you need.
    
        if (aspectRatio > 1){
            // Width > Height, so scale xSpan accordinly.
            xSpan *= aspectRatio;
        }
        else{
            // Height >= Width, so scale ySpan accordingly.
            ySpan = xSpan / aspectRatio;
        }
    
        glOrhto2D(-1*xSpan, xSpan, -1*ySpan, ySpan, -1, 1);
    
        // Use the entire window for rendering.
        glViewport(0, 0, windowWidth, windowHeight);
    }
    
        4
  •  0
  •   José Antonio López Cano    7 年前

    我也在学习opengl。我昨天遇到了这个问题,但我没有找到正确的答案。今天,我已经解决了这个问题。在我的小程序中,当改变窗口的宽度或高度时,对象会改变大小。这是我的代码(请原谅我的错误):

    #include <GL/freeglut.h>
    
    void fnReshape(int ww, int hh)
    {
      GLdouble r;
      if(hh == 0)
        hh = 1.0;
      if(hh > ww)
        r = (double) hh / (double) ww;
      else
        r = (double) ww / (double) hh;
      glViewport(0, 0, ww, hh);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      if(hh > ww)
        glFrustum(-1.0, 1.0, -1.0 * r, 1.0 * r, 2.0, 200.0);
      else
        glFrustum(-1.0 * r, 1.0 * r, -1.0, 1.0, 2.0, 200.0);
    }
    //////////////////////////////////////////////////////////////////
    void fnDisplay(void)
    {
      glClear(GL_COLOR_BUFFER_BIT);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      glTranslatef(0., 0., -5.);
      glBegin(GL_QUAD_STRIP);
      glColor3f(0., 0., 1.0);
      glVertex3f(-1., -1., 0.);
      glVertex3f(-1., 1., 0.);
      glVertex3f(1., -1., 0.);
      glVertex3f(1., 1., 0.);
      glEnd();
      glutSwapBuffers();
    }
    ////////////////////////////////////////////////////////////
    int main(int argc, char **argv) {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_RGBA |GLUT_DOUBLE);
        glutInitWindowSize(500, 500);
        glutCreateWindow("Sample window");
        glClearColor(1.0, 0, 0, 1.0);
        glutDisplayFunc(fnDisplay);
        glutReshapeFunc(fnReshape);
        glutMainLoop();
        return 0;
    }
    
        5
  •  0
  •   Sathsara AM    7 年前

    该示例仅显示一个矩形框,当窗口调整大小时,该框的大小不会改变。您可以直接复制并粘贴到您的项目中(假设我是openGl初学者)

    #include<windows.h>
    #include<glut.h>
    
    GLfloat x1=100.0f;
    GLfloat y1=150.0f;
    GLsizei rsize = 50;
    
    GLfloat xstep=1.0f;
    GLfloat ystep=1.0f;
    
    GLfloat windowWidth;
    GLfloat windowHeight;
    
    
    void scene(void){
       glClear(GL_COLOR_BUFFER_BIT);
       glColor3f(1.0f,0.0f,0.0f);
    
       glRectf(x1,y1,x1+rsize,y1-rsize);
    
       glutSwapBuffers();
    }
    
    void setupRc(void){
    
      glClearColor(0.0f,0.0f,1.0f,0.0f);
    
    }
    
    void changeSize(GLsizei w,GLsizei h){
      if(h==0)
      h=1;
      glViewport(0,0,w,h);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
       if(w>=h){
         windowWidth=250.0f*w/h;
         windowHeight=250.f;
       }
       else{
         windowWidth=250.0f;
         windowHeight=250.f*h/w;
       } 
    
       glOrtho(0.0f,windowWidth,0.0f,windowHeight,1.0f,-1.0f);
    
    
       glMatrixMode(GL_MODELVIEW);
       glLoadIdentity();
    
    
    }
    
    
    
    
    void main(void){
    
       glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    
       glutCreateWindow("Rectangle");
    
       glutReshapeFunc(changeSize);
       glutDisplayFunc(scene);
       setupRc();
    
       glutMainLoop();
    
    }