使用鼠标单击OpenGL-C ++将形状移动到单击的位置

时间:2014-12-18 15:50:33

标签: c++ opengl mouseevent

我需要帮助来理解如何缩放我的坐标。指令说,修改代码将三角形移动到鼠标点击位置。有人能解释一下这是怎么做到的吗?

以下是我正在使用的源代码:

#ifdef __APPLE__
#include <GLUT/glut.h> 
#else
#include <GL/glut.h> 
#endif

#include <stddef.h>
#include <iostream>

// values controlled by fast keys
float g_angle = 0.0f;
float g_xoffset = 0.0f;
float g_yoffset = 0.0f;
int x;
int y;

// increments
const float g_angle_step = 32.0f; // degrees
const float g_offset_step = 32.0f; // world coord units

// last cursor click
int g_cursor_x = 0;
int g_cursor_y = 0;

void draw_triangle()
{
    // in model cooridnates centred at (0,0)
    static float vertex[3][2] =
        {
            {-1.0f, -1.0f},
            {1.0f, -1.0f},
            {0.0f, 1.0f}
        };

    glBegin(GL_LINE_LOOP); 
        for (size_t i=0;i<3;i++)
            glVertex2fv(vertex[i]);
    glEnd();
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT); 
    glColor3f(1.0f, 1.0f, 1.0f); 
    glLineWidth(2.0f);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
        glTranslatef(500.0f+g_xoffset, 500.0f+g_yoffset, 0.0f);
        glScalef(100.0f, 100.0f, 1.0f);
        glRotatef(g_angle, 0.0f, 0.0f, 1.0f); 
        draw_triangle();
    glPopMatrix(); // done with stack
    glutSwapBuffers(); 
}

// handles mouse click events
// button will say which button is presed, e.g. GLUT_LEFT_BUTTON, GLUT_RIGHT_BUTTON
// state will say if the button is GLUT_UP or GLUT_DOWN
// x and y are the poitner position 
void mouse_click(int button, int state, int x, int y)
{
    if (button==GLUT_LEFT_BUTTON)
    {       
        std::cerr << "\t left mouse button pressed!" << std::endl;

        if (state==GLUT_UP)
        {
            std::cerr << "\t button released...click finished" << std::endl;

            g_cursor_x = x;
            g_cursor_y = y;

            std::cerr << "\t cursor at (" << g_cursor_x << ", " << 
                                             g_cursor_y << ")" << std::endl;
        }

    }
    else
    if (button==GLUT_RIGHT_BUTTON)
    {
        std::cerr << "\t right mouse button pressed!" << std::endl;
    }

// Here is my attempt:
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) 
    {
        float x_min = (-x+500)/512;
        float x_max = (x-500)/512;
        float y_min = (-y+500)/512;
        float y_max = (y-500)/512;
        gluOrtho2D(x_min, x_max, y_min, y_max);
        //glTranslatef(x/512, 1-y/512, 0.0f);
            std::cerr << x << ", " << y << std::endl;
    }
    glutPostRedisplay();
}

void mouse_motion(int x, int y)
{
    std::cerr << "\t mouse is at (" << x << ", " << y << ")" << std::endl;
    glutPostRedisplay();
}


// will get which key was pressed and x and y positions if required
void keyboard(unsigned char key, int, int)
{
    std::cerr << "\t you pressed the " << key << " key" << std::endl;

    switch (key)
    {
        case 'q': exit(1); // quit!

        // clockwise rotate
        case 'r': g_angle += g_angle_step; break;
    }

    glutPostRedisplay(); // force a redraw
}

// any special key pressed like arrow keys
void special(int key, int, int)
{
    // handle special keys
    switch (key)
    {
        case GLUT_KEY_LEFT: g_xoffset -= g_offset_step; break;
        case GLUT_KEY_RIGHT: g_xoffset += g_offset_step; break;
        case GLUT_KEY_UP: g_yoffset += g_offset_step; break;
        case GLUT_KEY_DOWN: g_yoffset -= g_offset_step; break;
    }

    glutPostRedisplay(); // force a redraw
}

void init()
{
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity();
    gluOrtho2D(0, 1000, 0, 1000);
    glClearColor(0.0f, 0.0f, 1.0f, 0.0f); 

    g_cursor_x = g_cursor_y = 500; // middle of window
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA); 
    glutInitWindowSize(512, 512); 
    glutInitWindowPosition(50, 50); 
    glutCreateWindow("Mouse Test"); 
    glutDisplayFunc(display); 

    // handlers for keyboard input
    glutKeyboardFunc(keyboard); 
    glutSpecialFunc(special); 

    // mouse event handlers
    glutMouseFunc(mouse_click); 
    glutPassiveMotionFunc(mouse_motion); 

    init(); 
    glutMainLoop(); 

    return 0; 
}

1 个答案:

答案 0 :(得分:1)

这应该可以解决您的问题。使用下面的代码替换您的代码(您的尝试)。

 if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) 
 { 

    g_xoffset = x;
    g_yoffset = 1000-y;

   } glutPostRedisplay();