OpenGl achieve a plurality of objects are moving the mouse ---------- a moving object does not move to another object - to read a plurality of pre-operation stepping stone model 3d

Original author: aircraft

Original link: https: //www.cnblogs.com/DOMLX/p/11620088.html

 

 

 

Preface:

  Because the next project needs to read multiple 3D models, and move stitching, so I tried to implement mouse control two objects to move without disturbing each other as a stepping stone.

 

 

 

A mouse control function prepares

  We need to get information on the mouse, then inevitably require a response function to control the mouse event, it has been very good opengl inside the mouse control function, we used to use directly on the line.

 

glutMouseFunc( (void*)Func(int button, int state, int x, int y) );
glutMouseFunc这个是调用鼠标函数的入口,func是我们给鼠标处理函数的命名, 三个参数分别是鼠标响应的事件类型,比如左键点击,右键点击之类,x,y则是当前鼠标在窗口的位置坐标。

下面这个是处理鼠标移动时候的调用函数
glutMotionFunc(&func(int x,inty)); // 鼠标移动的时候的函数 x,y当前鼠标坐标

反正调用起来非常的简单只要自己写好一个鼠标点击类事件处理函数和一个鼠标移动事件处理函数,然后传入进去就行了,调用函数放在main函数里。反正后面代码有。

比如:
// mouse motion 
void the onMouseMove ( int X, int y) {
     // when the mouse is pressed into the subsequent state is determined 
    IF (mousetate) {
         // X is y because the corresponding normal vector corresponding to the 
        IF (the Choose == . 1 ) { 
            movX1 = (X - X1) / width1; 
            glutPostRedisplay (); 
            movY1 = - ((Y - Yl) / height1); 
            glutPostRedisplay (); 
            STD :: COUT << " mobile = X1 " << << X " = Y1 " << << Y STD :: endl; 
        }
        else {
            std::cout << "not choose" << std::endl;
        }
        if (choose == 2) {
            movX2 = (x - x2) / width2;
            glutPostRedisplay();
            movY2 = -((y - y2) / height2);
            glutPostRedisplay();
            std::cout << " 移动 x2 = " << x << " y2 = " << y << std::endl;
        }
        else {
            std::cout << "the Choose not " << std :: endl; 
        } 
    } 
} 




glutMotionFunc ( & onMouseMove); // function call when the mouse is moved

 

II. Some respond to mouse events

if (state == GLUT_DOWN) // equivalent "if a mouse button is pressed"
IF (State == GLUT_UP) // equivalent "if a mouse button is released,"
IF (Button == GLUT_LEFT_BUTTON) / / equivalent "if the mouse button has been pressed is released or"
IF (Button == GLUT_RIGHT_BUTTON) // equivalent "if the right mouse is pressed or released"
IF (Button == GLUT_MIDDLE_BUTTON) // equivalent "If the mouse button is pressed or is released."

There are mouse wheel events

GLUT_WHEEL_UP  

GLUT_WHEEL_DOWN

These two may sometimes encounter their own gult library is not defined, it is the older version's sake, do not want trouble under the new version or a new version under still not been resolved, then directly in the file header is defined like this:

#define GLUT_WHEEL_UP 3 // define a wheel operation
#define GLUT_WHEEL_DOWN 4

 

III. Implementation process Introduction

  First, we want to draw multiple objects, then this is the entry not talk about it.

  Secondly, we want to click the mouse to select an object, when we hold down the mouse to move objects with our mouse movement. Holding the mouse click to select the range that the object may be a center point coordinates to a side length d of the rectangular area, when the mouse clicks in this region, we selected the object is determined.

  When two objects overlap, we prefer to select the first draw object moves.

 

  After then the question becomes, select the object, the object Follow us on how to achieve the mouse to move it?

  Very simple, in the horizontal direction, as long as the mouse is moved to the changed coordinates and then subtracting the coordinates before the movement divided by the width or length of the object, the normal vector is obtained movement. movX1 = (x - x1) / width1;

  The vertical direction, Similarly available movY1 = - ((y - Y1) / height1); Why more negative numbers here, because the downward movement is negative, a positive direction.

  

  Then move after move to change the normal vector, so the program calls the window redraw once. If the blinking occurs, you can use double buffering.

 

Mouse click event-handling code:

 

