Search code examples
c++openglglutopengl-compatglu

Calibrate coordinates on OpenGL?


I have a problem regarding the gluOrtho2D function. I want to resize the window size and calibrate its coordinates, but i have problems with the function. I think that the coordinates calculated

The problem is that if i click somewhere on the window, the point isn't on the cursor, but somewhere near it ( ~20 pixels). If i resize the window, i want the window points to be converted to the new window size, that's why the gluOrtho2D function had those parameters. Maybe i didn't figure it out the good way.

GLdouble  mouseX = ( double )(2* widthValue * x / windowWidthSize) - widthSize ;
GLdouble  mouseY = -( double )(2 * heightValue * y / windowHeightSize) + heightValue;

are good as i want them to take values from -30 to +30 (both x and y), but the

gluOrtho2D( -width / widthValue , width / widthValue , -height / heightValue , height / heightValue);

function doesn't convert them as i want. Any ideas to fix it?

#include<windows.h>
#include<GL/Glut.h> //includes the opengl, glu, and glut header files
#include<stdlib.h> //includes the standard library header file
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;

vector<pair<GLdouble,GLdouble>>v;

GLdouble  heightValue = 30.0; // the points X and Y coordinates would be [-30,30]
GLdouble  widthValue = 30.0; // the points X and Y coordinates would be [-30,30]

void initGL()
{
    glClearColor(1,1,1,0);
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glPointSize(5.0);
    glBegin(GL_POINTS);

    glColor3f(1.0f, 1.0f, 0.0f);

 // prints the points
    for(auto i : v)
        glVertex2d(i.first, i.second);

    glEnd();
    glFlush();
}

void reshape(GLsizei width, GLsizei height) {

   // Set the viewport to cover the new window
   glViewport(0, 0, width, height);

   // Set the aspect ratio of the clipping area to match the viewport
   glMatrixMode(GL_PROJECTION);  // To operate on the Projection matrix
   glLoadIdentity();             // Reset the projection matrix

   // here is the problem with the coordinates. Any help??
   gluOrtho2D(-width/ widthValue, width/ widthValue,-height / heightValue ,height / heightValue);
}

void mouseClick(int button, int state, int x, int y)
{

   if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) // left button is pressed
   {

   double windowHeightSize = glutGet(GLUT_WINDOW_HEIGHT); // gets window's size
   double windowWidthSize = glutGet(GLUT_WINDOW_WIDTH); // gets window's size

 //   converts the click coordinate on the screen to the coordinate on the window 
    GLdouble  mouseX = (double)(60.0 * x / windowWidthSize) - 30.0; 
    GLdouble  mouseY = -(double)(60.0 * y / windowHeightSize) + 30.0;

    v.push_back(make_pair(mouseX,mouseY) ); // insert the point's coordinates in the vector
    display();

   }

}

int main(int argc,char** argv)
{
    glutInit(&argc,argv);

    glutInitWindowSize(800, 600);
    glutInitWindowPosition(50, 50);//sets the position of the window in pixels from top left corner
    glutCreateWindow("Program Find Convex Hull");

    glutDisplayFunc(display);
    glutReshapeFunc(reshape); // functia este apelata cand redimensionam fereastra
    glutMouseFunc(mouseClick);

  //  initGL();
    glutMainLoop();//loops the current event

    return 0;
}

Solution

  • If the Orthographic projection is set by:

    gluOrtho2D(-ortho_x, ortho_x, -ortho_y, ortho_y);
    

    then the transformation of the moue position (window coordinates) to view coordinates is:

    GLdouble mouseX = (double)(x/windowWidthSize * 2*ortho_x) - ortho_x; 
    GLdouble mouseY = ortho_y - (double)(y/windowHeightSize * 2*ortho_y);
    

    Apply that to your example:

    GLdouble ortho_x = 30.0;
    GLdouble ortho_y = -30.0;
    
    void reshape(GLsizei width, GLsizei height) {
    
       // Set the viewport to cover the new window
       glViewport(0, 0, width, height);
    
       // Set the aspect ratio of the clipping area to match the viewport
       glMatrixMode(GL_PROJECTION);  // To operate on the Projection matrix
       glLoadIdentity();             // Reset the projection matrix
    
       ortho_x = width / widthValue;   
       ortho_y = height / heightValue;
    
       gluOrtho2D(-ortho_x, ortho_x, -ortho_y, ortho_y);
    }
    
    void mouseClick(int button, int state, int x, int y)
    {
    
       if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) // left button is pressed
       {
         double windowHeightSize = glutGet(GLUT_WINDOW_HEIGHT); // gets window's size
         double windowWidthSize = glutGet(GLUT_WINDOW_WIDTH); // gets window's size
    
          //   converts the click coordinate on the screen to the coordinate on the window 
          GLdouble mouseX = (double)(x/windowWidthSize * 2*ortho_x) - ortho_x; 
          GLdouble mouseY = ortho_y - (double)(y/windowHeightSize * 2*ortho_y);
    
          v.push_back(make_pair(mouseX,mouseY) ); // insert the point's coordinates in the vector
          glutPostRedisplay();
       }
    }
    

    Note, it is not necessary to change (ortho_x, ortho_y) in reshape. Since you mentioned in your question "i want them to take values from -30 to +30", it is even possible to keep (30.0, 30.0).