OpenGL坐标 逆变换和模拟变换_第1页
OpenGL坐标 逆变换和模拟变换_第2页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

逆变换和模拟变换几何处理管线擅长使用视图和投影矩阵以及用于裁剪的视口把顶点的世界(物体)坐标变换为窗口(屏幕)坐标。但是,在有些情况下,需要反转这个过程。一种常见的情形就是应用程序的用户利用鼠标选择了三维空间中的一个位置。鼠标只返回一个二维值,也就是鼠标光标的屏幕位置。因此,应用程序必须反转变换过程,确定这个屏幕位置源于三维空间的什么地方。OpenGL工具函数库中gluUnProject()和gluUnProject4()函数用于执行这种逆变换操作。只要提供一个经过变换的顶点的三维窗口坐标以及所有对它产生影响的变换,gluUnProject()就可以返回这个顶点的源物体坐标。如果深度范围不是默认的[0,1],应该使用gluUnProject4()函数。intgluUnProject(GLdoublewinx,GLdoublewiny,GLdoublewinz,constGLdoublemodelMatrix[16],constGLdoubleprojMatrix[16],constGLintviewport[4],GLdouble*objx,GLdouble*objy,GLdouble*objz);这个函数使用由模型视图矩阵(modelMatrix)、投影矩阵(projMatrix)和视口(viewport)定义的变换,把指定的窗口坐标(winx,winy,winz)映射到物体坐标。它产生的物体坐标是在objx、objy和objz中返回的。这个函数返回GL_TRUE(表示成功)或GL_FALSE(表示失败,例如矩阵不可逆)。这个函数并不会使用视口对坐标进行裁剪,也不会消除那些位于glDepthRange()范围之外的深度值。对变换过程进行逆操作存在一些固有的难度。二维屏幕上的一个位置可以来自于三维空间中一条直线上的任意一点。为了消除这种歧义,gluUnProject()要求提供一个窗口深度坐标(winz),它是根据glDepthRange()函数指定的。关于深度范围的更多信息,参见第3.4.2节。如果使用的是glDepthRange()的默认值,winz为0.0表示这个经过变换的点的物体坐标位于近侧裁剪平面上,如果winz是1.0表示它的坐标位于远侧裁剪平面上。示例程序3-8说明了gluUnProject()函数的用法。这个程序读取鼠标位置,并确定鼠标光标位置经过变换之后在三维空间的近侧裁剪平面和远侧裁剪平面上的点。经过计算得的物体坐标被打印到标准输出,但渲染的窗口本身仍然保持为黑色。示例程序3-8逆变换几何处理管线:unproject.cvoiddisplay(void){glClear(GL_COLOR_BUFFER_BIT);glFlush();}voidreshape(intw,inth){glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(45.0,(GLfloat)w/(GLfloat)h,1.0,100.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}voidmouse(intbutton,intstate,intx,inty){GLintviewport[4];GLdoublemvmatrix[16],projmatrix[16];GLintrealy;/*OpenGLycoordinateposition*/GLdoublewx,wy,wz;/*returnedworldx,y,zcoords*/110第3章switch(button){caseGLUT_LEFT_BUTTON:if(state==GLUT_DOWN){glGetIntegerv(GL_VIEWPORT,viewport);glGetDoublev(GL_MODELVIEW_MATRIX,mvmatrix);glGetDoublev(GL_PROJECTION_MATRIX,projmatrix);/*noteviewport[3]isheightofwindowinpixels*/realy=viewport[3]-(GLint)y-1;printf("Coordinatesatcursorare(%4d,%4d)\n",x,realy);gluUnProject((GLdouble)x,(GLdouble)realy,0.0,mvmatrix,projmatrix,viewport,&wx,&wy,&wz);printf("Worldcoordsatz=0.0are(%f,%f,%f)\n",wx,wy,wz);gluUnProject((GLdouble)x,(GLdouble)realy,1.0,mvmatrix,projmatrix,viewport,&wx,&wy,&wz);printf("Worldcoordsatz=1.0are(%f,%f,%f)\n",wx,wy,wz);}break;caseGLUT_RIGHT_BUTTON:if(state==GLUT_DOWN)exit(0);break;default:break;}}intmain(intargc,char**argv){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(500,500);glutInitWindowPosition(100,100);glutCreateWindow(argv[0]);glutDisplayFunc(display);glutReshapeFunc(reshape);glutMouseFunc(mouse);glutMainLoop();return0;}GLU1.3引入了一个经过修改的gluUnProject()版本。gluUnProject4()可以处理非标准的glDepthRange()值,也可以处理w坐标值不等于1的情况。intgluUnProject4(GLdoublewinx,GLdoublewiny,GLdoublewinz,GLdoubleclipw,constGLdoublemodelMatrix[16],constGLdoubleprojMatrix[16],constGLintviewport[4],GLclampdzNear,GLclampdzFar,GLdouble*objx,GLdouble*objy,GLdouble*objz,GLdouble*objw);总体上说,这个函数的功能类似于gluUnProject()。它使用由模型视图矩阵、投影矩阵、视口和深度范围值zNear和zFar定义的变换,把指定的窗口坐标(winx,winy,winz)映射到物体坐标。它产生的物体坐标是在objx、objy、ojbz和objw中返回的。gluProject()是另一个工具函数库中的函数,和gluUnProject()相对应。gluProject()模拟变换管线的操作。只要提供三维物体坐标以及对它们产生影响的所有变换,gluProject()就会返回经过变换的窗口坐标。intgluProject(GLdoubleobjx,GLdoubleobjy,GLdoubleobjz,constGLdoublemodelMatrix[16],constGLdoubleprojMatrix[16],constGLintviewport[4],GLdouble*winx,GLdouble*winy,GLdouble*winz);这个函数使用由模型视图矩阵、投影矩阵和视口定义的变换,把指定的物体坐标(objx,objy,objz)变换为窗口坐标。它产生的窗口坐标是在winx、winy和winz中返回的。这个函数返回GL_TRUE(表示成功)或GL_FALSE(表示失败)。注意:传递给gluUnProject()、gluUnProject4()

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论