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

问题描述 投票:11回答:5

我正在绘制几个从窗口高度和宽度键入的形状(例如圆圈)。由于窗口始终以给定大小开始,因此它们被正确绘制,但是当窗口调整大小时,它会使宽高比混乱。

无论窗口大小如何,我如何正确绘制形状?

opengl graphics viewport
5个回答
15
投票

您绝对不希望明确依赖于窗口大小来使对象的大小。

正如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, bottomtop都相等而且ratio=width/height

5
投票

如果你正在使用像gluPerspective()这样的东西,只需使用窗口宽度/高度比:

gluPerspective(60, (double)width/(double)height, 1, 256);

2
投票

您应该设置某种窗口处理函数,只要调整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);
}

0
投票

我也在学习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;
}

0
投票

有很多方法可以做到这一点。以下示例向您展示了我在项目及其工作中的表现。该示例显示了一个矩形框,当窗口调整大小时,它不会改变它的大小。你可以直接将它复制并粘贴到你的项目中(考虑到我是一个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();

}
© www.soinside.com 2019 - 2024. All rights reserved.