OpenGL: 实现立体显示
2014-02-25 17:08
411 查看
立体显示原理:设没有立体显示的模型视图矩阵ModelView为Mv,投影矩阵为Mp,则、物体空间的任何一点为P,则变换到屏幕坐标P*=Mp×Mv×P;注意前面已经说过opengl里面坐标列优先,所以矩阵都是右乘。左眼和右眼的变换都是由中间的变换矩阵变换而来,则立体显示中左眼的变换矩阵公式为:P(L)*=Ms(L) × Mp(L) × Mt(L) × Mv(L) × P;右眼的矩阵变换公式为:P(R)*=Ms(R) × Mp(R) × Mt(R) × Mv(R) × P;其中Ms,Mt是立体显示需要而增加的变换。程序里面有几个参数,现实世界眼睛到屏幕的距离Fd,两眼之间的距离Sd,比例尺R,如图:
![](http://hi.csdn.net/attachment/201004/28/0_1272448583rqia.gif)
如上图:没有立体显示,视点位于就是中间的蓝色位置,立体显示就是将左眼(红色),右眼(绿色)的视图分开绘制。程序中左眼用红色去画,右眼同时用绿色和蓝色绘制。 代码:
![](http://hi.csdn.net/attachment/201004/28/0_1272448583rqia.gif)
如上图:没有立体显示,视点位于就是中间的蓝色位置,立体显示就是将左眼(红色),右眼(绿色)的视图分开绘制。程序中左眼用红色去画,右眼同时用绿色和蓝色绘制。 代码:
#include <windows.h> #include <GL/glut.h> #include <math.h> #pragma comment(lib,"glut32.lib") #pragma comment(lib,"glu32.lib") #pragma comment(lib,"opengl32.lib") void init(void) { GLfloat mat_diffuse[] = { 1.0, 1.0, 0.0 }; GLfloat mat_specular[] = {0.8, 0.8, 0.0, 1.0}; GLfloat mat_shininess[] = { 300. }; GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 0.0 }; GLfloat light_ambient[] = {0.7, 0.2, 0.2, 1.0}; glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_SMOOTH); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); } /**//*---------------------------------------------------------------------------- * 初始化参数 */ GLfloat PI=3.1415926; GLfloat Fd=5.0; //fusion distance GLfloat RealScreenToEyeDistance=1.0; GLfloat R = Fd / RealScreenToEyeDistance; //比例尺 R = Fd / RealScreenToEyeDistance GLfloat Sd = 0.05; //两眼之间的距离 GLfloat aspect = 1.0; //gluLookAt函数里面的参数 GLfloat fovy = 60.0; //张角 GLfloat f = 1 / tan( (fovy * PI) / (2 * 180) ); //f=ctg(fovy/2); //列优先的矩阵模型视图矩阵,投影矩阵 GLfloat LeftModelViewMatrix[16]= { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, Sd * R / 2.0, 0.0, 0.0, 1.0 }; GLfloat LeftProjectMatrix[16]= { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -(Sd * f) / (2.0 * Fd * aspect), 0.0, 0.0, 1.0 }; GLfloat RightModelViewMatrix[16]= { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -Sd * R / 2.0, 0.0, 0.0, 1.0 }; GLfloat RightProjectMatrix[16]= { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, (Sd * f) / (2.0 * Fd * aspect), 0.0, 0.0, 1.0 }; //for the use of rotating static GLfloat spin = 0.0; void display(void) { GLfloat matrix[16]={0.}; glColorMask(1.0, 1.0, 1.0, 1.0); glClearColor(0.0, 0.0, 0.0, 1.0); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); //--------------------------------------------------------------------------------------------- //Left View port glMatrixMode(GL_PROJECTION); glPushMatrix(); { glGetFloatv(GL_PROJECTION_MATRIX, matrix); glLoadIdentity(); glMultMatrixf(LeftProjectMatrix); glMultMatrixf(matrix); { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslated(0.0, 0.0, -Fd); glPushMatrix(); { glGetFloatv(GL_MODELVIEW_MATRIX, matrix); glLoadIdentity(); glMultMatrixf(LeftModelViewMatrix); glMultMatrixf(matrix); glColorMask(1.0, 0.0, 0.0, 1.0); /**//* * 物体的坐标Vp * 变换到屏幕坐标:Vp'= LeftProjectMatrix×Mp × LeftModelViewMatrix×Mv × Mr×Vp */ glPushMatrix(); { glRotatef(spin, 0.0, 1.0, 0.0); glutSolidTeapot(1.0); } glPopMatrix(); } } glPopMatrix(); glMatrixMode(GL_PROJECTION); } glPopMatrix(); glFlush(); //--------------------------------------------------------------------------------------------- //Right View port glMatrixMode(GL_PROJECTION); glPushMatrix(); { glGetFloatv(GL_PROJECTION_MATRIX, matrix); glLoadIdentity(); glMultMatrixf(RightProjectMatrix); glMultMatrixf(matrix); glMatrixMode(GL_MODELVIEW); glPushMatrix(); { glGetFloatv(GL_MODELVIEW_MATRIX, matrix); glLoadIdentity(); glMultMatrixf(RightModelViewMatrix); glMultMatrixf(matrix); glColorMask(0.0, 1.0, 1.0, 1.0); glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); /**//* * 物体的坐标Vp * 变换到屏幕坐标:Vp'= RightProjectMatrix×Mp× RightModelViewMatrix×Mv × Mr×Vp */ glPushMatrix(); { glRotatef(spin, 0.0, 1.0, 0.0); glutSolidTeapot(1.0); //glutSolidSphere(1.0, 20, 5); } } glPopMatrix(); glMatrixMode(GL_PROJECTION); } glPopMatrix(); glFlush (); glutSwapBuffers(); } void reshape (int w, int h) { if (h == 0) { h == 1; } glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity(); //投影矩阵:Mp gluPerspective(fovy, (GLfloat)w / (GLfloat)h, 1.0, 20.0); } void spinDisplay(void) { spin = spin + 1.0; if (spin > 360.0) { spin = spin - 360.0; } glutPostRedisplay(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutIdleFunc(spinDisplay); glutMainLoop(); return 0; }相关立体显示链接:http://local.wasp.uwa.edu.au/~pbourke/projection/stereorender//article/1342267.html
相关文章推荐
- 去年12月29日,红旗Linux员工在网上发出请愿书“风雨飘摇,中科红旗路在啊何方?”,又打出横幅”软件所还我核高基专项款,大股东无视职工死活“,到工信部大门口集体请愿、讨薪,闹得很不安宁。
- Linux系统手动安装rpm包依赖关系分析(以Kernel升级为例)
- 在嵌入式Linux系统中实现USB存储设备的自动挂载
- shell脚本学习笔记一
- centos6.4下编译apue.h(第二版)
- 在linux中导入sql文件的方法分享(使用命令行转移mysql数据库)
- linux 链接脚本
- Linux文件系统之hard link&symbol link
- OpenGL: 绘制按钮
- centos初装后并没有带上rz sz的程序。需要安装: yum install lrzsz
- 关于MVC中DropDownListFor的一个bug
- CS/BS架构区别
- windows下eclipse远程连接linux上的hadoop集群
- Linux crontab 任务调度的使用
- opencv中测量运行时间的函数
- 可靠、高吞吐架构基础改造
- linux进程后台运行的几种方法
- Linux开机启动程序详解[转]
- CentOS 6.5 X64 U盘启动盘制作
- Linux环境下修改MySQL端口方法: