前序

前段时间学习3D MAX,一对比就发现差距是相当大。我也做了一个三维展示的小软件,但是拖拽操作非常不友好,如果场景的尺寸特别大,会导致拖不动,尺寸过小会导致轻轻拖一下,模型就不知道飞哪去了。我是每次鼠标移动都是让模型移动相同的距离,所以就出现了这种情况。下面就简单说一下,怎么做到模型跟随鼠标移动,就像鼠标抓着模型到处甩的效果。

方法



我们在设置OpenGL的投影矩阵的时候,需要设置近平面和远平面,这里,BP和DQ分别表示近平面和远平面。除此外,我们还需要设置摄像机的位置,这里我们用A点代表摄像机,摄像机的角度为2θ,假设观察的物体位于CF平面上,我们的屏幕分辨率是X * Y,OpenGL的视口长宽设置为屏幕大小,那么,我们可以很容易的算出物体所在表面的高度CF = tanθ * AC。如果鼠标在纵向拖动的像素距离为ybits,那么相应的物体需要在Y轴方向移动的距离ydistance = ybits / Y * CF = ybits / Y * AC * tanθ。现在只要能取到AC的长度就能算出物体需要移动的距离。

深度缓冲

在OpenGL中我们可以通过获取鼠标所在点的深度值,然后通过gluUnProject函数就能得到这个点所在的z轴坐标。

int winX, winY;     //winX和winY分别是窗口的xy坐标
double x, y, z; //鼠标所在点在OpenGL坐标系中的坐标
float depth; //鼠标点所在的深度值
int viewport[4]; //视口数据
double mvMatrix[16], projectMatrix[16]; //当前的modelview矩阵和projection矩阵 glGetIntegerv(GL_VIEWPORT, viewport); //获取当前视口
glGetDoublev(GL_MODELVIEW_MATRIX, mvMatrix); //获取当前的modelview矩阵
glGetDoublev(GL_PROJECTTION_MATRIX, projectMatrix); //获取当前的projection矩阵 //鼠标当前的坐标为mouseX, mouseY, 均为int类型
winX = mouseX;
winY = viewport[3] - mouseY; //Windows上的点坐标远点位于屏幕左上角
glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, &depth); //获取深度,保存于depth
//gluUnProject(x坐标,y坐标,深度,modelview矩阵,projection矩阵,OpenGL的x坐标,OpenGL的y坐标,OpenGL的z坐标)
gluUnProject((GLdouble)winX, (GLdouble)winY, (GLdouble)depth, mvMatrix, projectMatrix, &x, &y, &z);

最后的计算

知道了鼠标点在OpenGL坐标系的具体坐标后,可以通过摄像机的坐标与点坐标之间运算,得到一个大概的移动距离(通过屏幕坐标反算OpenGL坐标会有误差)

OpenGL鼠标拖拽的更多相关文章

  1. CSharpGL(20)用unProject和Project实现鼠标拖拽图元

    CSharpGL(20)用unProject和Project实现鼠标拖拽图元 效果图 例如,你可以把Big Dipper这个模型拽成下面这个样子. 配合旋转,还可以继续拖拽成这样. 当然,能拖拽的不只 ...

  2. JavaScript鼠标拖拽特效及相关问题总结

    #div1{width:200px;height:200px;background:red;position:absolute;} #div2{width:200px;height:200px;bac ...

  3. 一款基于jQuery的支持鼠标拖拽滑动焦点图

    记得之前我们分享过一款jQuery全屏广告图片焦点图,图片切换效果还不错.今天我们要分享另外一款jQuery焦点图插件,它的特点是支持鼠标拖拽滑动,所以在移动设备上使用更加方便,你只要用手指滑动屏幕即 ...

  4. 【狼】unity 鼠标拖拽物体实现任意角度自旋转

    主要涉及函数 Input.GetAxis(“Mouse x”) 可取得鼠标横向(x轴)移动增量 Input.GetAxis(“Mouse y”) 可取得鼠标竖向(y轴)移动增量 通过勾股定理获取拖拽长 ...

  5. NGUI对象跟随鼠标拖拽移动

    public Camera WNGUICamera; Vector3 _WoldPosition;//指针的初始位置 // Vector3 _WoldAng; Vector3 WscreenSpace ...

  6. 鼠标拖拽定位和DOM各种尺寸详解

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. Arcgis for qml - 鼠标拖拽移动

    以实现鼠标拖拽文本图层为例 GitHub:ArcGIS拖拽文本 作者:狐狸家的鱼 目的是利用鼠标进行拖拽. 实现两种模式,一种是屏幕上的拖拽,第二种是地图上图层的挪动. 屏幕上的拖拽其实跟ArcGIS ...

  8. html5的鼠标拖拽

    鼠标拖拽 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  9. javascript鼠标拖拽的那些事情

    <html> <head> <title>javascript鼠标拖拽的那些事情</title> <meta http-equiv="C ...

随机推荐

  1. super、this

    1)super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句) 2)this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句) 3)super: 它引用当前对 ...

  2. SuperMap iClient 查询成功后如何传递参数?

    一.iClient API文档中的接口描述 二.范例 //定义一个this对象 this.param = new SuperMap.LonLat(point.x, point.y); querySer ...

  3. Python开发简单爬虫(二)---爬取百度百科页面数据

    一.开发爬虫的步骤 1.确定目标抓取策略: 打开目标页面,通过右键审查元素确定网页的url格式.数据格式.和网页编码形式. ①先看url的格式, F12观察一下链接的形式;② 再看目标文本信息的标签格 ...

  4. 【RabbitMQ系列】队列、绑定、交换器

    队列: 从概念上来讲,AMQP消息路由必须有三部分:交换器.队列和绑定.生产者把消息发布到交换器上:消息最终到达队列,并被消费者接收:绑定决定了消息如何从路由器路由到特定的队列. 消费者通过以下两种方 ...

  5. 基础补充:使用xlrd模块读取excel文件

    因为接口测试用例使用excel文件来维护的,所以有必要学习下操作excel的基本方法 参考博客:python 3 操作 excel 把自己练习的代码贴出来,是一些基本的操作,每行代码后面都加了注释. ...

  6. 利用拷贝data目录文件的方式迁移mysql数据库

    其实迁移数据库,一般用sql文件就行,把A服务器数据库的表结构和数据等等导出,然后导入到B服务器数据库, 但是这次数据文件过大,大约有40个G,使用命令行导入,效果不是很好,经常在执行过程中报错.卡死 ...

  7. [福大软工] W班 团队第一次作业—团队展示成绩公布

    作业地址 https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1715W/homework/906 作业要求 根据已经组队的队伍组成, 每 ...

  8. LeetCode---Container With Most Water(11)

    Description: Given n non-negative integers a1, a2, ..., an, where each represents a point at coordin ...

  9. bisect 二分查找

    先说明的是,使用这个模块的函数前先确保操作的列表是已排序的. 先看看 insort  函数: 其插入的结果是不会影响原有的排序. 再看看 bisect  函数: 其目的在于查找该数值将会插入的位置并返 ...

  10. Tornado websocket应用

    应用场景 WebSocket 的特点如下 适合服务器主动推送的场景(好友上线,即时聊天信息,火灾警告,股票涨停等) 相对于Ajax和Long poll等轮询技术,它更高效,不耗费网络带宽和计算资源 它 ...