原作:航空機
オリジナルリンクします。https://www.cnblogs.com/DOMLX/p/11620088.html
はじめに:
次のプロジェクトは、複数の3Dモデルを読み込み、ステッチを移動する必要があるので、私は踏み台にお互いを乱すことなく移動するために、マウスの制御に2つのオブジェクトを実装しようとしたので。
マウス制御機能を用意します
私たちは、その後、必然的に私たちはラインで直接使用するために使用され、それがマウス制御機能の内部で非常に良いopenglのされている、マウスイベントを制御するための応答関数を必要とし、マウスに関する情報を取得する必要があります。
glutMouseFunc( (void*)Func(int button, int state, int x, int y) );
glutMouseFunc
这个是调用鼠标函数的入口,func是我们给鼠标处理函数的命名, 三个参数分别是鼠标响应的事件类型,比如左键点击,右键点击之类,x,y则是当前鼠标在窗口的位置坐标。
下面这个是处理鼠标移动时候的调用函数
glutMotionFunc(&func(int x,inty)); // 鼠标移动的时候的函数 x,y当前鼠标坐标
反正调用起来非常的简单只要自己写好一个鼠标点击类事件处理函数和一个鼠标移动事件处理函数,然后传入进去就行了,调用函数放在main函数里。反正后面代码有。
比如:
// マウスの動きが 無効 ONMOUSEMOVE(int型 X、int型のY){ // マウスがその後の状態に押し込まれ決定される IF (mousetateが){ // 対応する法線ベクトルに対応するので、XがYである IF ==選択し(図1 ){ movX1 =(X - X1)/ WIDTH1; glutPostRedisplay(); movY1 = - ((Y -イル)/ height1); glutPostRedisplay(); STD :: COUT << " モバイル= X1 " << << X " = Y1 " << << Y STD :: ENDL; } 他の{ のstd :: coutの << " 選択しない" << はstd ::てendl; } であれば(==選択2 ){ movX2 =(X - X2)/ 幅2。 glutPostRedisplay(); movY2 = - ((Y - Y 2)/ 身長2)。 glutPostRedisplay(); std :: COUT << " 移动X2 = " << X << " Y2 = " << Y << はstd :: ENDL。 } 他{ STD ::ないことを選択し、「 << ;のstd ::てendl } } } glutMotionFunc(&ONMOUSEMOVE); // 関数呼び出しマウスが移動したとき
II。マウスイベントにいくつかの応答
もし(状態== GLUT_DOWN)//同等の"マウスボタンが押された場合、"
IF(状態== GLUT_UP)//同等の"マウスボタンが離された場合、"
IF(ボタン== GLUT_LEFT_BUTTON)/ /同等の「マウスボタンが解放されたり押された場合には、」
IF(ボタン== GLUT_RIGHT_BUTTON)//同等の「右マウスボタンが押されたり解放されている場合、」
IF(ボタン== GLUT_MIDDLE_BUTTON)//同等「マウスボタンが押されたり解放されます。」
マウスホイールイベントがあります。
GLUT_WHEEL_UP
GLUT_WHEEL_DOWN
これら二つは時々新しいバージョンや、まだ解決されていない場合、直接ファイルのヘッダーに次のように定義されているの下に新しいバージョンでトラブルを望んでいない、それは古いバージョンの酒で、ライブラリーが定義されていない、自分のgultが発生する場合があります。
#define GLUT_WHEEL_UP 3 //ホイール操作の定義
の#define GLUT_WHEEL_DOWN 4
III。実施プロセスの紹介
まず、我々は複数のオブジェクトを描きたい、これはそれについて話をしないエントリです。
第二に、我々は、我々は、マウスの動きにオブジェクトを移動するために、マウスを押したままにすると、オブジェクトを選択し、マウスをクリックします。マウスクリックを保持することは、この領域におけるマウスクリックは、我々は、オブジェクトが決定された選択されたときにオブジェクトが、中心点が矩形領域の辺の長さdに調整することができる範囲を選択します。
2つのオブジェクトが重なっている場合、我々は最初の描画オブジェクトが移動を選択することを好みます。
その後、質問はなった後、オブジェクトを選択し、オブジェクトは、それを移動するために、マウスを達成するためにどのように私たちに従ってください?
非常に単純な、水平方向に限り、マウスを変更座標に移動し、オブジェクトの幅または長さで割った移動前の座標を減算しているように、法線ベクトルは、動きを得られます。movX1 =(X - X1)/ WIDTH1。
垂直方向、同様に使用可能movY1 = - ((Y - Y1)/ height1);なぜ、より負の数ここで、下方への移動が正方向、負であるためです。
そして、法線ベクトルを変更するために移動した後に移動するので、プログラムはウィンドウを一度再描画を呼び出します。瞬きが発生した場合は、ダブルバッファリングを使用することができます。
マウスクリックイベント処理コード:
// 鼠标交互
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(); }