# ortho2d view changed on re-display

## Recommended Posts

jondill    107

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);
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;
}


##### Share on other sites
PeterStock    821

Maybe the projection and model-view matrices are being confused? I see you're setting the projection matrix in the display function - I set my model-view matrix there, and set the projection matrix only when changing the window size. From the sound of what triggers the bug, it sounds like checking your window resize callback might be a good idea :)