OpenGL鼠标拖拽
前序
前段时间学习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鼠标拖拽的更多相关文章
- CSharpGL(20)用unProject和Project实现鼠标拖拽图元
CSharpGL(20)用unProject和Project实现鼠标拖拽图元 效果图 例如,你可以把Big Dipper这个模型拽成下面这个样子. 配合旋转,还可以继续拖拽成这样. 当然,能拖拽的不只 ...
- JavaScript鼠标拖拽特效及相关问题总结
#div1{width:200px;height:200px;background:red;position:absolute;} #div2{width:200px;height:200px;bac ...
- 一款基于jQuery的支持鼠标拖拽滑动焦点图
记得之前我们分享过一款jQuery全屏广告图片焦点图,图片切换效果还不错.今天我们要分享另外一款jQuery焦点图插件,它的特点是支持鼠标拖拽滑动,所以在移动设备上使用更加方便,你只要用手指滑动屏幕即 ...
- 【狼】unity 鼠标拖拽物体实现任意角度自旋转
主要涉及函数 Input.GetAxis(“Mouse x”) 可取得鼠标横向(x轴)移动增量 Input.GetAxis(“Mouse y”) 可取得鼠标竖向(y轴)移动增量 通过勾股定理获取拖拽长 ...
- NGUI对象跟随鼠标拖拽移动
public Camera WNGUICamera; Vector3 _WoldPosition;//指针的初始位置 // Vector3 _WoldAng; Vector3 WscreenSpace ...
- 鼠标拖拽定位和DOM各种尺寸详解
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Arcgis for qml - 鼠标拖拽移动
以实现鼠标拖拽文本图层为例 GitHub:ArcGIS拖拽文本 作者:狐狸家的鱼 目的是利用鼠标进行拖拽. 实现两种模式,一种是屏幕上的拖拽,第二种是地图上图层的挪动. 屏幕上的拖拽其实跟ArcGIS ...
- html5的鼠标拖拽
鼠标拖拽 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- javascript鼠标拖拽的那些事情
<html> <head> <title>javascript鼠标拖拽的那些事情</title> <meta http-equiv="C ...
随机推荐
- [poj3904]Sky Code_状态压缩_容斥原理
Sky Code poj-3904 题目大意:给你n个数,问能选出多少满足题意的组数. 注释:如果一个组数满足题意当且仅当这个组中有且只有4个数,且这4个数的最大公约数是1,$1\le n\le 10 ...
- linux小白成长之路4————centos7配置自动更新安装安全补丁
[内容指引] 安装yum-cron; 修改配置:nano: 手工启动服务: 将服务设置为开机自动启动. 为保证linux系统的安全性以及稳定性,可以使用yum-cron服务自动更新: 1.安装yum- ...
- TensorFlow-谷歌深度学习库 用tfrecord写入读取
TensorFlow自带一种数据格式叫做tfrecords. 你可以把你的输入转成专属与TensorFlow的tfrecords格式并保存在本地. -关于输入碎碎念:输入比如图片,可以有各种格式呀首先 ...
- oralce数据库常用到的一些sql命令(加字段注释,修改数据之类)
最近开始接触oralce,整理了一下最近使用 pl/sql 常用到的一些sql命令 1.修改表中的数据 编写查询语句及条件,然后加上"FOR UPDATE","FOR U ...
- python 堆排序
堆排序就是把堆顶的最大数取出, 将剩余的堆继续调整为最大堆,具体过程在第二块有介绍,以递归实现 剩余部分调整为最大堆后,再次将堆顶的最大数取出,再将剩余部分调整为最大堆,这个过程持续到剩余数只有一个时 ...
- AWS中,如果使用了ELB,出现outofservice
平台:亚马逊AWS EC2 出现状况: 我创建了弹性平衡负载,也注册了实例,但是实例的状态一直是outofservice.为什么? 为什么会出现这个问题呢? 1:实例有问题: 2:负载平衡器创建的有问 ...
- 日志 --BUG记录
2014-12-15日 在做520wawa的免费推广 部署web应用时 错把path设置为"/*",导致启动tomcat时,导致错误 <Context path=&quo ...
- 从一次输入框无法输入的bug,谈如何限制输入框输入类型
bug的产生和修改 上周临近周末休息的时候,一个同事跑过来了,对我说:"阿伦啊,有一个页面出问题了,火狐浏览器所有的input都没法输入了."我一听,是不是你给加了什么属性,让in ...
- MSSQL 2000 错误823恢复
一.故障描述 MSSQL Server 2000 附加数据库错误823,附加数据库失败.数据库没有备份,不能通过备份恢复数据库,急需恢复数据库中的数据. 二.故障分析SQL Server数据库 823 ...
- DELL EqualLogic PS存储硬盘故障数据恢复成功案例分享
DELL EqualLogic PS4000采用虚拟ISCSI SAN阵列,为远程或分支办公室.部门和中小企业存储部署带来企业级功能.智能化.自动化和可靠性.以简化的管理.快速的部署及合理的价格满足了 ...