Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't correctly reshape polygons in the window

I'm trying to develop a program in which every time a click is performed on the window, a random-size circle appears on the window centered on where the click happened. After that, I need to use glOrtho() or gluOrtho2D() so that the viewing volume would be set up in such a way that when the window is resized, the circles do not change their sizes or get distorted on the screen.

I tried to write the reshape function in different ways but I can't get the right result.

int winWidth = 800;             
int winHeight = 600; 

int main( int argc, char** argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE );  
    glutInitWindowSize( winWidth, winHeight );
    glutCreateWindow( "main" );

    MyInit();

    glutDisplayFunc( MyDisplay );
    glutReshapeFunc( MyReshape );
    glutMouseFunc( MyMouse );

    glutMainLoop();
    return 0;
}

void MyReshape( int w, int h )
{
    winWidth = w;
    winHeight = h;

    glViewport( 0, 0, w, h );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    if (w <= h)
        glOrtho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w,
            2.0 * (GLfloat) h / (GLfloat) w, -20.0, 20.0);
    else
        glOrtho(-2.0 * (GLfloat) w / (GLfloat) h,
            2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, -20.0, 20.0);

    glMatrixMode( GL_MODELVIEW );

}

void MyMouse( int btn, int state, int x, int y )
{
    if ( btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
    {
        disc[numDiscs].pos[0] = x;
        disc[numDiscs].pos[1] = y;
        disc[numDiscs].speed[0] = ((rand() % 2) * 2 - 1) * (MIN_X_SPEED + rand() / (RAND_MAX / (MAX_X_SPEED - MIN_X_SPEED)));
        disc[numDiscs].speed[1] = ((rand() % 2) * 2 - 1) * (MIN_Y_SPEED + rand() / (RAND_MAX / (MAX_Y_SPEED - MIN_Y_SPEED)));
        disc[numDiscs].radius = (MIN_RADIUS + rand() / (RAND_MAX / (MAX_RADIUS - MIN_RADIUS)))/10;
        disc[numDiscs].color[0] = (char)rand() % 256;
        disc[numDiscs].color[1] = (char)rand() % 256;
        disc[numDiscs].color[2] = (char)rand() % 256;

        numDiscs++;
        glutPostRedisplay();
    }
}

void MyDisplay( void )
{
    glClear( GL_COLOR_BUFFER_BIT );
    glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

    for ( int i = 0; i < numDiscs; i++ ) DrawDisc( &disc[i] );

    glFlush();  
}

void MyInit( void )
{
    glClearColor( 0.0, 0.0, 0.0, 1.0 ); 
    glShadeModel( GL_FLAT );
}

1 Answers

[...] in such a way that when the window is resized, the circles do not change their sizes or get distorted [...]

If the circles should keep there size in pixel units, then you've to define a orthographic projection, which is based on the relation of the current size of the window to initial size of the window.
Since the size of you window is (800, 600) you've to scale the projection dependent on the height of the window by w/600.0 respectively h/600.0, because the height is less than the width and the aspect is applied to the longer side:

void MyReshape( int w, int h )
{
    winWidth = w;
    winHeight = h;

    glViewport( 0, 0, w, h );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    if (w <= h)
    {
        GLdouble  aspect = (GLdouble)h / w;
        GLdouble  scale  = w / 600.0;

        scale *= 2.0;
        project = glm::ortho(-scale, scale, -scale * aspect, scale * aspect, -20.0, 20.0);
    }
    else
    {
        GLdouble  aspect = (GLdouble)w / h;
        GLdouble  scale  = h / 600.0;

        scale *= 2.0;
        project = glm::ortho(-scale * aspect, scale * aspect, -scale, scale, -20.0, 20.0);
    }
    glMatrixMode( GL_MODELVIEW );
}
like image 147
Rabbid76 Avatar answered Jan 29 '26 16:01

Rabbid76