Hi,
I'm trying out a zooming in-and-out with orthogonal projection. The following program changes the orthogonal projection between -200...200 by -200..200 (largest) to -100...100 by -100...100 (smallest). 4 triangles are drawn.
Everything seems to work fine if I let the program run on its own. (I don't care about aspect ratio for now.) But then I noticed something.
If I force a redisplay by covering my opengl program's window *completely* with another window, I notice that frequently the objects (the 4 triangles) drawn have been scaled. The scaling can be quite random. Furthermore, if the program's window is only partially covered and then revealed, everything would be fine and the 4 triangles are not scaled. The random scaling occurs only when the program's window is *fully* covered by another window. The same problem also occurs if I minimize and then maximize the program's window.
However I notice that the display is fine if I just drag and move the program's window around.
Can someone explain what's happening? I'm sure I'm missing something very important here.
#include <GL/freeglut.h>
const int M = 400; // window is M-by-M
float x = M/2, y = M/2; // gluOrtho2d is set to -x....x by -y...y.
const float abs_d = 50; // speed of zooming
float d = -abs_d; // velocity of zooming
int prev_time;
void display()
{
// Calculate new x, y for new ortho2d viewing volume
int curr_time = glutGet(GLUT_ELAPSED_TIME);
float elapsed_time = (curr_time - prev_time) / 1000.0;
prev_time = curr_time;
if (elapsed_time <= 0) return;
float dt = elapsed_time; // shorthand
x += d * dt;
y += d * dt;
if (x < 100)
{
d = abs_d; // switch to zoom out
x = 100; y = 100;
}
else if (x > M/2)
{
d = -abs_d; // switch to zoom in
x = M/2; y = M/2;
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-x, x, -y, y);
// Draw 4 triangles
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0, 0);
glVertex2f(-100, 0);
glVertex2f(-100, 100);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex2f(100, 0);
glVertex2f(180, 0);
glVertex2f(50, -100);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2f(-50, 0);
glVertex2f(0, -100);
glVertex2f(0, -150);
glColor3f(0.5f, 0.5f, 0.5f);
glVertex2f(100, 150);
glVertex2f(50, 120);
glVertex2f(100, 70);
glEnd();
glutSwapBuffers();
}
void timer_callback(int x)
{
glutPostRedisplay();
glutTimerFunc(50, timer_callback, 0);
}
int main(int argc, char ** argv)
{
glutInit(&argc, argv);
glutInitWindowPosition(0, 0);
glutInitWindowSize(M, M);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutCreateWindow("test");
glClearColor(1.0, 1.0, 1.0, 0.0);
glutDisplayFunc(display);
glutTimerFunc(50, timer_callback, 0);
prev_time = glutGet(GLUT_ELAPSED_TIME);
glEnable(GL_SMOOTH);
glutMainLoop();
return 0;
}