我是靠谱客的博主 热心冬日,最近开发中收集的这篇文章主要介绍OpenGL三维坐标与二维坐标:gluProject 和 gluUnproject 的详解 简介:,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
简介:
三维空间中,经常需要将3D空间中的点转换到2D(屏幕坐标),或者将2D点转换到3D空间中。当你使用OpenGL的时候,简单使用gluProject()和gluUnproject()函数就可以实现这个功能了。但这两个神奇的函数是怎样实现的,一直困扰着我,经过一番仔细研究,将自己的思路写在这里:
gluPorject()
先通过看代码,来一步一步分析它的数学原理吧!(其实代码是次要的,数学原理在这里才是关键所在!)这里的代码据说是赖在mesa OpenGL中的!
PS:这里为了更好理解,我修改了一下里面的代码,但没有兼顾效率的!
[cpp]
view plain
copy
[cpp]
view plain
copy
-
- static
void transform_point(GLdouble out[4] , const GLdouble m[16], const GLdouble in[4]) - {
- #define
M(row,col) m[col*4+row] -
out[0] = M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3]; -
out[1] = M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3]; -
out[2] = M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3]; -
out[3] = M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3]; - #undef
M - }
-
- GLint
gluProject(GLdouble objx, GLdouble objy, GLdouble objz -
, const GLdouble model[16], const GLdouble proj[16], const GLint viewport[4] -
, GLdouble * winx, GLdouble * winy, GLdouble * winz) - {
-
-
GLdouble objCoor[4]; -
GLdouble objProj[4], objModel[4]; -
-
-
// 4x4 matrix must be multi to a 4 dimension vector( it a 1 x 4 matrix) -
// so we need to put the original vertex to a 4D vector -
objCoor[0] = objx; -
objCoor[1] = objy; -
objCoor[2] = objz; -
objCoor[3] = 1.0; -
-
// 由于原来的向量位于标准基向量(1, 0, 0), (0, 1, 0), (0, 0, 1)中,所以需要先转换到当前的模型矩阵中 -
transform_point(objModel, model, objCoor); -
-
// 然后将模型矩阵中的顶点转换到投影矩阵所在坐标系的矩阵中 -
transform_point(objProj, proj, objModel); -
-
// scale matrix -
-
-
-
if (objProj[3] == 0.0) -
return GL_FALSE; -
-
objProj[0] /= objProj[3]; -
objProj[1] /= objProj[3]; -
objProj[2] /= objProj[3]; -
-
-
// 由于投影矩阵投影在[-1, 1]之间,所以需要将转换后的投影坐标放置到[0, 1]之间 -
// 最后再在一个offset 矩形中转换为屏幕坐标就可以了(viewport[4]可以简单的认为一个offset矩形) -
- #define
SCALE_FROM_0_TO_1(_pt) (((_pt) + 1)/2) -
objProj[0] = SCALE_FROM_0_TO_1(objProj[0]); -
objProj[1] = SCALE_FROM_0_TO_1(objProj[1]); -
objProj[2] = SCALE_FROM_0_TO_1(objProj[2]); - #undef
SCALE_FROM_0_TO_1 -
-
*winx = viewport[0] + objProj[0] * viewport[2]; -
*winy = viewport[1] + objProj[1] * viewport[3]; -
-
-
*winz = objProj[2]; -
return GL_TRUE; - }
[cpp]
view plain
copy
基本的思路就是:
1、将输入的顶点,通过模型视图矩阵,变换到模型视图矩阵的坐标系中;
2、将模型视图矩阵中的顶点,再变换到投影矩阵中;
3、将顶点缩放到[0, 1]的映射区间中;
4、通过视口的位置和大小,计算出当前3D顶点中的屏幕坐标(2D坐标)
gluUnproject
其实gluUnproject和gluProject是非常类似的,代码我暂时没有去找,但我认为应该是这样的(其实就是gluPorject反过来的过程,只是有一些数学运算要注意一下):
1、首先,需要将输入的顶点,通过视口变换到[0, 1]之间;
2、然后将顶点缩放到[-1, 1]之间,就是上面代码中的scaleMat矩阵的逆矩阵
3、然后乘上投影矩阵的逆矩阵;
4、最后就是乘上模型视图矩阵的逆矩阵;
最后
以上就是热心冬日为你收集整理的OpenGL三维坐标与二维坐标:gluProject 和 gluUnproject 的详解 简介:的全部内容,希望文章能够帮你解决OpenGL三维坐标与二维坐标:gluProject 和 gluUnproject 的详解 简介:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复