В OpenGL, как я могу изменить размер окна? - PullRequest
11 голосов
/ 16 июля 2010

Я рисую несколько фигур (таких как круги), которые выделены по высоте и ширине окна.Поскольку окно всегда начинается с заданного размера, оно отображается правильно, но при изменении размера окна оно ухудшает соотношение сторон.

Как правильно нарисовать фигуры, независимо от размера окна?

Ответы [ 5 ]

15 голосов
/ 17 июля 2010

Вы определенно не хотите, чтобы размер ваших объектов явно зависел от размера окна.

Как уже предлагалось 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)

5 голосов
/ 16 июля 2010

Если вы используете что-то вроде gluPerspective (), просто используйте соотношение ширины / высоты окна:

gluPerspective(60, (double)width/(double)height, 1, 256);
2 голосов
/ 03 апреля 2013

Вы должны установить какую-то функцию обработчика окна, которая вызывается всякий раз, когда размер вашего окна OpenGL изменяется. Вам нужно позаботиться о случае, когда aspectRatio> 1, и когда aspectRatio <= 1 отдельно. Невыполнение этого требования может привести к падению геометрии за пределы экрана после изменения размера экрана. </p>

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 голосов
/ 21 августа 2017

Есть много способов сделать это. Следующий пример показывает, как я делаю это в своих проектах и ​​как это работает. В примере показан просто прямоугольник, который не меняет свой размер при изменении размера окна. Вы можете напрямую скопировать и вставить его в свой проект (учтите, что я новичок в 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();

}
0 голосов
/ 11 августа 2017

Я тоже учусь 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;
}
...