// 鼠标交互
void myMouse(int button, int state, int x, int y)
{    //鼠标左键按下或者松开
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
        mousetate = 1;
        if (!choose) {
            if (x<(x1 + chooseWidth) && x>(x1 - chooseWidth)) {
                if (y<(Y1 + chooseHeight) && y>(Y1 - chooseHeight)) {
                    x1 = 400;
                    Y1 = 400;
                    movX1 = (x - x1) / width1;
                    movY1 = -((y - Y1) / height1);
                    choose = 1;
                }
            }
            else if (x<(x2 + chooseWidth) && x>(x2 - chooseWidth)) {
                if (y<(y2 + chooseHeight) && y>(y2 - chooseHeight)) {
                    x2 = 400;
                    y2 = 400;
                    movX2 = (x - x2) / width2;
                    movY2 = -((y - y2) / height2);
                    choose = 2;
                }
            }
            
        }
        std::cout << "x = " << x << " y = " << y << std::endl;
    }
    if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
        if (choose == 1) {
            x1 += (movX1*width1);
            Y1 += -(movY1*height1);
        }
        if (choose == 2) {
            x2 += (movX2*width2);
            y2 += -(movY2*height2);
        }
        mousetate = 0;
        choose = 0;
        std::cout << "x = " << x1 << " y = " << Y1 << std::endl;
    }
        
    //滚轮事件
    //scale 增加就是放大 减小就是缩小
    //currentfile 对不同的模型用不用的scale
    if (state == GLUT_UP && button == GLUT_WHEEL_UP) {
        
    }
    else scale = 0.2;
    if (state == GLUT_UP && button == GLUT_WHEEL_DOWN) {
        
    }
    else scale = 0.2;
    //glutPostRedisplay();//促使主程序尽快的重绘窗口
}

 

 

 

鼠标移动处理程序代码:
// 鼠标运动时
void onMouseMove(int x, int y) {
    //当鼠标状态为按下时进入后续判断
    if (mousetate) {
        //x对应y是因为对应的是法向量
        if (choose == 1) {
            movX1 = (x - x1) / width1;
            glutPostRedisplay();
            movY1 = -((y - Y1) / height1);
            glutPostRedisplay();
            std::cout << " 移动 x1 = " << x << " y1 = " << y << std::endl;
        }
        else {
            std::cout << "not choose" << std::endl;
        }
        if (choose == 2) {
            movX2 = (x - x2) / width2;
            glutPostRedisplay();
            movY2 = -((y - y2) / height2);
            glutPostRedisplay();
            std::cout << " 移动 x2 = " << x << " y2 = " << y << std::endl;
        }
        else {
            std::cout << "not choose" << std::endl;
        }
    }
}

 

我们预览程序运行,分别控制两个正方体的移动。

移动前:

 

 

移动后:

 

 

这个就是我们本文实现的内容,后面就可以用于读取多个3d模型分别进行移动。

 

项目完整代码,配置好Opengl环境可以直接运行,更多项目分享以及学习教程,请关注在下!!!!:

#include <GL/glut.h>
#include <iostream>

// 绘制立方体


// 将立方体的八个顶点保存到一个数组里面 

static GLfloat vertex_list[][3] = {
    -0.5f, -0.5f, -0.5f,
     0.5f, -0.5f, -0.5f,
    -0.5f,  0.5f, -0.5f,
     0.5f,  0.5f, -0.5f,
    -0.5f, -0.5f,  0.5f,
     0.5f, -0.5f,  0.5f,
    -0.5f,  0.5f,  0.5f,
     0.5f,  0.5f,  0.5f,
};

// 将要使用的顶点的序号保存到一个数组里面 

static GLint index_list[][4] = {
    0, 2, 3, 1,
    0, 4, 6, 2,
    0, 1, 5, 4,
    4, 5, 7, 6,
    1, 3, 7, 5,
    2, 6, 7, 3,
};

#define  GLUT_WHEEL_UP 3           //定义滚轮操作
#define  GLUT_WHEEL_DOWN 4

const int windowsWidth = 800;
const int windowsHeight = 800;
GLfloat scale = 0.2;

