2

My openGL application draws the circle as an oval instead of a circle. My code is:

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();

glOrtho(0.0f, 800, 0.0f, 400, 0.0f, 1.0f);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();

glPushMatrix();

glColor3f(255.0, 255.0, 255.0);
drawRect(racket_left_x, racket_left_y, racket_width, racket_height);
drawRect(racket_right_x, racket_right_y, racket_width, 
racket_height);
glPopMatrix();

// drawBall();
//drawBall2();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
drawBall();

glPopMatrix();
glPopMatrix();

glutSwapBuffers();

How can I fix this?

I've tried changing the glMatrixModes but that doesn't seems to work. Thanks.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Test
  • 47
  • 4
  • This is essentially a duplicate of https://stackoverflow.com/questions/9071814/opengl-stretched-shapes-aspect-ratio – Dúthomhas Nov 04 '17 at 02:40
  • Possible duplicate of [OpenGL stretched shapes - aspect ratio](https://stackoverflow.com/questions/9071814/opengl-stretched-shapes-aspect-ratio) – BDL Nov 04 '17 at 08:58

1 Answers1

0

The projection matrix transforms all vertex data from the eye coordinates to the clip coordinates. Then, these clip coordinates are also transformed to the normalized device coordinates (NDC) by dividing with w component of the clip coordinates. The normalized device coordinates is in range (-1, -1, -1) to (1, 1, 1).

With the orthographic projection, the eye space coordinates are linearly mapped to the NDC.

The orthographic projection can be set up by glOrtho. If you want to set up a projection that allows you to draw in window size scales, then you have to do it like this:

int wndWidth  = 800;  
int wndHeight = 400; 
glOrtho( 0.0, (float)wndWidth, 0.0, (float)wndHeight, -1.0, 1.0 );

If the viewport is rectangular this has to be considerd by mapping the coordinates.

float aspect = (float)widht/height;
glOrtho(-aspect, aspect, -1.0f, 1.0f, -1.0f, 1.0f);


You set up a proper window size projection matrix before you draw the rectangles (drawRect)

glMatrixMode (GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, 800, 0.0f, 400, 0.0f, 1.0f);

.....

drawRect( ..... );


But you "clear" the projection matrix and do not care about the aspect of the view before you draw the circle (drawBall).

Change your code somehow like this:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

float aspect = 800.0f/400.0f;
glOrtho(-aspect, aspect, -1.0f, 1.0f, -1.0f, 1.0f);

drawBall();


By the way, while glPushMatrix push an element to the matrix stack, glPopMatrix pop an element from the matrix stack. In OpenGL there is one matrix stack for each matrix mode (See glMatrixMode). The matrix modes are GL_MODELVIEW, GL_PROJECTION, and GL_TEXTURE and all matrix operations, are applied to the matrix stack you have specified by glMatrixMode.
This means the both glPopMatrix instructions at the end of your code snippet should not be there.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174