在 OpenGL 上校准坐标?

Calibrate coordinates on OpenGL?

我对 gluOrtho2D 函数有疑问。我想调整 window 大小并校准其坐标,但我的功能有问题。我认为坐标计算

问题是,如果我单击 window 上的某个位置,该点不在光标上,而是在它附近的某个位置(~20 像素)。如果我调整 window 的大小,我希望将 window 点转换为新的 window 大小,这就是 gluOrtho2D 函数具有这些参数的原因。可能我没有想出好的方法。

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

很好,因为我希望它们取值从 -30 到 +30(x 和 y),但是

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

函数没有按照我的意愿转换它们。有什么解决办法吗?

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

如果 Orthographic projection 设置为:

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

那么鼠标位置(window坐标)到视图坐标的转换为:

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

将其应用于您的示例:

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

请注意,reshape 中的 (ortho_xortho_y) 无需更改。由于您在问题中提到 "i want them to take values from -30 to +30",甚至可以保留 (30.0, 30.0).