前序

前段时间学习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. mysql学习第一天

    Mysql语句语法 一.数据库定义语句(DDL) 1.alter database 语法 alter database 用于更改数据库的全局特性,这些特性存储在数据库目录中的db.opt文件中.要使用 ...

  2. oracle维护数据的完整性

    介绍: 数据的完整性用于确保数据库数据遵从一定的商业的逻辑规则.在oracle中,数据完整性可以使用约束.触发器.应用程序(过程.函数)三种方法来实现,在这三种方法中,因为约束易于维护,并且具有最好的 ...

  3. codeforce round #467(div.2)

    A. Olympiad 给出n个数,让你找出有几个非零并且不重复的数 所以用stl的set //#define debug #include<stdio.h> #include<ma ...

  4. STL常用整理

    S T L Sting: << 判断拼音序 size length 字符串长度 str[n] 代表字符串中的一个字符 可用作左值 string::size_type 用于表示字符串长度计量 ...

  5. 利用python 创建XML文件

    #coding=utf-8 from xml.etree import ElementTree import pdb def printNodeInfo(node): #node.tag 标签名称 # ...

  6. 201421123042 《Java程序设计》第2周学习总结

    1. 本周学习总结 以几个关键词描述本周的学习内容.并将关键词之间的联系描述或绘制出来. 原则:少而精,自己写.即使不超过5行也可,但请一定不要简单的复制粘贴. 引用类型 引用类型是指向一个对象,感觉 ...

  7. Scala 操作符与提取器

    实际上Scala没有操作符, 只是以操作符的格式使用方法. 操作符的优先级取决于第一个字符(除了赋值操作符), 而结合性取决于最后一个字符 Scala的操作符命名更加灵活:) 操作符 中置操作符(In ...

  8. 为SRS流媒体服务器添加HLS加密功能(附源码)

    为SRS流媒体服务器添加HLS加密功能(附源码) 之前测试使用过nginx的HLS加密功能,会使用到一个叫做nginx-rtmp-module的插件,但此插件很久不更新了,网上搜索到一个中国制造的叫做 ...

  9. js 从一个函数中传递值到另一个函数

    一个函数的调用大家都会用 我今天在调接口的时候突然发现需要引用个另一个函数中拿到的值 举个栗子 刚开始 我是这样调用的 alert弹出的是 hello world . 但是我a函数内部还有一个函数 画 ...

  10. leetcode题解 6.ZigZag Conversion

    6.ZigZag Conversion 题目: The string "PAYPALISHIRING" is written in a zigzag pattern on a gi ...