GLfloat movX1 = -1.0f, movX2 = 1.0f, movY1 = 0.0f, movY2 = 0.0f;
GLfloat width1 = (windowsWidth / 2.0)*scale,height1 = (windowsHeight / 2)*scale;
GLfloat width2 = (windowsWidth / 2)*scale, height2 = (windowsHeight / 2)*scale;
GLfloat x1 = (windowsWidth / 2)+(width1*movX1), x2 = (windowsWidth / 2) + (width1*movX2), Y1 = (windowsHeight / 2)+(height1*movY1), y2 = (windowsHeight / 2) + (height1*movY2), z1 = 0.0f, z2 = 0.0f;
GLfloat chooseWidth = 20,chooseHeight = 20;
GLfloat dx = 0, dy = 0;
bool mousetate = 0;
int choose = 0;
// 鼠标交互
void myMouse(int button, int state, int x, int y)
{    //鼠标左键按下或者松开
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
        mousetate = 1;
        if (!choose) {
            if (x<(x1 + chooseWidth) && x>(x1 - chooseWidth)) {
                if (y<(Y1 + chooseHeight) && y>(Y1 - chooseHeight)) {
                    x1 = 400;
                    Y1 = 400;
                    movX1 = (x - x1) / width1;
                    movY1 = -((y - Y1) / height1);
                    choose = 1;
                }
            }
            else if (x<(x2 + chooseWidth) && x>(x2 - chooseWidth)) {
                if (y<(y2 + chooseHeight) && y>(y2 - chooseHeight)) {
                    x2 = 400;
                    y2 = 400;
                    movX2 = (x - x2) / width2;
                    movY2 = -((y - y2) / height2);
                    choose = 2;
                }
            }
            
        }
        std::cout << "x = " << x << " y = " << y << std::endl;
    }
    if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
        if (choose == 1) {
            x1 += (movX1*width1);
            Y1 += -(movY1*height1);
        }
        if (choose == 2) {
            x2 += (movX2*width2);
            y2 += -(movY2*height2);
        }
        mousetate = 0;
        choose = 0;
        std::cout << "x = " << x1 << " y = " << Y1 << std::endl;
    }
        
    //滚轮事件
    //scale 增加就是放大 减小就是缩小
    //currentfile 对不同的模型用不用的scale
    if (state == GLUT_UP && button == GLUT_WHEEL_UP) {
        
    }
    else scale = 0.2;
    if (state == GLUT_UP && button == GLUT_WHEEL_DOWN) {
        
    }
    else scale = 0.2;
    //glutPostRedisplay();//促使主程序尽快的重绘窗口
}

// 鼠标运动时
void onMouseMove(int x, int y) {
    //当鼠标状态为按下时进入后续判断
    if (mousetate) {
        //x对应y是因为对应的是法向量
        if (choose == 1) {
            movX1 = (x - x1) / width1;
            glutPostRedisplay();
            movY1 = -((y - Y1) / height1);
            glutPostRedisplay();
            std::cout << " 移动 x1 = " << x << " y1 = " << y << std::endl;
        }
        else {
            std::cout << "not choose" << std::endl;
        }
        if (choose == 2) {
            movX2 = (x - x2) / width2;
            glutPostRedisplay();
            movY2 = -((y - y2) / height2);
            glutPostRedisplay();
            std::cout << " 移动 x2 = " << x << " y2 = " << y << std::endl;
        }
        else {
            std::cout << "not choose" << std::endl;
        }
    }
}

// 绘制立方体

void DrawCube(void)
{
    glPushMatrix();
    glFrontFace(GL_CCW);//逆时针
    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    int i, j;
    

    
    glBegin(GL_QUADS);
    
    //glBegin(GL_LINES);
    for (i = 0; i < 6; ++i) // 12 条线段

    {
        for (j = 0; j < 4; ++j) // 每条线段 2个顶点

        {
            glVertex3fv(vertex_list[index_list[i][j]]);
        }
    }
    glEnd();
    
    
}

static float rotate = 0;
static int times = 0;

void renderScene2(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glColor3f(0, 0, 1);
    glScalef(0.3, 0.3, 0.3);    // 缩放
    glPushMatrix();

    //glTranslatef(-0.2, 0, 0); // 平移

    //glScalef(2, 1, 1);    // 缩放


    times++;
    if (times > 100)
    {
        times = 0;
    }

    if (times % 100 == 0)
    {
        rotate += 0.3;
    }
    
    glPushMatrix();
    
    glTranslatef(-2, 0, 0); // 平移
    glRotatef(rotate, 0, 1, 0);
    glRotatef(rotate, 1, 0, 0);
    DrawCube();
    glPopMatrix();
    
    glTranslatef(2, 0, 0); // 平移
    glRotatef(rotate, 0, 1, 0);
    glRotatef(rotate, 1, 0, 0);
    //glScalef(0.5, 0.5, 0.5);    // 缩放
    DrawCube();
    
    glPopMatrix();
    glutSwapBuffers();
}
void renderScene(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    
    
    glScalef(scale, scale, scale);    // 缩放
    glPushMatrix();
    glColor3f(0, 0, 1);
    glTranslatef(movX1, movY1, 0);
    DrawCube();
    glPopMatrix();

    glPushMatrix();
    glColor3f(0, 1, 0);
    glTranslatef(movX2, movY2, 0);
    DrawCube();
    glPopMatrix();
    glutSwapBuffers();
}

void main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(windowsWidth, windowsHeight);
    glutCreateWindow("GLDemo");
    glutMouseFunc(&myMouse);        //鼠标点击处理函数
    glutMotionFunc(&onMouseMove); // 鼠标移动的时候的函数
    glutDisplayFunc(&renderScene);
    glutIdleFunc(&renderScene);

    glutMainLoop();
}

 

 

 

 

Guess you like

Origin www.cnblogs.com/DOMLX/p/11620088.html