OpenGL: 实现立体显示
https://blog.csdn.net/augusdi/article/details/19922295
立体显示原理:设没有立体显示的模型视图矩阵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,如图:

如上图:没有立体显示,视点位于就是中间的蓝色位置,立体显示就是将左眼(红色),右眼(绿色)的视图分开绘制。
程序中左眼用红色去画,右眼同时用绿色和蓝色绘制。
代码:
- #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/
http://blog.csdn.net/ryfdizuo/article/details/2327478
OpenGL: 实现立体显示的更多相关文章
- 3D立体显示大屏幕拼接视频墙系统解决方案【转】
http://shop.souvr.com/thread-123416-1-1.html 随着3D立体视像.全息影像等技术不断取得突破性进展,国内外越来越多的公司投身3D显示领域,产品层出不穷.3D技 ...
- CreatarGlobe实现多机立体显示方案(初稿)
CreatarGlobe实现多机立体显示方案(初稿) 关键字 : 集群渲染 立体显示 大屏幕 边缘融合 多机同步 多机同步显示 关键字: 大屏幕投影融合系统解决方案 集群渲染 多机3D同步显示又称“集 ...
- 基于3D Vision眼镜的OSG立体显示 【转】
http://blog.csdn.net/qq_20038925/article/details/50510565 OSG 立体显示 3D Vision眼镜:所实现的是被动立体. 1.本人最近在做os ...
- 【AR实验室】OpenGL ES绘制相机(OpenGL ES 1.0版本)
0x00 - 前言 之前做一些移动端的AR应用以及目前看到的一些AR应用,基本上都是这样一个套路:手机背景显示现实场景,然后在该背景上进行图形学绘制.至于图形学绘制时,相机外参的解算使用的是V-SLA ...
- [OpenGL超级宝典]专栏前言
我小时候的梦想呢,是做宇航员或者科学家或者是做一款属于自己的游戏,后来前面两个梦想都没有实现,于是我就来实现我的第三个梦想了,,,我呢,也算是零基础,因为我的专业是物联网工程,这个专业覆盖面之广,简直 ...
- OpenGL超级宝典笔记----渲染管线
在OpenGL中任何事物都在3D空间中,但是屏幕和窗口是一个2D像素阵列,所以OpenGL的大部分工作都是关于如何把3D坐标转变为适应你屏幕的2D像素.3D坐标转为2D坐标的处理过程是由OpenGL的 ...
- OpenGL超级宝典笔记----框架搭建
自从工作后,总是或多或少的会接触到客户端3d图形渲染,正好自己对于3d图形的渲染也很感兴趣,所以最近打算从学习OpenGL的图形API出发,进而了解3d图形的渲染技术.到网上查了一些资料,OpenGL ...
- 现代3D图形编程学习-基础简介(3)-什么是opengl (译)
本书系列 现代3D图形编程学习 OpenGL是什么 在我们编写openGL程序之前,我们首先需要知道什么是OpenGL. 将OpenGL作为一个API OpenGL 通常被认为是应用程序接口(API) ...
- OpenGL shader 中关于顶点坐标值的思考
今天工作中需要做一个事情: 在shader内部做一些空间距离上的计算,而且需要对所有的点进行计算,符合条件的显示,不符合条件的点不显示. 思路很简单,在vertex shader内知道顶点坐标,进行计 ...
随机推荐
- syslog-ng应用详解
syslog-ng应用详解 科技小能手 2017-11-07 02:43:00 浏览136 评论0 日志 LOG 配置 主机 syslog source file varchar 摘要: 最近做一 ...
- (转)spring计划任务,springMvc计划任务,Spring@Scheduled,spring定时任务
一.计划任务实现类 1.用@Component注解标识计划任务类,这样spring可以自动扫描 2.在方法中使用注解标识要执行的方法:@Scheduled(cron="*/30 * * * ...
- 6个炫酷又好用的 Python 工具,个个都很奔放呀
贝多芬写完<第九交响曲>后说:it's done:耶稣在被处死前说:it is done:<指环王>结尾摧毁魔戒后Frodo说:it's done! 我整理完这6个Python ...
- np.percentile()
np.percentile(a, q, axis=None, out=None, overwrite_input=False, interpolation='linear', keepdims=Fal ...
- iOS 开发常用链接总结
知识归纳 1.招聘一个靠谱的程序员 面试题答案 https://github.com/ChenYilong/iOSInterviewQuestions 2.中文 iOS/Mac 开发博客列表 http ...
- CSU 1817 Bones’s Battery Submit(二分+Floyd)
Bones's Battery Submit [题目链接]Bones's Battery Submit [题目类型]二分+Floyd &题意: 有n个点,m条边,从点ui到点vi的费电量是di ...
- Linux(Centos)服务器配置node项目
以阿里云服务器,CentOS系统为例 上一节已经提到怎么安装nodejs,以下是以vue项目为例 步骤: (1)首先安装vue脚手架@vue/cli, 官网参考 vue-cli3.x [root@lu ...
- ubuntu安装python-mysqldb
前期准备: sudo apt-get install libmysqld-dev sudo apt-get install libmysqlclient-dev sudo apt-get insta ...
- 详解tween.js 中文使用指南
补间(动画)是一个概念,允许你以平滑的方式更改对象的属性.你只需告诉它哪些属性要更改,当补间结束运行时它们应该具有哪些最终值,以及这需要多长时间,补间引擎将负责计算从起始点到结束点的值. 例如,pos ...
- Java多线程-----volatile关键字详解
volatile原理 Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程.当把变量声明为volatile类型后, 编译器与运行时都会注意 ...