Project和unProject两个函数的执行结果是完全相反的。
Project是把模型坐标系上的点,经过视图矩阵、模型矩阵、投影矩阵转换到窗口屏幕坐标系上。unProject是把窗口屏幕上的点,经过视图矩阵、模型矩阵、投影矩阵逆转换到模型坐标系上。
Project(double objx, double objy, double objz, double[] modelMatrix, double[] projMatrix, int[] viewport, double[] winx, double[] winy, double[] winz):
其中:
(objx,objy,objz):是OpenGL的世界坐标系坐标;
modelMatrix:是当前OpenGL采用的模型矩阵;
projMatrix:是当前OpenGL采用的投影矩阵;
viewport:是当前OpenGL采用的视图矩阵;
(winx[0],winy[0]):是OpenGL世界坐标系点映射到屏幕坐标系的像素坐标;
winz[0]:是屏幕坐标点对应的像素深度;
UnProject(double winx, double winy, double winz, double[] modelMatrix, double[] projMatrix, int[] viewport, ref double objx, ref double objy, ref double objz):
其中:
(winx,winy):是当前屏幕坐标,注意:以左下角为零点;
winz:是当前屏幕坐标点深度,该值可通过ReadPixels方法读取当前点位像素深度;
modelMatrix:是当前OpenGL采用的模型矩阵;
projMatrix:是当前OpenGL采用的投影矩阵;
viewport:是当前OpenGL采用的视图矩阵;
(objx,objy,objz):是屏幕坐标映射到OpenGL世界坐标系下对应的坐标;
OpenGL的矩阵数据获取:
int[] Viewport = new int[4];//视图矩阵
double[] ModelView_Matrix = new double[16];//模型矩阵
double[] Project_Matrix = new double[16];//投影矩阵
OpenGL gl = this.openGLControl1.OpenGL;
gl.GetInteger(OpenGL.GL_VIEWPORT, Viewport);
gl.GetDouble(OpenGL.GL_MODELVIEW_MATRIX, ModelView_Matrix);
gl.GetDouble(OpenGL.GL_PROJECTION_MATRIX, Project_Matrix);
关于,ReadPixels的屏幕坐标系winz深度值获取:
var array = new float[1];//存储ReadPixels读取的深度参数
GCHandle pinned = GCHandle.Alloc(array, GCHandleType.Pinned);
IntPtr winz = pinned.AddrOfPinnedObject();
gl.ReadPixels((int)wx[0], (int)wy[0], 1, 1, OpenGL.GL_DEPTH_COMPONENT, OpenGL.GL_FLOAT, winz);//获取鼠标所在位置的像素深度
pinned.Free();
gl.UnProject((double)e.X, (double)Viewport[3] - e.Y, (double)array[0], ModelView_Matrix, Project_Matrix, Viewport, ref xpos, ref ypos, ref zpos);
//(xpos,ypos,zpos)是屏幕坐标映射到OpenGL世界坐标系点位坐标
其中:
ReadPixels(int x, int y, int width, int height, uint format, uint type, IntPtr pixels);
ReadPixels(int x, int y, int width, int height, uint format, uint type, byte[] pixels);
format能够读取的数据包括:OpenGL.COLOR_INDEX、OpenGL.STENCIL_INDEX、OpenGL.DEPTH_COMPONENT、OpenGL.RED、OpenGL.GREEN、OpenGL.BLUE、OpenGL.ALPHA、OpenGL.RGB、 OpenGL.RGBA、OpenGL.LUMINANCE、OpenGL.LUMINANCE_ALPHA。
测试程序在这里:SharpGL测试范例