如何使用鼠标滚轮修复放大和缩小?

How to fix zoom in & out with mouse scroll wheel?

我正在尝试制作一个程序,让我能够放大和缩小我绘制的图形,但我没有这样做;它正在切换图形的方向,如果我继续滚动,它就会消失。假设要执行的函数是 MouseFunc() 和 renderScene()。欢迎对问题或帮助进行任何解释。

#include"glut.h"
#include<cmath>
#include<iostream>
using namespace std;

float xr = 0, yr = 0; //to control the object's movement from left to right

// XZ position of the camera
float x = 0.0f, z = 5.0f; //Module 4
float angleX = 0.0f; //Module 4

//Shift + ArrowKey rotation
float transX = 0.0f;
float transY = 0.0f;
float rotY = 0.0f;
//end

//Mouse Commands
//float ZoomFactor = 0.5;
GLfloat theta3 = 0;
GLfloat phi = 0;
GLfloat rho = 5;

GLfloat camX = 0;
GLfloat camY = 0;
GLfloat camZ = 0;
GLfloat upX = 0;
GLfloat upY = 0;
GLfloat upZ = 0;
//end

GLfloat angle = 0.0f;
int refreshmill = 1;

void timer(int value) { //to control the rotation of the object
    glutTimerFunc(refreshmill, timer, 0);
}

void myDisplay(void) {
    //Circle One
    float theta;
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1, 0, 0);

    glPushMatrix();
    glBegin(GL_POLYGON);
    for (int x = 0; x < 360; x++) {
        theta = x * 3.142 / 180;
        glVertex2f(150 * cos(theta) + xr, 150 * sin(theta) + yr);
    }
    glEnd();
    glPopMatrix();

    //Circle Two
    float theta2;

    glPushMatrix();
    glTranslatef(0.5f, 0.0f, 0.0f); // rotation
    glRotatef(angle, 0.0f, 0.0f, -0.5f); // rotation
    glBegin(GL_POLYGON);
    glColor3f(0, 0, 1);
    for (int x = 0; x < 360; x++) {
        theta2 = x * 3.142 / 180;
        glVertex2f(150 + 15 * cos(theta2) + xr, 15 * sin(theta2) + yr);
    }

    angle += 0.2; // rotation
    glEnd();
    glPopMatrix();

    //Draw Star
    glColor3ub(119, 193, 15);

    glPushMatrix();
    glBegin(GL_POLYGON);
    glVertex2d(15 + xr, 60 + yr);
    glVertex2d(75 + xr, 75 + yr); //right peak
    glVertex2d(15 + xr, 90 + yr);
    glVertex2d(0 + xr, 150 + yr); //Up-peak Changed
    glVertex2d(-15 + xr, 90 + yr);
    glVertex2d(-75 + xr, 75 + yr);
    glVertex2d(-15 + xr, 60 + yr);
    glVertex2d(0 + xr, 0 + yr);
    glEnd();
    glPopMatrix();
}

//Close code
void handleKeypress(unsigned char key, int x, int y){
    switch (key){
    case 27: //when the escape key is pressed the program will exit.
        exit(0);
    }
}

//Movement of drawing
void keyboard(int key, int x, int y) {

    float fraction = 0.1f;
    bool shift = false;
    int mod = glutGetModifiers();
    if (mod == GLUT_ACTIVE_SHIFT) {
        shift = true;
    }
    if (!shift) {
        switch (key) {

        case GLUT_KEY_RIGHT: xr++; break;
        case GLUT_KEY_LEFT:  xr--; break;
        case GLUT_KEY_UP:    angleX -= 1.0f; break; //Module 4
        case GLUT_KEY_DOWN:  angleX += 1.0f; break; //Module 4
        }
    }
    else {
        switch (key) {

        case GLUT_KEY_LEFT:// Rotación del dibujo hacia la izquierda en el eje de Y
            rotY -= 1.0f;
            break;
        case GLUT_KEY_RIGHT:// Rotación del dibujo hacia la derecha en el eje de Y
            rotY += 1.0f;
            break;
        }
    }
}

