OpenGL: 实现立体显示

转载 2014年02月25日 17:08:08

立体显示原理:设没有立体显示的模型视图矩阵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: 图片满屏显示

实现图片满屏显示,最常用的用途是把一张图片作为显示窗体的背景图片。我这里有总两种方法: 一、 正交模式显示背景图片关闭深度测试正交投影设置四边形的尺寸为窗口四个角,将图片贴到Quad上切换到透视模式下...
  • Augusdi
  • Augusdi
  • 2014年02月26日 17:15
  • 1985

OpenGL实现立体显示

立体显示原理:设没有立体显示的模型视图矩阵ModelView为Mv,投影矩阵为Mp,则、物体空间的任何一点为P,则变换到屏幕坐标P*=Mp×Mv×P;注意前面已经说过opengl里面坐标列优先,所以矩...
  • dizuo
  • dizuo
  • 2008年04月25日 14:35
  • 7159

立体显示 opengl

  • 2008年05月27日 00:31
  • 112KB
  • 下载

VS2012下基于Glut OpenGL显示一些立体图形示例程序:

Glut下提供了一些现成的绘制立体的API,如glutWireSphere绘制球,glutWireCone绘制椎体,glutWireCube绘制立体,glutWireTorus绘制甜圈,glutWir...
  • yearafteryear
  • yearafteryear
  • 2013年06月25日 23:45
  • 17028

OpenGL: OpenGL实现立体显示

立体显示原理:设没有立体显示的模型视图矩阵ModelView为Mv,投影矩阵为Mp,则、物体空间的任何一点为P,则变换到屏幕坐标P*=Mp×Mv×P;注意前面已经说过opengl里面坐标列优先,所以矩...
  • Augusdi
  • Augusdi
  • 2014年07月23日 11:15
  • 1780

Android OpenGL显示任意3D模型文件

前面两篇文章我们介绍了OpenGL相关的基本知识,现在我们已经会绘制基本的图案了,但是还远远不能满足我们的需求。我们要做的是显示任意的模型,这也是本文所要做的事情。在阅读本文之前,请先确保你已经看过我...
  • huachao1001
  • huachao1001
  • 2016年07月29日 15:44
  • 13052

OpenGL立体显示实现

立体显示原理:设没有立体显示的模型视图矩阵ModelView为Mv,投影矩阵为Mp,则、物体空间的任何一点为P,则变换到屏幕坐标P*=Mp×Mv×P;注意前面已经说过opengl里面坐标列优先,所以矩...
  • wang15061955806
  • wang15061955806
  • 2016年01月06日 16:28
  • 243

opengl 立体球体的实现

  • 2012年12月23日 08:56
  • 3.4MB
  • 下载

OpenCV学习笔记(15)使用OpenGL显示双目视觉三维重构效果

上一篇笔记中使用Matlab初步显示了双目视觉重构出的环境三维效果图,不过并没有加上纹理信息。在OpenCV中文论坛里,大象的帖子(http://www.opencv.org....
  • chenyusiyuan
  • chenyusiyuan
  • 2010年06月24日 14:23
  • 49677

基于OpenGL和OpenCV的三维显示

最近想用OpenCV+OpenGL+QT实现三维显示,但是一直都么有弄出来,今天看了一篇博客,感觉很不错,拿来分享下。       简而言之,这段代码是如何从disparity image获得点...
  • sky_freebird
  • sky_freebird
  • 2011年08月17日 15:23
  • 13505
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OpenGL: 实现立体显示
举报原因:
原因补充:

(最多只允许输入30个字)