用鼠标单击 OpenGL 拖动 3d 对象
Posted
技术标签:
【中文标题】用鼠标单击 OpenGL 拖动 3d 对象【英文标题】:3d Object Dragging with mouse click OpenGL 【发布时间】:2018-11-15 03:26:02 【问题描述】:我正在尝试左键单击并拖动任何 3d 对象,如果我放开它,它应该保持在新位置,我将如何实现这一点? 3d 对象是从头文件中的绘图函数加载的。
有人说我应该使用 glutMouseFunc 或 glutMotionFunc。
void MouseClickCallbackFunction(int button, int state, int x, int y)
if (state == GLUT_DOWN)
if (button == GLUT_LEFT)
std::cout << "Left " << x << " " << y <<std::endl;
leftClick.x = x;
leftClick.y = y;
else if (button == GLUT_RIGHT_BUTTON)
std::cout << "Right " << x << " " << y << std::endl;
rightClick.x = x;
rightClick.y = y;
theGame->mouseClicked(button, state, x, y);
glutPostRedisplay();
/* function MouseMotionCallbackFunction()
* Description:
* - this is called when the mouse is clicked and moves
*/
void MouseMotionCallbackFunction(int x, int y)
theGame->mouseMoved(x, y);
glutPostRedisplay();
int main(int argc, char **argv)
/* initialize the window and OpenGL properly */
glutInit(&argc, argv);
glutInitContextVersion(4, 2);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("OpenGL Framework");
glewExperimental = true;
if (glewInit() != GLEW_OK)
std::cout << "GLEW could not be initialized. \n";
system("pause");
return 0;
//glewInit();
std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl;
/* set up our function callbacks */
glutDisplayFunc(DisplayCallbackFunction);
glutKeyboardFunc(KeyboardCallbackFunction);
glutKeyboardUpFunc(KeyboardUpCallbackFunction);
glutMouseFunc(MouseClickCallbackFunction);
glutMotionFunc(MouseMotionCallbackFunction);
glutTimerFunc(1, TimerCallbackFunction, 0);
/* init the game */
theGame = new Game();
theGame->initializeGame();
/* start the game */
glutMainLoop();
return 0;
这是绘制对象的函数
void Game::draw()
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
PassThrough.Bind();
PassThrough.SendUniformMat4("uModel", MonkeyTransform.data, false);
PassThrough.SendUniformMat4("uView", CameraTransform.GetInverse().data, false);
PassThrough.SendUniformMat4("uProj", CameraProjection.data, false);
PassThrough.SendUniform("uTex", 0);
PassThrough.SendUniform("LightPosition", CameraTransform.GetInverse() * vec4(4.0f,0.0f,0.0f,1.0f));
PassThrough.SendUniform("LightAmbient", vec3(0.15f, 0.15f, 0.15f));
PassThrough.SendUniform("LightDiffuse", vec3(0.7f,0.1f,0.2f));
PassThrough.SendUniform("LightSpecular", vec3(0.8f,0.1f,0.1f));
PassThrough.SendUniform("LightSpecularExponent", 50.0f);
PassThrough.SendUniform("Attenuation_Constant", 1.0f);
PassThrough.SendUniform("Attenuation_Linear", 0.1f);
PassThrough.SendUniform("Attenuation_Quadratic", 0.01f);
glBindVertexArray(Monkey.VAO);
glDrawArrays(GL_TRIANGLES, 0, Monkey.GetNumVerticies());
glBindVertexArray(0);
PassThrough.unBind();
glutSwapBuffers();
【问题讨论】:
看看这个Compute objects moving with arrows and mouse 【参考方案1】:这个概念叫做鼠标拾取。实现这一点的一种方法是光线投射。本质上,您要做的是将鼠标坐标映射到场景中的某个区域。在您的情况下,您想检查该位置是否在猴子内。那么就如同处理鼠标上、下、移动事件一样简单。
鼠标按下:检查对象是否被拾取。如果是,那就太好了——也许突出显示它或其他东西。将参考存储到选取的对象;存储鼠标在拾取开始时的位置(pos)
鼠标移动:鼠标按下了吗?是拾取的对象参考吗?根据鼠标移动事件中 pos 和 coord 之间的增量更新对象位置
鼠标上移:清除拾取的 obj ref、位置
此链接可能感兴趣http://antongerdelan.net/opengl/raycasting.html
【讨论】:
我将如何用代码实现这个?有什么例子吗? 我找到了另一个可能对您有帮助的答案:***.com/questions/25861374/…以上是关于用鼠标单击 OpenGL 拖动 3d 对象的主要内容,如果未能解决你的问题,请参考以下文章
虚拟仿真Unity3D中实现鼠标的单击双击拖动的不同状态判断