//Mouse Function
void MouseFunc(int button, int state, int x, int y){
    if (button > 4){
        rho = rho + 3.0;
    }
    else (button < 3);{
        rho = rho - 3.0;
    }
}

void renderScene(void) {

    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0, 1.0, 0.0);
    glRotatef(rotY, 0.0, 1.0, 0.0); //Rotation with Shift + ArrowKey

    GLfloat camX = rho * cos(theta3*3.1415926f / 180)*sin(phi*3.1415926f / 180);
    GLfloat camY = rho * sin(theta3*3.1415926f / 180);
    GLfloat camZ = rho * cos(theta3*3.1415926f / 180)*cos(phi*3.1415926f / 180);

    // Reduce theta slightly to obtain another point on the same longitude line on the sphere.
    GLfloat dt = 1;
    GLfloat eyeXtemp = -rho * cos((theta3 - dt)*3.1415926f / 180)*sin(phi*3.1415926f / 180);
    GLfloat eyeYtemp = -rho * sin((theta3 - dt)*3.1415926f / 180);
    GLfloat eyeZtemp = -rho * cos((theta3 - dt)*3.1415926f / 180)*cos(phi*3.1415926f / 180);

    // Connect these two points to obtain the camera's up vector.
    GLfloat upX = eyeXtemp - camX;
    GLfloat upY = eyeYtemp - camY;
    GLfloat upZ = eyeZtemp - camZ;

    // Clear Color and Depth Buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Reset transformations
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // Set the camera
    gluLookAt(camX, camY, camZ, 0, 0, 0, upX, upY, upZ);
    gluLookAt(x, 0.0f, z, x, 0.0f, z - 1.0f, 0.0f, 1.0f, 0.0f); //Module 4
    glRotatef(angleX, 1, 0, 0); //Module 4

    myDisplay();

    glFlush();
    glutPostRedisplay();
    glutSwapBuffers();
}

void init() {
    glClearColor(0, 0, 0, 1);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(0.0f, 0.1f, 0.1f, 0.0f);
    glOrtho(-250, 250, -250, 250, -250, 250); //IMPORTANT- Define from negative to positive
    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char** argv) {
    // init GLUT and create window
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("Homework: Circle");
    // register callbacks
    glutDisplayFunc(renderScene);
    glutTimerFunc(0,timer,0);
    glutKeyboardFunc(handleKeypress);
    glutSpecialFunc(keyboard);
    glutMouseFunc(MouseFunc);
    // OpenGL init
    init();
    // enter GLUT event processing cycle
    glutMainLoop();
}

用于设置透视和正交投影。删除透视投影gluPerspective:

void init() {
    glClearColor(0, 0, 0, 1);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    //gluPerspective(0.0f, 0.1f, 0.1f, 0.0f); <---- delete

    glOrtho(-250, 250, -250, 250, -250, 250);
    glMatrixMode(GL_MODELVIEW);
}

如果要缩放,则必须更改正射投影 (glOrtho)。投影矩阵描述了从场景的 3D 点到视口的 2D 点的映射。

实现鼠标滚轮事件,在限定范围内改变zoom

例如

GLdouble zoom = 0.0f;
void MouseFunc(int button, int state, int x, int y){

    GLdouble min_z = -100.0;
    GLdouble max_z = 100.0;

    if (button == 4 && zoom < max_z) {
        zoom += 3.0;
    }
    else if (button == 3 && zoom > min_z) {
        zoom -= 3.0;
    }
}

修改正交投影,依赖显示循环中的zoom renderScene:

void renderScene(void) {

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    GLdouble ortho = 250 + zoom;
    glOrtho(-ortho, ortho, -ortho, ortho, -250, 250);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // [...]
}