C++ 另一个缩放到点的问题

C++ 另一个缩放到点的问题,c++,qt,opengl,zooming,model-view,C++,Qt,Opengl,Zooming,Model View,我有一个2D应用程序,它是一个图像查看器。 我有能力在窗口中平移图像,我有一个基本的缩放功能。 现在我想改进缩放,使其缩放到鼠标下的点。 到目前为止,我已经在谷歌上阅读了所有可能的内容,并且我已经接近了一些有用的东西, 但仍然找不到有效的方法,以下是我得到的: glMatrixMode (GL_PROJECTION); glLoadIdentity(); // w and h are respectivly the width and

我有一个2D应用程序,它是一个图像查看器。 我有能力在窗口中平移图像,我有一个基本的缩放功能。 现在我想改进缩放,使其缩放到鼠标下的点。 到目前为止,我已经在谷歌上阅读了所有可能的内容,并且我已经接近了一些有用的东西, 但仍然找不到有效的方法,以下是我得到的:

          glMatrixMode (GL_PROJECTION);
          glLoadIdentity();

         // w and h are respectivly the width  and height of the window      
        // newzoom_pos is the point in openGL coordinates  where the user requested the zoom
        // zoomFactor is between [0.1,10.0]  , 0.1 -> 1.0 means downscale, 1.0 -> 10.0 means upscale
        // transX and transY are used to pan around the image
        float left = (0.f+transX -newzoom_pos.x())/zoomFactor  +newzoom_pos.x();
        float right = (w+transX -newzoom_pos.x())/zoomFactor +newzoom_pos.x();
        float bottom = (h-transY-newzoom_pos.y())/zoomFactor +newzoom_pos.y();
        float top = (0.f-transY -newzoom_pos.y())/zoomFactor +newzoom_pos.y();

        glOrtho(left, right, top, bottom, -1, 1);

        glMatrixMode (GL_MODELVIEW);
        glLoadIdentity ();
它几乎可以工作,但它不好,它不能精确地缩放到所需的点,当图像很小并且还不能完全适应查看器时(周围有黑色),它很混乱并且不工作

顺便说一句,以下是用户放大鼠标滚轮事件处理程序时的代码:

zoomFactor+=0.1;
QPoint oglpos = openGLpos(new_zoomPoint.x(), new_zoomPoint.y());
 this->newzoom_pos = oglpos;
openGLpos功能如下所示:

QPoint ViewerGL::openGLpos(int x,int y){
    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    GLfloat winX=0, winY=0, winZ=0;
    GLdouble posX=0, posY=0, posZ=0;
    glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
    glGetDoublev( GL_PROJECTION_MATRIX, projection );
    glGetIntegerv( GL_VIEWPORT, viewport );
    winX = (float)x;
    winY = viewport[3]- y;
    if(winY == 0) winY =1.f;
    glReadPixels( x, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
    GLint b=gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
    if(b==GLU_FALSE) cout << "failed unprojection" << endl;
    return QPoint(posX,posY);
}
qpointviewergl::openGLpos(int x,int y){
闪烁视口[4];
GLdouble modelview[16];
gl双投影[16];
GLfloat winX=0,winY=0,winZ=0;
GLdouble posX=0,posY=0,posZ=0;
glGetDoublev(GL_模型视图_矩阵,模型视图);
glGetDoublev(GL_投影矩阵,投影);
glGetIntegerv(GL_视口,视口);
winX=(float)x;
winY=视口[3]-y;
如果(winY==0)winY=1.f;
glReadPixels(x、winY、1、1、GL_深度分量、GL_浮点和winZ);
闪烁b=glunproject(winX、winY、winZ、modelview、投影、视口、&posX、&posY、&posZ);
如果(b==GLU_FALSE)不能