Search code examples
c++qtopenglcoordinate-transformation

OpenGl and QT coordinates


when I am using OpenGL in a non-qt project and i like to draw a line, im using this code:

glMatrixMode(GL_PROJECTION);
glOrtho(0,500,0,500,-1,1);

glBegin(GL_LINES);
   glVertex(50, 50);
   glVertex2i(200,200);
glEnd();

when im trying to do it at qt(using widget promote), those numbers are not coorect.

but if im using:

glBegin(GL_LINES);
   glVertex2f(-0.5, 0.5);
   glVertex2f(1, 1);
glEnd();

as i saw in many tutorials, i didn't write here the glOrtho and the glMatrixMode

so why in windows or linux the coordinates are different than qt and how to use it correctly?


Solution

  • First of all note, the OpenGL matrix stack and drawing with glBegin/glEnd sequences is deprecated since more than 10 years. Read about Fixed Function Pipeline and see Vertex Specification for a state of the art way of rendering.


    glOrtho set an orthographic projection matrix. The projection matrix describes the mapping from 3D points of the view on a scene, to 2D points on the viewport.
    At Orthographic Projection the coordinates in the view space are linearly mapped to clip space coordinates and the clip space coordinates are equal to the normalized device coordinates, because the w component is 1 (for a cartesian input coordinate).
    The values for left, right, bottom, top, near and far define a box. All the geometry which is inside the volume of the box is "visible" on the viewport.

    orthographic projection

    But glOrhto multiplies the current matrix on the mtrix stack with the new orthographic projection matrix.

    This means if you do

    glMatrixMode(GL_PROJECTION);
    glOrtho(0,500,0,500,-1,1);
    

    in every frame, then the projection matrix will continuously and progressively change

    To set a matrix to the matrix stack, the matrix stack has to be be initialized with the identity matrix first:

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,500,0,500,-1,1);
    


    Another possibility is to use glPushMatrix and glPopMatrix at the begin and the end of the renering. Push the matrix before you change it and pop it after the rendering.
    Since glOrtho changes the top most matrix on the matrix stack, glPopMtrix will "undo" the changes.

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glOrtho(0,500,0,500,-1,1);
    
    // do the rendering here
    
    glPopMatrix();