In OpenGL, how can I adjust for the window being resized?
Asked Answered
T

5

17

I am drawing several shapes (such as circles) that are keyed off of the window height & width. Since the window always starts at a given size, they are drawn correctly, but when the window is resized, it messes the aspect ratio up.

How can I draw the shapes properly, regardless of window size?

Trying answered 16/7, 2010 at 17:3 Comment(0)
M
28

You definitely don't want to make the size of your objects explicitly dependent on the window size.

As already suggested by genpfault, adjust your projection matrix whenever the window size changes.

Things to do on window resize:

  1. Adjust viewport

    glViewport(0, 0, width, height)
    
  2. Adjust scissor rectangle (only if you have GL_SCISSOR_TEST enabled)

    glScissor(0, 0, width, height)
    
  3. Adjust projection matrix

    In case of legacy (fixed function pipeline) OpenGL, you can do it the following ways:

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

    or

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

    or

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

    (assuming that left, right, bottom and top are all equal and ratio=width/height)

Mousetail answered 17/7, 2010 at 8:11 Comment(1)
Scissoring also influences the redrawn area, if you once set the clip rect by calling glScissor(). See this.Submicroscopic
A
7

If you're using something like gluPerspective() just use the window width/height ratio:

gluPerspective(60, (double)width/(double)height, 1, 256);
Abruzzi answered 16/7, 2010 at 19:19 Comment(0)
C
4

You should setup some sort of window handler function that is called whenever your OpenGL window is resized. You need to take care of the case when aspectRatio > 1, and when aspectRatio <= 1 separately. Not doing so may result in geometry falling offscreen after a screen resize.

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);
}
Conal answered 3/4, 2013 at 5:35 Comment(0)
F
0

I am learning opengl too. I faced this problem yesterday and I have not found the correct answer. Today, I have solve the problem. In my little program, the object changes size when resizing the window changing width or heigt. This is my code (please, forgive my errors):

#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;
}
Friedman answered 11/8, 2017 at 16:0 Comment(0)
A
0

There are many methods to do that. Following example shows you how I'm doing it in my projects and its working. The example shows you simply a rectangle box which do not changes it size when window is resizing. You can directly copy and paste it in your project(consider that i'm a openGl beginner)

#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();

}
Albanian answered 21/8, 2017 at 11:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.